summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/cortex-m/panic.c2
-rw-r--r--include/panic.h7
-rw-r--r--util/ectool.c34
3 files changed, 34 insertions, 9 deletions
diff --git a/core/cortex-m/panic.c b/core/cortex-m/panic.c
index df3b08db57..85d0701b21 100644
--- a/core/cortex-m/panic.c
+++ b/core/cortex-m/panic.c
@@ -372,7 +372,7 @@ void report_panic(void)
pdata->magic = PANIC_DATA_MAGIC;
pdata->struct_size = sizeof(*pdata);
- pdata->struct_version = 1;
+ pdata->struct_version = 2;
pdata->arch = PANIC_ARCH_CORTEX_M;
pdata->flags = 0;
pdata->reserved = 0;
diff --git a/include/panic.h b/include/panic.h
index 6caaf6a2d8..256ce84e87 100644
--- a/include/panic.h
+++ b/include/panic.h
@@ -14,11 +14,14 @@
/* Data saved across reboots */
struct panic_data {
uint8_t arch; /* Architecture (PANIC_ARCH_*) */
- uint8_t struct_version; /* Structure version (currently 1) */
+ uint8_t struct_version; /* Structure version (currently 2) */
uint8_t flags; /* Flags (PANIC_DATA_FLAG_*) */
uint8_t reserved; /* Reserved; set 0 */
- uint32_t regs[12]; /* psp, ipsr, msp, r4-r11, lr(=exc_return) */
+ 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 */
uint32_t mmfs;
diff --git a/util/ectool.c b/util/ectool.c
index 702f8298b3..eafe2e5d93 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -1604,8 +1604,13 @@ int cmd_panic_info(int argc, char *argv[])
struct panic_data *pdata = (struct panic_data *)ec_inbuf;
const uint32_t *lregs = pdata->regs;
const uint32_t *sregs = NULL;
- int in_handler;
+ enum {
+ ORIG_UNKNOWN = 0,
+ ORIG_PROCESS,
+ ORIG_HANDLER
+ } origin = ORIG_UNKNOWN;
int i;
+ const char *panic_origins[3] = {"", "PROCESS", "HANDLER"};
rv = ec_command(EC_CMD_GET_PANIC_INFO, 0, NULL, 0,
ec_inbuf, ec_max_insize);
@@ -1617,17 +1622,34 @@ int cmd_panic_info(int argc, char *argv[])
return 0;
}
+ /*
+ * We only understand panic data with version <= 2. Warn the user
+ * of higher versions.
+ */
+ if (pdata->struct_version > 2)
+ fprintf(stderr,
+ "Unknown panic data version (%d). "
+ "Following data may be incorrect!\n",
+ pdata->struct_version);
+
printf("Saved panic data:%s\n",
(pdata->flags & PANIC_DATA_FLAG_OLD_HOSTCMD ? "" : " (NEW)"));
- in_handler = ((pdata->regs[11] & 0xf) == 1 ||
- (pdata->regs[11] & 0xf) == 9);
+ if (pdata->struct_version == 2)
+ origin = ((lregs[11] & 0xf) == 1 || (lregs[11] & 0xf) == 9) ?
+ ORIG_HANDLER : ORIG_PROCESS;
+ /*
+ * In pdata struct, 'regs', which is allocated before 'frame', has
+ * one less elements in version 1. Therefore, if the data is from
+ * version 1, shift 'sregs' by one element to align with 'frame' in
+ * version 1.
+ */
if (pdata->flags & PANIC_DATA_FLAG_FRAME_VALID)
- sregs = pdata->frame;
+ sregs = pdata->frame - (pdata->struct_version == 1 ? 1 : 0);
printf("=== %s EXCEPTION: %02x ====== xPSR: %08x ===\n",
- in_handler ? "HANDLER" : "PROCESS",
+ panic_origins[origin],
lregs[1] & 0xff, sregs ? sregs[7] : -1);
for (i = 0; i < 4; ++i)
print_panic_reg(i, sregs, i);
@@ -1636,7 +1658,7 @@ int cmd_panic_info(int argc, char *argv[])
print_panic_reg(10, lregs, 9);
print_panic_reg(11, lregs, 10);
print_panic_reg(12, sregs, 4);
- print_panic_reg(13, lregs, in_handler ? 2 : 0);
+ print_panic_reg(13, lregs, origin == ORIG_HANDLER ? 2 : 0);
print_panic_reg(14, sregs, 5);
print_panic_reg(15, sregs, 6);