diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/cortex-m/panic.c | 102 | ||||
-rw-r--r-- | core/nds32/panic.c | 8 |
2 files changed, 62 insertions, 48 deletions
diff --git a/core/cortex-m/panic.c b/core/cortex-m/panic.c index 5866a14ca6..5ecad1535b 100644 --- a/core/cortex-m/panic.c +++ b/core/cortex-m/panic.c @@ -18,6 +18,9 @@ #include "util.h" #include "watchdog.h" +#define BASE_EXCEPTION_FRAME_SIZE_BYTES (8 * sizeof(uint32_t)) +#define FPU_EXCEPTION_FRAME_SIZE_BYTES (18 * sizeof(uint32_t)) + /* Whether bus fault is ignored */ static int bus_fault_ignored; @@ -77,6 +80,53 @@ static int32_t is_frame_in_handler_stack(const uint32_t exc_return) return (exc_return & 0xf) == 1 || (exc_return & 0xf) == 9; } +/* + * Returns the size of the exception frame. + * + * See B1.5.7 "Stack alignment on exception entry" of ARM DDI 0403D for details. + * In short, the exception frame size can be either 0x20, 0x24, 0x68, or 0x6c + * depending on FPU context and padding for 8-byte alignment. + */ +static uint32_t get_exception_frame_size(const struct panic_data *pdata) +{ + uint32_t frame_size = 0; + + /* base exception frame */ + frame_size += BASE_EXCEPTION_FRAME_SIZE_BYTES; + + /* CPU uses xPSR[9] to indicate whether it padded the stack for + * alignment or not. + */ + if (pdata->cm.frame[CORTEX_PANIC_FRAME_REGISTER_PSR] & BIT(9)) + frame_size += sizeof(uint32_t); + +#ifdef CONFIG_FPU + /* CPU uses EXC_RETURN[4] to indicate whether it stored extended + * frame for FPU or not. + */ + if (!(pdata->cm.regs[CORTEX_PANIC_REGISTER_LR] & BIT(4))) + frame_size += FPU_EXCEPTION_FRAME_SIZE_BYTES; +#endif + + return frame_size; +} + +/* + * Returns the position of the process stack before the exception frame. + * It computes the size of the exception frame and adds it to psp. + * If the exception happened in the exception context, it returns psp as is. + */ +uint32_t get_panic_stack_pointer(const struct panic_data *pdata) +{ + uint32_t psp = pdata->cm.regs[CORTEX_PANIC_REGISTER_PSP]; + + if (!is_frame_in_handler_stack( + pdata->cm.regs[CORTEX_PANIC_REGISTER_LR])) + psp += get_exception_frame_size(pdata); + + return psp; +} + #ifdef CONFIG_DEBUG_EXCEPTIONS /* Names for each of the bits in the mmfs register, starting at bit 0 */ static const char * const mmfs_name[32] = { @@ -185,50 +235,6 @@ static void show_fault(uint32_t mmfs, uint32_t hfsr, uint32_t dfsr) } /* - * Returns the size of the exception frame. - * - * See B1.5.7 "Stack alignment on exception entry" of ARM DDI 0403D for details. - * In short, the exception frame size can be either 0x20, 0x24, 0x68, or 0x6c - * depending on FPU context and padding for 8-byte alignment. - */ -static uint32_t get_exception_frame_size(const struct panic_data *pdata) -{ - uint32_t frame_size = 0; - - /* base exception frame */ - frame_size += 8 * sizeof(uint32_t); - - /* CPU uses xPSR[9] to indicate whether it padded the stack for - * alignment or not. */ - if (pdata->cm.frame[7] & (1 << 9)) - frame_size += sizeof(uint32_t); - -#ifdef CONFIG_FPU - /* CPU uses EXC_RETURN[4] to indicate whether it stored extended - * frame for FPU or not. */ - if (!(pdata->cm.regs[11] & (1 << 4))) - frame_size += 18 * sizeof(uint32_t); -#endif - - return frame_size; -} - -/* - * Returns the position of the process stack before the exception frame. - * It computes the size of the exception frame and adds it to psp. - * If the exception happened in the exception context, it returns psp as is. - */ -static uint32_t get_process_stack_position(const struct panic_data *pdata) -{ - uint32_t psp = pdata->cm.regs[0]; - - if (!is_frame_in_handler_stack(pdata->cm.regs[11])) - psp += get_exception_frame_size(pdata); - - return psp; -} - -/* * Show extra information that might be useful to understand a panic() * * We show fault register information, including the fault address registers @@ -254,7 +260,7 @@ static void panic_show_process_stack(const struct panic_data *pdata) { panic_printf("\n=========== Process Stack Contents ==========="); if (pdata->flags & PANIC_DATA_FLAG_FRAME_VALID) { - uint32_t psp = get_process_stack_position(pdata); + uint32_t psp = get_panic_stack_pointer(pdata); int i; for (i = 0; i < 16; i++) { if (psp + sizeof(uint32_t) > @@ -334,9 +340,9 @@ void __keep report_panic(void) sp = is_frame_in_handler_stack(pdata->cm.regs[11]) ? pdata->cm.regs[2] : pdata->cm.regs[0]; /* If stack is valid, copy exception frame to pdata */ - if ((sp & 3) == 0 && - sp >= CONFIG_RAM_BASE && - sp <= CONFIG_RAM_BASE + CONFIG_RAM_SIZE - 8 * sizeof(uint32_t)) { + if ((sp & 3) == 0 && sp >= CONFIG_RAM_BASE && + sp <= CONFIG_RAM_BASE + CONFIG_RAM_SIZE - + BASE_EXCEPTION_FRAME_SIZE_BYTES) { const uint32_t *sregs = (const uint32_t *)sp; int i; diff --git a/core/nds32/panic.c b/core/nds32/panic.c index 8b87cc0ef8..4945bae53e 100644 --- a/core/nds32/panic.c +++ b/core/nds32/panic.c @@ -141,6 +141,14 @@ void panic_get_reason(uint32_t *reason, uint32_t *info, uint8_t *exception) } #endif /* CONFIG_SOFTWARE_PANIC */ +/** + * Returns the SP register + */ +uint32_t get_panic_stack_pointer(const struct panic_data *pdata) +{ + return pdata->nds_n8.regs[15]; +} + static void print_panic_information(uint32_t *regs, uint32_t itype, uint32_t ipc, uint32_t ipsw) { |