/* Copyright 2013-2014 IBM Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef __STACKFRAME_H #define __STACKFRAME_H #include #define STACK_ENTRY_OPAL_API 0 /* OPAL call */ #define STACK_ENTRY_HMI 0x0e60 /* Hypervisor maintenance */ #define STACK_ENTRY_RESET 0x0100 /* System reset */ #define STACK_ENTRY_SOFTPATCH 0x1500 /* Soft patch (denorm emulation) */ /* Safety/ABI gap at top of stack */ #define STACK_TOP_GAP 0x100 /* Remaining stack space (gap included) */ #define NORMAL_STACK_SIZE (STACK_SIZE/2) /* Emergency (re-entry) stack size */ #define EMERGENCY_STACK_SIZE (STACK_SIZE/2) /* Offset to get to normal CPU stacks */ #define CPU_STACKS_OFFSET (CPU_STACKS_BASE + \ NORMAL_STACK_SIZE - STACK_TOP_GAP) /* Offset to get to emergency CPU stacks */ #define EMERGENCY_CPU_STACKS_OFFSET (CPU_STACKS_BASE + NORMAL_STACK_SIZE + \ EMERGENCY_STACK_SIZE - STACK_TOP_GAP) /* Gap below the stack. If our stack checker sees the stack below that * gap, it will flag a stack overflow */ #define STACK_SAFETY_GAP 512 /* Warning threshold, if stack goes below that on mcount, print a * warning. */ #define STACK_WARNING_GAP 2048 #define STACK_CHECK_GUARD_BASE 0xdeadf00dbaad300 #ifndef __ASSEMBLY__ #include #include /* This is the struct used to save GPRs etc.. on OPAL entry * and from some exceptions. It is not always entirely populated * depending on the entry type */ struct stack_frame { /* Standard 112-byte stack frame header (the minimum size required, * using an 8-doubleword param save area). The callee (in C) may use * lrsave; we declare these here so we don't get our own save area * overwritten */ uint64_t backchain; uint64_t crsave; uint64_t lrsave; uint64_t compiler_dw; uint64_t linker_dw; uint64_t tocsave; uint64_t paramsave[8]; /* Space for stack-local vars used by asm. At present we only use * one doubleword. */ uint64_t locals[1]; /* Entry type */ uint64_t type; /* GPR save area * * We don't necessarily save everything in here */ uint64_t gpr[32]; /* Other SPR saved * * Only for some exceptions. */ uint32_t cr; uint32_t xer; uint32_t dsisr; uint64_t ctr; uint64_t lr; uint64_t pc; uint64_t msr; uint64_t cfar; uint64_t srr0; uint64_t srr1; uint64_t hsrr0; uint64_t hsrr1; uint64_t dar; } __attribute__((aligned(16))); /* Backtrace entry */ struct bt_entry { unsigned long sp; unsigned long pc; }; /* Backtrace metadata */ struct bt_metadata { unsigned int ents; unsigned long token; unsigned long r1_caller; unsigned long pir; }; /* Boot stack top */ extern void *boot_stack_top; /* Create a backtrace */ void backtrace_create(struct bt_entry *entries, unsigned int max_ents, struct bt_metadata *metadata); /* Convert a backtrace to ASCII */ extern void backtrace_print(struct bt_entry *entries, struct bt_metadata *metadata, char *out_buf, unsigned int *len, bool symbols); /* For use by debug code, create and print backtrace, uses a static buffer */ extern void backtrace(void); #ifdef STACK_CHECK_ENABLED extern void check_stacks(void); #else static inline void check_stacks(void) { } #endif #endif /* __ASSEMBLY__ */ #endif /* __STACKFRAME_H */