From 279c513865ebbd3bd860fd4be83d0827566de1df Mon Sep 17 00:00:00 2001 From: Jack Rosenthal Date: Mon, 6 May 2019 17:18:53 -0600 Subject: 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 Reviewed-on: https://chromium-review.googlesource.com/1599732 Commit-Ready: ChromeOS CL Exonerator Bot Reviewed-by: Jett Rink Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1609609 Commit-Queue: Jett Rink Tested-by: Jett Rink --- chip/ish/watchdog.c | 27 --------------------------- core/minute-ia/interrupts.c | 33 ++++++++++++++++++++++++--------- core/minute-ia/panic.c | 7 ++++++- 3 files changed, 30 insertions(+), 37 deletions(-) diff --git a/chip/ish/watchdog.c b/chip/ish/watchdog.c index fd0ebcf247..79f6e788df 100644 --- a/chip/ish/watchdog.c +++ b/chip/ish/watchdog.c @@ -20,7 +20,6 @@ */ #include "common.h" -#include "console.h" #include "hooks.h" #include "task.h" #include "registers.h" @@ -46,32 +45,6 @@ int watchdog_init(void) return EC_SUCCESS; } -/* Parameters are pushed by hardware, we only care about %EIP */ -__attribute__ ((noreturn)) -void watchdog_warning(uint32_t errorcode, - uint32_t eip, - uint32_t cs, - uint32_t eflags) -{ - ccprintf("\nWDT Expired. EIP was 0x%08X. Resetting...\n", eip); - cflush(); - - system_reset(SYSTEM_RESET_AP_WATCHDOG); - __builtin_unreachable(); -} - -__attribute__ ((noreturn)) -void watchdog_warning_irq(void) -{ - /* - * Parameters to watchdog_warning were pushed by hardware, use - * asm here to re-use these parameters in the call. - */ - __asm__ ("call watchdog_warning\n"); - __builtin_unreachable(); -} -DECLARE_IRQ(ISH_WDT_IRQ, watchdog_warning_irq); - void watchdog_reload(void) { /* 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); -- cgit v1.2.1