summaryrefslogtreecommitdiff
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
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>
-rw-r--r--chip/ish/watchdog.c27
-rw-r--r--core/minute-ia/interrupts.c33
-rw-r--r--core/minute-ia/panic.c7
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);