diff options
author | Jack Rosenthal <jrosenth@chromium.org> | 2019-05-13 15:22:36 -0600 |
---|---|---|
committer | Jack Rosenthal <jrosenth@chromium.org> | 2019-06-06 19:55:59 +0000 |
commit | 0c5985a74f66f89f05d6f26666c15229fc68d1df (patch) | |
tree | 99aaeabb8b1d4ac9cf302a170725876e715f5c2f | |
parent | c723e723392aabc35747a6678b4b7931d7aeddb7 (diff) | |
download | chrome-ec-0c5985a74f66f89f05d6f26666c15229fc68d1df.tar.gz |
ish: max-retries mechanism for watchdog timer
This adds a relevant config option, as well as implementation for a
max-retries mechanism on the watchdog timer. Included is an
implementation for ISH which counts persistent data storage and halts
when the max-retries is exceeded.
BUG=b:132059981
BRANCH=none
TEST=observed system halt after 4 resets, then re-enable once we had a
successful reset
Change-Id: I7b443d9a20a474b294d494c5b6046a38eaf6ff12
Signed-off-by: Jack Rosenthal <jrosenth@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1609605
Reviewed-by: Jett Rink <jettrink@chromium.org>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
-rw-r--r-- | chip/ish/system.c | 35 | ||||
-rw-r--r-- | chip/ish/watchdog.c | 8 | ||||
-rw-r--r-- | include/config.h | 7 |
3 files changed, 49 insertions, 1 deletions
diff --git a/chip/ish/system.c b/chip/ish/system.c index 0d778eaa5e..f634981817 100644 --- a/chip/ish/system.c +++ b/chip/ish/system.c @@ -10,6 +10,7 @@ #include "gpio.h" #include "hooks.h" #include "host_command.h" +#include "interrupts.h" #include "ish_fwst.h" #include "ish_persistent_data.h" #include "power_mgt.h" @@ -21,6 +22,10 @@ #include "timer.h" #include "util.h" +#define CPUTS(outstr) cputs(CC_SYSTEM, outstr) +#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) +#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) + int system_is_reboot_warm(void) { return !(system_get_reset_flags() & @@ -45,6 +50,27 @@ uint32_t chip_read_reset_flags(void) return ish_persistent_data.reset_flags; } +/* + * Kill the Minute-IA core and don't come back alive. + * + * Used when the watchdog timer exceeds max retries and we want to + * disable ISH completely. + */ +__attribute__((noreturn)) +static void system_halt(void) +{ + cflush(); + + while (1) { + disable_all_interrupts(); + WDT_CONTROL = 0; + CCU_TCG_EN = 1; + __asm__ volatile ( + "cli\n" + "hlt\n"); + } +} + void system_reset(int flags) { uint32_t save_flags; @@ -60,8 +86,15 @@ void system_reset(int flags) system_encode_save_flags(flags, &save_flags); - if (flags & SYSTEM_RESET_AP_WATCHDOG) + if (flags & SYSTEM_RESET_AP_WATCHDOG) { save_flags |= RESET_FLAG_WATCHDOG; + ish_persistent_data.watchdog_counter += 1; + if (ish_persistent_data.watchdog_counter + >= CONFIG_WATCHDOG_MAX_RETRIES) { + CPRINTS("Halting ISH due to max watchdog resets"); + system_halt(); + } + } chip_save_reset_flags(save_flags); diff --git a/chip/ish/watchdog.c b/chip/ish/watchdog.c index 79f6e788df..2e83b57f25 100644 --- a/chip/ish/watchdog.c +++ b/chip/ish/watchdog.c @@ -21,6 +21,7 @@ #include "common.h" #include "hooks.h" +#include "ish_persistent_data.h" #include "task.h" #include "registers.h" #include "system.h" @@ -32,6 +33,13 @@ int watchdog_init(void) { + /* + * Put reset counter back at zero if last reset was not caused + * by watchdog + */ + if ((system_get_reset_flags() & RESET_FLAG_WATCHDOG) == 0) + ish_persistent_data.watchdog_counter = 0; + /* Initialize WDT clock divider */ CCU_WDT_CD = WDT_CLOCK_HZ / 10; /* 10 Hz => 100 ms period */ diff --git a/include/config.h b/include/config.h index ce38ee658b..fcc4bf6727 100644 --- a/include/config.h +++ b/include/config.h @@ -3972,6 +3972,13 @@ */ #undef CONFIG_WATCHDOG_HELP +/* + * The maximum number of times that the watchdog timer may reset + * before halting the system (or taking some sort of other + * chip-dependent corrective action). + */ +#define CONFIG_WATCHDOG_MAX_RETRIES 4 + /* Watchdog period in ms; see also AUX_TIMER_PERIOD_MS */ #define CONFIG_WATCHDOG_PERIOD_MS 1600 |