summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@chromium.org>2018-10-22 16:56:10 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-10-29 04:15:05 -0700
commit51a6070f845ed670c5a198a7045af3d3bb3bbdd4 (patch)
treea247c66e5299aae1d9a657fdd695c3759063ec40
parent149190dd3a823d835be71ec4b4e4ae9e5120c774 (diff)
downloadchrome-ec-51a6070f845ed670c5a198a7045af3d3bb3bbdd4.tar.gz
system: Remember if reset was due to AP watchdog triggering
On MT8183, when EC detects a watchdog reset, EC needs to reboot itself in preparation for the next boot. This means that AP loses the reset cause (as AP system reset is toggled), and, therefore, we need to save the reset reason in the EC. BRANCH=none BUG=b:109900671 TEST=apshutdown, powerb, see that reset reason is: reset-pin TEST=Use test-wd from bug. Reset reason: reset-pin ap-watchdog Change-Id: I2e30306db5727a22de930f00dc30de40b9695bef Signed-off-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1295890 Reviewed-by: Jett Rink <jettrink@chromium.org>
-rw-r--r--chip/stm32/system.c32
-rw-r--r--common/system.c2
-rw-r--r--include/system.h5
-rw-r--r--power/mt8183.c7
-rw-r--r--util/ectool.c3
5 files changed, 46 insertions, 3 deletions
diff --git a/chip/stm32/system.c b/chip/stm32/system.c
index a03550d7f9..c7ff4f23d9 100644
--- a/chip/stm32/system.c
+++ b/chip/stm32/system.c
@@ -33,9 +33,26 @@
/* We use 16-bit BKP / BBRAM entries. */
#define STM32_BKP_ENTRIES (STM32_BKP_BYTES / 2)
+/*
+ * Use 32-bit for reset flags, if we have space for it:
+ * - 2 indexes are used unconditionally (SCRATCHPAD and SAVED_RESET_FLAGS)
+ * - VBNV_CONTEXT requires 8 indexes, so a total of 10 (which is the total
+ * number of entries on some STM32 variants).
+ * - Other config options are not a problem (they only take a few entries)
+ *
+ * Given this, we can only add an extra entry for the top 16-bit of reset flags
+ * if VBNV_CONTEXT is not enabled, or if we have more than 10 entries.
+ */
+#if !defined(CONFIG_HOSTCMD_VBNV_CONTEXT) || STM32_BKP_ENTRIES > 10
+#define CONFIG_STM32_RESET_FLAGS_EXTENDED
+#endif
+
enum bkpdata_index {
BKPDATA_INDEX_SCRATCHPAD, /* General-purpose scratchpad */
BKPDATA_INDEX_SAVED_RESET_FLAGS, /* Saved reset flags */
+#ifdef CONFIG_STM32_RESET_FLAGS_EXTENDED
+ BKPDATA_INDEX_SAVED_RESET_FLAGS_2, /* Saved reset flags (cont) */
+#endif
#ifdef CONFIG_HOSTCMD_VBNV_CONTEXT
BKPDATA_INDEX_VBNV_CONTEXT0,
BKPDATA_INDEX_VBNV_CONTEXT1,
@@ -152,12 +169,19 @@ static void check_reset_cause(void)
uint32_t raw_cause = STM32_RCC_RESET_CAUSE;
uint32_t pwr_status = STM32_PWR_RESET_CAUSE;
+#ifdef CONFIG_STM32_RESET_FLAGS_EXTENDED
+ flags |= bkpdata_read(BKPDATA_INDEX_SAVED_RESET_FLAGS_2) << 16;
+#endif
+
/* Clear the hardware reset cause by setting the RMVF bit */
STM32_RCC_RESET_CAUSE |= RESET_CAUSE_RMVF;
/* Clear SBF in PWR_CSR */
STM32_PWR_RESET_CAUSE_CLR |= RESET_CAUSE_SBF_CLR;
/* Clear saved reset flags */
bkpdata_write(BKPDATA_INDEX_SAVED_RESET_FLAGS, 0);
+#ifdef CONFIG_STM32_RESET_FLAGS_EXTENDED
+ bkpdata_write(BKPDATA_INDEX_SAVED_RESET_FLAGS_2, 0);
+#endif
if (raw_cause & RESET_CAUSE_WDG) {
/*
@@ -343,9 +367,17 @@ void system_reset(int flags)
if (flags & SYSTEM_RESET_HARD)
save_flags |= RESET_FLAG_HARD;
+#ifdef CONFIG_STM32_RESET_FLAGS_EXTENDED
+ if (flags & SYSTEM_RESET_AP_WATCHDOG)
+ save_flags |= RESET_FLAG_AP_WATCHDOG;
+
+ bkpdata_write(BKPDATA_INDEX_SAVED_RESET_FLAGS, save_flags & 0xffff);
+ bkpdata_write(BKPDATA_INDEX_SAVED_RESET_FLAGS_2, save_flags >> 16);
+#else
/* Reset flags are 32-bits, but BBRAM entry is only 16 bits. */
ASSERT(!(save_flags >> 16));
bkpdata_write(BKPDATA_INDEX_SAVED_RESET_FLAGS, save_flags);
+#endif
if (flags & SYSTEM_RESET_HARD) {
#ifdef CONFIG_SOFTWARE_PANIC
diff --git a/common/system.c b/common/system.c
index 4e0ab91c2f..e2ef1ee5ff 100644
--- a/common/system.c
+++ b/common/system.c
@@ -93,7 +93,7 @@ static const char * const reset_flag_descs[] = {
"other", "reset-pin", "brownout", "power-on", "watchdog", "soft",
"hibernate", "rtc-alarm", "wake-pin", "low-battery", "sysjump",
"hard", "ap-off", "preserved", "usb-resume", "rdd", "rbox",
- "security" };
+ "security", "ap-watchdog" };
static uint32_t reset_flags;
static int jumped_to_image;
diff --git a/include/system.h b/include/system.h
index c040bca840..ca7b24c624 100644
--- a/include/system.h
+++ b/include/system.h
@@ -33,6 +33,7 @@
#define RESET_FLAG_RDD (1 << 15) /* USB Type-C debug cable */
#define RESET_FLAG_RBOX (1 << 16) /* Fixed Reset Functionality */
#define RESET_FLAG_SECURITY (1 << 17) /* Security threat */
+#define RESET_FLAG_AP_WATCHDOG (1 << 18) /* AP experienced a watchdog reset */
/* Per chip implementation to save/read raw RESET_FLAG_ flags. */
void chip_save_reset_flags(int flags);
@@ -274,6 +275,10 @@ const char *system_get_build_info(void);
* Wait for reset pin to be driven, rather that resetting ourselves.
*/
#define SYSTEM_RESET_WAIT_EXT (1 << 4)
+/*
+ * Indicate that this reset was triggered by an AP watchdog
+ */
+#define SYSTEM_RESET_AP_WATCHDOG (1 << 5)
/**
* Reset the system.
diff --git a/power/mt8183.c b/power/mt8183.c
index 631f2f3c7f..ff842ba01c 100644
--- a/power/mt8183.c
+++ b/power/mt8183.c
@@ -140,11 +140,16 @@ DECLARE_DEFERRED(chipset_force_shutdown_button);
/* If chipset needs to be reset, EC also reboots to RO. */
void chipset_reset(enum chipset_reset_reason reason)
{
+ int flags = SYSTEM_RESET_HARD;
+
CPRINTS("%s: %d", __func__, reason);
report_ap_reset(reason);
cflush();
- system_reset(SYSTEM_RESET_HARD);
+ if (reason == CHIPSET_RESET_AP_WATCHDOG)
+ flags |= SYSTEM_RESET_AP_WATCHDOG;
+
+ system_reset(flags);
/* This should not be reachable. */
while (1)
diff --git a/util/ectool.c b/util/ectool.c
index bd7725131e..4cb4b71623 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -769,7 +769,8 @@ int cmd_uptimeinfo(int argc, char *argv[])
"usb-resume",
"rdd",
"rbox",
- "security"
+ "security",
+ "ap-watchdog"
};
struct ec_response_uptime_info r;