From d142b71d2d4673f54e6c560f01e67168ade74c73 Mon Sep 17 00:00:00 2001 From: Jack Rosenthal Date: Fri, 10 May 2019 11:48:29 -0600 Subject: ish: save and restore reset flags across reset In order to implement watchdog reset counter, we need to be saving and restoring reset flags. b:132457636 explains the details of the memory layout chosen for the soft-register. BUG=b:132366384,b:132457636 BRANCH=none TEST=reset arcada_ish using: `reboot' command, watchdog expiration, and cold-reset, observed the correct value for "reset cause" printed during boot Change-Id: I84b965803d37703fac6494fb55a97c674ce64b89 Signed-off-by: Jack Rosenthal Reviewed-on: https://chromium-review.googlesource.com/1606074 Reviewed-by: Jett Rink Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1615651 Commit-Queue: Jett Rink Tested-by: Jett Rink --- chip/ish/registers.h | 4 ++++ chip/ish/system.c | 32 ++++++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 8 deletions(-) (limited to 'chip') diff --git a/chip/ish/registers.h b/chip/ish/registers.h index b00cce72e5..eb028b403d 100644 --- a/chip/ish/registers.h +++ b/chip/ish/registers.h @@ -338,6 +338,10 @@ enum ish_i2c_port { /* Software defined registers */ +/* Persistent reset flags - placed directly at end of panic data */ +#define ISH_RESET_FLAGS REG32(CONFIG_PANIC_DATA_BASE \ + + CONFIG_PANIC_DATA_SIZE) + #if defined(CHIP_FAMILY_ISH3) /* on ISH3, reused ISH2PMC IPC message registers */ #define SNOWBALL_BASE IPC_ISH2PMC_MSG_BASE diff --git a/chip/ish/system.c b/chip/ish/system.c index 2389140aca..560a71678b 100644 --- a/chip/ish/system.c +++ b/chip/ish/system.c @@ -30,7 +30,8 @@ enum hibdata_index { int system_is_reboot_warm(void) { - return 0; + return !(system_get_reset_flags() & + (RESET_FLAG_POWER_ON | RESET_FLAG_HARD)); } void system_pre_init(void) @@ -39,34 +40,49 @@ void system_pre_init(void) task_enable_irq(ISH_FABRIC_IRQ); -#ifdef CONFIG_LOW_POWER_IDLE - ish_pm_init(); -#endif + if (IS_ENABLED(CONFIG_LOW_POWER_IDLE)) + ish_pm_init(); + + system_set_reset_flags(chip_read_reset_flags()); } void chip_save_reset_flags(int flags) { + ISH_RESET_FLAGS = flags; } uint32_t chip_read_reset_flags(void) { - return 0; + uint32_t flags = ISH_RESET_FLAGS; + + if (flags) + return flags; + + /* Flags are zero? Assume we came up from a cold reset */ + return RESET_FLAG_POWER_ON; } void system_reset(int flags) { + uint32_t save_flags; + + system_encode_save_flags(flags, &save_flags); + + if (flags & SYSTEM_RESET_AP_WATCHDOG) + save_flags |= RESET_FLAG_WATCHDOG; + + chip_save_reset_flags(save_flags); + /* * ish_pm_reset() does more (poweroff main SRAM, etc) than * ish_mia_reset() which just resets the ISH minute-ia cpu core */ - if (!IS_ENABLED(CONFIG_LOW_POWER_IDLE) || flags & SYSTEM_RESET_HARD) ish_mia_reset(); else ish_pm_reset(); - while(1) - ; + __builtin_unreachable(); } const char *system_get_chip_vendor(void) -- cgit v1.2.1