diff options
author | Furquan Shaikh <furquan@chromium.org> | 2017-06-11 17:04:49 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-06-15 17:27:53 -0700 |
commit | 98b58b5b692a188a54fd06819a5c749655855556 (patch) | |
tree | 7f56a06f222d7bbafdf47d98067d5be4fc956612 | |
parent | 7e59da99a2e76c1094b8bce675fb42ca384e7988 (diff) | |
download | chrome-ec-98b58b5b692a188a54fd06819a5c749655855556.tar.gz |
chip/npcx: Add support for saving/restoring panic data
For some platforms like poppy/eve where a PMIC reset is required on
reboot/panic to ensure a complete power-cycle of the AP, there is a
drop on VCC power rail thus resulting in a loss of panic data. For
such cases, provide API to backup panic data in BBRAM before
performing a PMIC reset. Additionally, check for panic data in
system_pre_init and restore if available from BBRAM.
BUG=b:62076222
BRANCH=None
TEST=make -j buildall
1. > crash divzero
> panic
=== PROCESS EXCEPTION: 06 ====== xPSR: ffffffff ===
r0 : r1 : r2 : r3 :
r4 :00000001 r5 :00000000 r6 :00000000 r7 :00000000
r8 :00000000 r9 :00000000 r10:00000000 r11:00000000
r12: sp :00000000 lr : pc :
Divide by 0
mmfs = 2000000, shcsr = 0, hfsr = 0, dfsr = 0
2. > crash assert
> panic
=== PROCESS EXCEPTION: 00 ====== xPSR: ffffffff ===
r0 : r1 : r2 : r3 :
r4 :dead6663 r5 :000000a4 r6 :00000000 r7 :00000000
r8 :00000000 r9 :00000000 r10:00000000 r11:00000000
r12: sp :00000000 lr : pc :
mmfs = 0, shcsr = 0, hfsr = 0, dfsr = 0
3. > crash watchdog
> panic
=== PROCESS EXCEPTION: 3c ====== xPSR: ffffffff ===
r0 : r1 : r2 : r3 :
r4 :dead6664 r5 :0000000a r6 :00000000 r7 :00000000
r8 :00000000 r9 :00000000 r10:00000000 r11:00000000
r12: sp :00000000 lr : pc :
mmfs = 0, shcsr = 0, hfsr = 0, dfsr = 0
4. > crash unaligned
> panic
=== PROCESS EXCEPTION: 06 ====== xPSR: ffffffff ===
r0 : r1 : r2 : r3 :
r4 :200c0d9e r5 :00000000 r6 :00000000 r7 :00000000
r8 :00000000 r9 :00000000 r10:00000000 r11:00000000
r12: sp :00000000 lr : pc :
Unaligned
mmfs = 1000000, shcsr = 0, hfsr = 0, dfsr = 0
Change-Id: I95cdd55e260487903e089653a47d3995d177daed
Signed-off-by: Furquan Shaikh <furquan@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/530136
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | chip/npcx/system.c | 81 | ||||
-rw-r--r-- | chip/npcx/system_chip.h | 5 |
2 files changed, 86 insertions, 0 deletions
diff --git a/chip/npcx/system.c b/chip/npcx/system.c index 5a6327fe04..f0f698684a 100644 --- a/chip/npcx/system.c +++ b/chip/npcx/system.c @@ -81,6 +81,7 @@ static int bbram_is_byte_access(enum bbram_data_index index) || index == BBRM_DATA_INDEX_PD0 || index == BBRM_DATA_INDEX_PD1 #endif + || index == BBRM_DATA_INDEX_PANIC_FLAGS ; } @@ -228,6 +229,82 @@ void system_set_rtc(uint32_t seconds) udelay(MTC_TTC_LOAD_DELAY_US); } +#ifdef CONFIG_CHIP_PANIC_BACKUP +/* + * Following information from panic data is stored in BBRAM: + * + * index | data + * ==========|============= + * 36 | MMFS + * 40 | HFSR + * 44 | BFAR + * 48 | LREG1 + * 52 | LREG3 + * 56 | LREG4 + * 60 | reserved + * + * Above registers are chosen to be saved in case of panic because: + * 1. MMFS, HFSR and BFAR seem to provide more information about the fault. + * 2. LREG1, LREG3 and LREG4 store exception, reason and info in case of + * software panic. + */ +#define BKUP_MMFS (BBRM_DATA_INDEX_PANIC_BKUP + 0) +#define BKUP_HFSR (BBRM_DATA_INDEX_PANIC_BKUP + 4) +#define BKUP_BFAR (BBRM_DATA_INDEX_PANIC_BKUP + 8) +#define BKUP_LREG1 (BBRM_DATA_INDEX_PANIC_BKUP + 12) +#define BKUP_LREG3 (BBRM_DATA_INDEX_PANIC_BKUP + 16) +#define BKUP_LREG4 (BBRM_DATA_INDEX_PANIC_BKUP + 20) + +#define BKUP_PANIC_DATA_VALID (1 << 0) + +void chip_panic_data_backup(void) +{ + struct panic_data *d = panic_get_data(); + + if (!d) + return; + + bbram_data_write(BKUP_MMFS, d->cm.mmfs); + bbram_data_write(BKUP_HFSR, d->cm.hfsr); + bbram_data_write(BKUP_BFAR, d->cm.dfsr); + bbram_data_write(BKUP_LREG1, d->cm.regs[1]); + bbram_data_write(BKUP_LREG3, d->cm.regs[3]); + bbram_data_write(BKUP_LREG4, d->cm.regs[4]); + bbram_data_write(BBRM_DATA_INDEX_PANIC_FLAGS, BKUP_PANIC_DATA_VALID); +} + +static void chip_panic_data_restore(void) +{ + struct panic_data *d = PANIC_DATA_PTR; + + /* Ensure BBRAM is valid. */ + if (!bbram_valid(BKUP_MMFS, 4)) + return; + + /* Ensure Panic data in BBRAM is valid. */ + if (!(bbram_data_read(BBRM_DATA_INDEX_PANIC_FLAGS) & + BKUP_PANIC_DATA_VALID)) + return; + + memset(d, 0, sizeof(*d)); + d->magic = PANIC_DATA_MAGIC; + d->struct_size = sizeof(*d); + d->struct_version = 2; + d->arch = PANIC_ARCH_CORTEX_M; + + d->cm.mmfs = bbram_data_read(BKUP_MMFS); + d->cm.hfsr = bbram_data_read(BKUP_HFSR); + d->cm.dfsr = bbram_data_read(BKUP_BFAR); + + d->cm.regs[1] = bbram_data_read(BKUP_LREG1); + d->cm.regs[3] = bbram_data_read(BKUP_LREG3); + d->cm.regs[4] = bbram_data_read(BKUP_LREG4); + + /* Reset panic data in BBRAM. */ + bbram_data_write(BBRM_DATA_INDEX_PANIC_FLAGS, 0); +} +#endif /* CONFIG_CHIP_PANIC_BACKUP */ + void chip_save_reset_flags(int flags) { bbram_data_write(BBRM_DATA_INDEX_SAVED_RESET_FLAGS, flags); @@ -559,6 +636,10 @@ void system_pre_init(void) * and DATA RAM to prevent code execution */ system_mpu_config(); + +#ifdef CONFIG_CHIP_PANIC_BACKUP + chip_panic_data_restore(); +#endif } void system_reset(int flags) diff --git a/chip/npcx/system_chip.h b/chip/npcx/system_chip.h index 750eb7a662..21560895c5 100644 --- a/chip/npcx/system_chip.h +++ b/chip/npcx/system_chip.h @@ -21,6 +21,11 @@ enum bbram_data_index { BBRM_DATA_INDEX_PD1 = 13, /* USB-PD saved port1 state */ BBRM_DATA_INDEX_VBNVCNTXT = 16, /* VbNvContext for ARM arch */ BBRM_DATA_INDEX_RAMLOG = 32, /* RAM log for Booter */ + BBRM_DATA_INDEX_PANIC_FLAGS = 35, /* Flag to indicate validity of + * panic data starting at index + * 36. + */ + BBRM_DATA_INDEX_PANIC_BKUP = 36, /* Panic data (index 35-63)*/ }; /* Issue a watchdog reset*/ |