summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-07-13 16:40:43 -0700
committerRandall Spangler <rspangler@chromium.org>2012-07-16 10:20:58 -0700
commit7ee63359b86be2c5aa9567f51d28613f6e40213e (patch)
treeda54f47eb9ca0a9e76997be34fe15a575484367a
parent0e933d1ce987cb68e4c5682508aba47f925613ae (diff)
downloadchrome-ec-7ee63359b86be2c5aa9567f51d28613f6e40213e.tar.gz
Support preserving reset flags across a reset
This is needed for flash pre-init to be able to hard reset to clear uncommitted write protect flags without losing the reset flags. BUG=chrome-os-partner:11368 TEST=manual Use reboot and sysinfo commands... 1. reset with keyboard. flags -> reset-pin 2. 'reboot soft preserve' flags -> soft reset-pin power-on 3. 'reboot hard preserve' flags -> hard soft reset-pin power-on 4. 'reboot soft'. flags -> soft 5. 'reboot hard'. flags -> hard power-on Change-Id: I6164a78d99c5c10330f90f651148c5795e7afdda Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/27418
-rw-r--r--chip/lm4/system.c23
-rw-r--r--chip/stm32/system.c4
-rw-r--r--common/host_command.c2
-rw-r--r--common/system_common.c16
-rw-r--r--include/system.h17
5 files changed, 42 insertions, 20 deletions
diff --git a/chip/lm4/system.c b/chip/lm4/system.c
index 959c3e4232..7b0a3ed041 100644
--- a/chip/lm4/system.c
+++ b/chip/lm4/system.c
@@ -13,8 +13,9 @@
/* Indices for hibernate data registers */
enum hibdata_index {
- HIBDATA_INDEX_SCRATCHPAD, /* General-purpose scratchpad */
- HIBDATA_INDEX_WAKE, /* Wake reasons for hibernate */
+ HIBDATA_INDEX_SCRATCHPAD, /* General-purpose scratchpad */
+ HIBDATA_INDEX_WAKE, /* Wake reasons for hibernate */
+ HIBDATA_INDEX_SAVED_RESET_FLAGS /* Saved reset flags */
};
/* Flags for HIBDATA_INDEX_WAKE */
@@ -135,6 +136,9 @@ static void check_reset_cause(void)
if (hib_status & 0x04)
flags |= RESET_FLAG_LOW_BATTERY;
+ /* Restore then clear saved reset flags */
+ flags |= hibdata_read(HIBDATA_INDEX_SAVED_RESET_FLAGS);
+ hibdata_write(HIBDATA_INDEX_SAVED_RESET_FLAGS, 0);
system_set_reset_flags(flags);
}
@@ -247,18 +251,23 @@ int system_pre_init(void)
return EC_SUCCESS;
}
-void system_reset(int is_hard)
+void system_reset(int flags)
{
/* Disable interrupts to avoid task swaps during reboot */
interrupt_disable();
- if (is_hard) {
+ /* Save current reset reasons if necessary */
+ if (flags & SYSTEM_RESET_PRESERVE_FLAGS)
+ hibdata_write(HIBDATA_INDEX_SAVED_RESET_FLAGS,
+ system_get_reset_flags());
+ else
+ hibdata_write(HIBDATA_INDEX_SAVED_RESET_FLAGS, 0);
+
+ if (flags & SYSTEM_RESET_HARD) {
/* Bounce through hibernate to trigger a hard reboot */
hibernate(0, 50000, HIBDATA_WAKE_HARD_RESET);
- } else {
- /* Soft reboot */
+ } else
CPU_NVIC_APINT = 0x05fa0004;
- }
/* Spin and wait for reboot; should never return */
while (1)
diff --git a/chip/stm32/system.c b/chip/stm32/system.c
index 8f72fb04b5..4222bfefea 100644
--- a/chip/stm32/system.c
+++ b/chip/stm32/system.c
@@ -86,13 +86,13 @@ int system_pre_init(void)
}
-void system_reset(int is_hard)
+void system_reset(int flags)
{
/* Disable interrupts to avoid task swaps during reboot */
interrupt_disable();
/* TODO: (crosbug.com/p/7470) support hard boot; this is a
- * soft boot. */
+ * soft boot. And support preserving reset flags, too... */
CPU_NVIC_APINT = 0x05fa0004;
/* Spin and wait for reboot; should never return */
diff --git a/common/host_command.c b/common/host_command.c
index 158aa79726..1420e79434 100644
--- a/common/host_command.c
+++ b/common/host_command.c
@@ -47,7 +47,7 @@ void host_command_received(struct host_cmd_handler_args *args)
* other command.
*/
if (args->command == EC_CMD_REBOOT) {
- system_reset(1);
+ system_reset(SYSTEM_RESET_HARD);
/* Reset should never return; if it does, post an error */
host_send_response(EC_RES_ERROR);
return;
diff --git a/common/system_common.c b/common/system_common.c
index 87685abc40..680d0c90ed 100644
--- a/common/system_common.c
+++ b/common/system_common.c
@@ -519,7 +519,7 @@ static int handle_pending_reboot(enum ec_reboot_cmd cmd)
case EC_REBOOT_JUMP_RW_B:
return system_run_image_copy(SYSTEM_IMAGE_RW_B);
case EC_REBOOT_COLD:
- system_reset(1);
+ system_reset(SYSTEM_RESET_HARD);
/* That shouldn't return... */
return EC_ERROR_UNKNOWN;
case EC_REBOOT_DISABLE_JUMP:
@@ -676,24 +676,28 @@ DECLARE_CONSOLE_COMMAND(sysjump, command_sysjump,
static int command_reboot(int argc, char **argv)
{
- int is_hard = 0;
+ int flags = 0;
- if (argc == 2) {
+ if (argc >= 2) {
if (!strcasecmp(argv[1], "hard") ||
!strcasecmp(argv[1], "cold")) {
ccputs("Hard-");
- is_hard = 1;
+ flags |= SYSTEM_RESET_HARD;
+ } else if (!strcasecmp(argv[1], "soft")) {
+ /* No extra flags */
} else
return EC_ERROR_PARAM1;
}
+ if (argc >= 3 && !strcasecmp(argv[2], "preserve"))
+ flags |= SYSTEM_RESET_PRESERVE_FLAGS;
ccputs("Rebooting!\n\n\n");
cflush();
- system_reset(is_hard);
+ system_reset(flags);
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(reboot, command_reboot,
- "[hard]",
+ "[hard|soft] [preserve]",
"Reboot the EC",
NULL);
diff --git a/include/system.h b/include/system.h
index ba046cc1b6..02dc2ce2bb 100644
--- a/include/system.h
+++ b/include/system.h
@@ -124,10 +124,19 @@ int system_get_board_version(void);
* user/machine which performed the build. */
const char *system_get_build_info(void);
-/* Reset the system. If is_hard, performs a hard reset, which cuts power to
- * the entire system; else performs a soft reset (which resets the core and
- * on-chip peripherals, without actually cutting power to the chip). */
-void system_reset(int is_hard);
+/* Flags for system_reset() */
+/*
+ * Hard reset. Cuts power to the entire system. If not present, does a soft
+ * reset which just resets the core and on-chip peripherals.
+ */
+#define SYSTEM_RESET_HARD (1 << 0)
+/*
+ * Preserve existing reset flags. Used by flash pre-init when it discovers it
+ * needs to do a hard reset to clear write protect registers.
+ */
+#define SYSTEM_RESET_PRESERVE_FLAGS (1 << 1)
+
+void system_reset(int flags);
/* Set a scratchpad register to the specified value. The scratchpad
* register must maintain its contents across a software-requested