diff options
author | Jack Rosenthal <jrosenth@chromium.org> | 2019-05-06 17:18:53 -0600 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-05-09 16:05:41 -0700 |
commit | 444754d08f5bb5d4ccd4914549d8a7dea3081169 (patch) | |
tree | 43b52be71f6d45a875c58450887a2115edad1f97 /core | |
parent | 6513dabd100d20a0c15ab65c126d865159672568 (diff) | |
download | chrome-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.c | 33 | ||||
-rw-r--r-- | core/minute-ia/panic.c | 7 |
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); |