summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorJack Rosenthal <jrosenth@chromium.org>2019-05-06 17:18:53 -0600
committerchrome-bot <chrome-bot@chromium.org>2019-05-09 16:05:41 -0700
commit444754d08f5bb5d4ccd4914549d8a7dea3081169 (patch)
tree43b52be71f6d45a875c58450887a2115edad1f97 /core
parent6513dabd100d20a0c15ab65c126d865159672568 (diff)
downloadchrome-ec-444754d08f5bb5d4ccd4914549d8a7dea3081169.tar.gz
ish: combine watchdog expiration and panic handler
watchdog_warning implements similar functionality to exception_panic, but worse, as the value it prints for EIP is wrong, and it does not have the no-double-panic logic of the panic handler. This commit removes watchdog_warning and integrates the relevant functionality into exception_panic. BUG=b:129983997 BRANCH=none TEST=observed watchdog reset with 'waitms 10500' Change-Id: I78375337aa85be5424850e29a8204c409384d019 Signed-off-by: Jack Rosenthal <jrosenth@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1599732 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Reviewed-by: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'core')
-rw-r--r--core/minute-ia/interrupts.c33
-rw-r--r--core/minute-ia/panic.c7
2 files changed, 30 insertions, 10 deletions
diff --git a/core/minute-ia/interrupts.c b/core/minute-ia/interrupts.c
index efa07ef062..5e69b9c199 100644
--- a/core/minute-ia/interrupts.c
+++ b/core/minute-ia/interrupts.c
@@ -169,15 +169,19 @@ static const irq_desc_t system_irqs[] = {
* and go directly to the CPU core, so get_current_interrupt_vector
* cannot be used.
*/
-#define DEFINE_EXN_HANDLER(vector) \
- void __keep exception_panic_##vector(void); \
- __attribute__ ((noreturn)) void exception_panic_##vector(void) \
- { \
- __asm__ ( \
- "push $" #vector "\n" \
- "call exception_panic\n"); \
- while (1) \
- continue; \
+#define DEFINE_EXN_HANDLER(vector) \
+ _DEFINE_EXN_HANDLER(vector, exception_panic_##vector)
+#define _DEFINE_EXN_HANDLER(vector, name) \
+ __DEFINE_EXN_HANDLER(vector, name)
+#define __DEFINE_EXN_HANDLER(vector, name) \
+ void __keep name(void); \
+ __attribute__ ((noreturn)) void name(void) \
+ { \
+ __asm__ ( \
+ "push $" #vector "\n" \
+ "call exception_panic\n"); \
+ while (1) \
+ continue; \
}
DEFINE_EXN_HANDLER(0);
@@ -200,6 +204,7 @@ DEFINE_EXN_HANDLER(17);
DEFINE_EXN_HANDLER(18);
DEFINE_EXN_HANDLER(19);
DEFINE_EXN_HANDLER(20);
+_DEFINE_EXN_HANDLER(ISH_WDT_VEC, exception_panic_wdt);
void set_interrupt_gate(uint8_t num, isr_handler_t func, uint8_t flags)
{
@@ -457,6 +462,16 @@ void init_interrupts(void)
set_interrupt_gate(19, exception_panic_19, IDT_DESC_FLAGS);
set_interrupt_gate(20, exception_panic_20, IDT_DESC_FLAGS);
+ /*
+ * Set up watchdog expiration like a panic, that way we can
+ * use the common panic handling code, and also properly
+ * retrieve EIP.
+ */
+ if (IS_ENABLED(CONFIG_WATCHDOG))
+ set_interrupt_gate(ISH_WDT_VEC,
+ exception_panic_wdt,
+ IDT_DESC_FLAGS);
+
/* Note: At reset, ID field is already set to 0 in APIC ID register */
/* Enable the APIC, mapping the spurious interrupt at the same time. */
diff --git a/core/minute-ia/panic.c b/core/minute-ia/panic.c
index 40e8ee1cf0..0898e4e717 100644
--- a/core/minute-ia/panic.c
+++ b/core/minute-ia/panic.c
@@ -50,7 +50,9 @@ const static char *panic_reason[] = {
*/
void panic_data_print(const struct panic_data *pdata)
{
- if (pdata->x86.vector <= 20)
+ if (pdata->x86.vector == ISH_WDT_VEC)
+ panic_printf("Reason: Watchdog Expiration\n");
+ else if (pdata->x86.vector <= 20)
panic_printf("Reason: %s\n", panic_reason[pdata->x86.vector]);
else
panic_printf("Interrupt vector number: 0x%08X (unknown)\n",
@@ -134,6 +136,9 @@ __attribute__ ((noreturn)) void __keep exception_panic(
if (panic_once) {
system_reset(SYSTEM_RESET_HARD);
+ } else if (vector == ISH_WDT_VEC) {
+ panic_once = 1;
+ system_reset(SYSTEM_RESET_AP_WATCHDOG);
} else {
panic_once = 1;
system_reset(0);