summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/cortex-m/panic.c40
-rw-r--r--include/config.h3
-rw-r--r--include/panic.h38
3 files changed, 75 insertions, 6 deletions
diff --git a/core/cortex-m/panic.c b/core/cortex-m/panic.c
index 5722e48910..5866a14ca6 100644
--- a/core/cortex-m/panic.c
+++ b/core/cortex-m/panic.c
@@ -339,8 +339,19 @@ void __keep report_panic(void)
sp <= CONFIG_RAM_BASE + CONFIG_RAM_SIZE - 8 * sizeof(uint32_t)) {
const uint32_t *sregs = (const uint32_t *)sp;
int i;
- for (i = 0; i < 8; i++)
+
+ /* Skip r0-r3 and r12 registers if necessary */
+ for (i = CORTEX_PANIC_FRAME_REGISTER_R0;
+ i <= CORTEX_PANIC_FRAME_REGISTER_R12; i++)
+ if (IS_ENABLED(CONFIG_PANIC_STRIP_GPR))
+ pdata->cm.frame[i] = 0;
+ else
+ pdata->cm.frame[i] = sregs[i];
+
+ for (i = CORTEX_PANIC_FRAME_REGISTER_LR;
+ i < NUM_CORTEX_PANIC_FRAME_REGISTERS; i++)
pdata->cm.frame[i] = sregs[i];
+
pdata->flags |= PANIC_DATA_FLAG_FRAME_VALID;
}
@@ -400,6 +411,33 @@ void exception_panic(void)
"mrs r1, psp\n"
"mrs r2, ipsr\n"
"mov r3, sp\n"
+#ifdef CONFIG_PANIC_STRIP_GPR
+ /*
+ * Check if we are in exception. This is similar to
+ * in_interrupt_context(). Exception bits are 9 LSB, so
+ * we can perform left shift for 23 bits and check if result
+ * is 0 (lsls instruction is setting appropriate flags).
+ */
+ "lsls r6, r2, #23\n"
+ /*
+ * If this is software panic (shift result == 0) then register
+ * r4 and r5 contain additional info about panic.
+ * Clear r6-r11 always and r4, r5 only if this is exception
+ * panic. To clear r4 and r5, 'movne' conditional instruction
+ * is used. It works only when flags contain information that
+ * result was != 0. Itt is pseudo instruction which is used
+ * to make sure we are using correct conditional instructions.
+ */
+ "itt ne\n"
+ "movne r4, #0\n"
+ "movne r5, #0\n"
+ "mov r6, #0\n"
+ "mov r7, #0\n"
+ "mov r8, #0\n"
+ "mov r9, #0\n"
+ "mov r10, #0\n"
+ "mov r11, #0\n"
+#endif
"stmia r0, {r1-r11, lr}\n"
"mov sp, %[pstack]\n"
"bl report_panic\n" : :
diff --git a/include/config.h b/include/config.h
index 753a97e6d5..80abb601c5 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1158,6 +1158,9 @@
*/
#undef CONFIG_CHIP_PANIC_BACKUP
+/* Don't save General Purpose Registers during panic */
+#undef CONFIG_PANIC_STRIP_GPR
+
/*
* When defined, it enables system safe mode. System safe mode allows the AP to
* capture the EC state after a panic.
diff --git a/include/panic.h b/include/panic.h
index 0d3a83a783..b366567468 100644
--- a/include/panic.h
+++ b/include/panic.h
@@ -17,13 +17,41 @@
extern "C" {
#endif
+enum cortex_panic_frame_registers {
+ CORTEX_PANIC_FRAME_REGISTER_R0 = 0,
+ CORTEX_PANIC_FRAME_REGISTER_R1,
+ CORTEX_PANIC_FRAME_REGISTER_R2,
+ CORTEX_PANIC_FRAME_REGISTER_R3,
+ CORTEX_PANIC_FRAME_REGISTER_R12,
+ CORTEX_PANIC_FRAME_REGISTER_LR,
+ CORTEX_PANIC_FRAME_REGISTER_PC,
+ CORTEX_PANIC_FRAME_REGISTER_PSR,
+ NUM_CORTEX_PANIC_FRAME_REGISTERS
+};
+
+enum cortex_panic_registers {
+ CORTEX_PANIC_REGISTER_PSP = 0,
+ CORTEX_PANIC_REGISTER_IPSR,
+ CORTEX_PANIC_REGISTER_MSP,
+ CORTEX_PANIC_REGISTER_R4,
+ CORTEX_PANIC_REGISTER_R5,
+ CORTEX_PANIC_REGISTER_R6,
+ CORTEX_PANIC_REGISTER_R7,
+ CORTEX_PANIC_REGISTER_R8,
+ CORTEX_PANIC_REGISTER_R9,
+ CORTEX_PANIC_REGISTER_R10,
+ CORTEX_PANIC_REGISTER_R11,
+ CORTEX_PANIC_REGISTER_LR,
+ NUM_CORTEX_PANIC_REGISTERS
+};
+
/* ARM Cortex-Mx registers saved on panic */
struct cortex_panic_data {
- uint32_t regs[12]; /* psp, ipsr, msp, r4-r11, lr(=exc_return).
- * In version 1, that was uint32_t regs[11] =
- * psp, ipsr, lr, r4-r11
- */
- uint32_t frame[8]; /* r0-r3, r12, lr, pc, xPSR */
+ /* See cortex_panic_registers enum for information about registers */
+ uint32_t regs[NUM_CORTEX_PANIC_REGISTERS];
+
+ /* See cortex_panic_frame_registers enum for more information */
+ uint32_t frame[NUM_CORTEX_PANIC_FRAME_REGISTERS];
uint32_t mmfs;
uint32_t bfar;