diff options
-rw-r--r-- | core/cortex-m/panic.c | 2 | ||||
-rw-r--r-- | include/panic.h | 7 | ||||
-rw-r--r-- | util/ectool.c | 34 |
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); |