summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFurquan Shaikh <furquan@chromium.org>2017-06-11 17:04:49 -0700
committerchrome-bot <chrome-bot@chromium.org>2017-06-15 17:27:53 -0700
commit98b58b5b692a188a54fd06819a5c749655855556 (patch)
tree7f56a06f222d7bbafdf47d98067d5be4fc956612
parent7e59da99a2e76c1094b8bce675fb42ca384e7988 (diff)
downloadchrome-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.c81
-rw-r--r--chip/npcx/system_chip.h5
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*/