diff options
author | Randall Spangler <rspangler@chromium.org> | 2012-07-13 16:40:43 -0700 |
---|---|---|
committer | Randall Spangler <rspangler@chromium.org> | 2012-07-16 10:20:58 -0700 |
commit | 7ee63359b86be2c5aa9567f51d28613f6e40213e (patch) | |
tree | da54f47eb9ca0a9e76997be34fe15a575484367a | |
parent | 0e933d1ce987cb68e4c5682508aba47f925613ae (diff) | |
download | chrome-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.c | 23 | ||||
-rw-r--r-- | chip/stm32/system.c | 4 | ||||
-rw-r--r-- | common/host_command.c | 2 | ||||
-rw-r--r-- | common/system_common.c | 16 | ||||
-rw-r--r-- | include/system.h | 17 |
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 |