From 085b31222b9f34e5470031fe1e957804beded69d Mon Sep 17 00:00:00 2001 From: Randall Spangler Date: Sun, 22 Jul 2012 14:00:37 -0700 Subject: Refactor reboot command to add ap-off and cancel options Also add 'preserve' flag, for tracking when flags have been preserved from a previous boot. BUG=chrome-os-partner:11663 TEST=manual reboot -> flags = soft reboot preserve -> flags = soft preserve From ectool, 'ectool reboot_ec cold at-shutdown' sysinfo -> shows reboot at shutdown: 4 reboot cancel sysinfo -> no longer shows pending reboot reboot ap-off -> flags = soft ap-off, AP is not powered on Change-Id: I117f33fe21048edb2261be4dcdc6c828a5794d54 Signed-off-by: Randall Spangler Reviewed-on: https://gerrit.chromium.org/gerrit/28139 --- chip/lm4/power_button.c | 17 +++++++++++------ chip/lm4/system.c | 12 ++++++++---- chip/stm32/system.c | 14 +++++++++----- common/gaia_power.c | 9 +++++++-- common/system_common.c | 26 ++++++++++++++++++-------- include/system.h | 10 +++++++++- 6 files changed, 62 insertions(+), 26 deletions(-) diff --git a/chip/lm4/power_button.c b/chip/lm4/power_button.c index b0f32f0997..e209cd4403 100644 --- a/chip/lm4/power_button.c +++ b/chip/lm4/power_button.c @@ -285,6 +285,8 @@ static void lid_switch_changed(uint64_t tnow) /* Set initial power button state */ static void set_initial_pwrbtn_state(void) { + uint32_t reset_flags = system_get_reset_flags(); + if (system_jumped_to_this_image() && chipset_in_state(CHIPSET_STATE_ON)) { /* @@ -295,13 +297,16 @@ static void set_initial_pwrbtn_state(void) *memmap_switches |= EC_SWITCH_POWER_BUTTON_PRESSED; set_pwrbtn_to_pch(0); } - } else if ((system_get_reset_flags() & RESET_FLAG_RESET_PIN) && - keyboard_scan_get_boot_key() == BOOT_KEY_DOWN_ARROW) { + } else if ((reset_flags & RESET_FLAG_AP_OFF) || + ((reset_flags & RESET_FLAG_RESET_PIN) && + keyboard_scan_get_boot_key() == BOOT_KEY_DOWN_ARROW)) { /* * Reset triggered by keyboard-controlled reset, and down-arrow - * was held down. Leave the main processor off. This is a - * fail-safe combination for debugging failures booting the - * main processor. + * was held down. Or reset flags request AP off. + * + * Leave the main processor off. This is a fail-safe + * combination for debugging failures booting the main + * processor. * * Don't let the PCH see that the power button was pressed. * Otherwise, it might power on. @@ -325,7 +330,7 @@ static void set_initial_pwrbtn_state(void) if (get_power_button_pressed()) { *memmap_switches |= EC_SWITCH_POWER_BUTTON_PRESSED; - if (system_get_reset_flags() & RESET_FLAG_RESET_PIN) + if (reset_flags & RESET_FLAG_RESET_PIN) pwrbtn_state = PWRBTN_STATE_BOOT_KB_RESET; else pwrbtn_state = PWRBTN_STATE_WAS_OFF; diff --git a/chip/lm4/system.c b/chip/lm4/system.c index 7b0a3ed041..4d7a36972e 100644 --- a/chip/lm4/system.c +++ b/chip/lm4/system.c @@ -253,15 +253,19 @@ int system_pre_init(void) void system_reset(int flags) { + uint32_t save_flags = 0; + /* Disable interrupts to avoid task swaps during reboot */ interrupt_disable(); /* 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); + save_flags = system_get_reset_flags() | RESET_FLAG_PRESERVED; + + if (flags & SYSTEM_RESET_LEAVE_AP_OFF) + save_flags |= RESET_FLAG_AP_OFF; + + hibdata_write(HIBDATA_INDEX_SAVED_RESET_FLAGS, save_flags); if (flags & SYSTEM_RESET_HARD) { /* Bounce through hibernate to trigger a hard reboot */ diff --git a/chip/stm32/system.c b/chip/stm32/system.c index a28abf41c9..026bcc8bb7 100644 --- a/chip/stm32/system.c +++ b/chip/stm32/system.c @@ -218,15 +218,19 @@ int system_pre_init(void) void system_reset(int flags) { + uint32_t save_flags = 0; + /* Disable interrupts to avoid task swaps during reboot */ interrupt_disable(); - /* Save current reset reason if necessary */ + /* Save current reset reasons if necessary */ if (flags & SYSTEM_RESET_PRESERVE_FLAGS) - bkpdata_write(BKPDATA_INDEX_SAVED_RESET_FLAGS, - system_get_reset_flags()); - else - bkpdata_write(BKPDATA_INDEX_SAVED_RESET_FLAGS, 0); + save_flags = system_get_reset_flags() | RESET_FLAG_PRESERVED; + + if (flags & SYSTEM_RESET_LEAVE_AP_OFF) + save_flags |= RESET_FLAG_AP_OFF; + + bkpdata_write(BKPDATA_INDEX_SAVED_RESET_FLAGS, save_flags); if (flags & SYSTEM_RESET_HARD) { #ifdef CHIP_VARIANT_stm32f100 diff --git a/common/gaia_power.c b/common/gaia_power.c index 9d009c9e98..48377523c3 100644 --- a/common/gaia_power.c +++ b/common/gaia_power.c @@ -23,13 +23,14 @@ * - If XPSHOLD is dropped by the AP, then we power the AP off */ -#include "board.h" #include "chipset.h" /* This module implements chipset functions too */ +#include "common.h" #include "console.h" #include "gpio.h" #include "hooks.h" #include "keyboard_scan.h" #include "power_led.h" +#include "system.h" #include "task.h" #include "timer.h" #include "util.h" @@ -247,7 +248,11 @@ int gaia_power_init(void) gpio_enable_interrupt(GPIO_SOC1V8_XPSHOLD); gpio_enable_interrupt(GPIO_SUSPEND_L); - /* auto power on if the recovery combination was pressed */ + /* Leave power off if requested by reset flags */ + if (system_get_reset_flags() & RESET_FLAG_AP_OFF) + auto_power_on = 0; + + /* Auto power on if the recovery combination was pressed */ if (keyboard_scan_recovery_pressed()) auto_power_on = 1; diff --git a/common/system_common.c b/common/system_common.c index 3251a79a56..198257057f 100644 --- a/common/system_common.c +++ b/common/system_common.c @@ -73,7 +73,7 @@ static struct jump_data * const jdata = static const char * const reset_flag_descs[] = { "other", "reset-pin", "brownout", "power-on", "watchdog", "soft", "hibernate", "rtc-alarm", "wake-pin", "low-battery", "sysjump", - "hard"}; + "hard", "ap-off", "preserved"}; static const char * const image_names[] = {"unknown", "RO", "RW"}; static uint32_t reset_flags; @@ -545,6 +545,9 @@ static int command_sysinfo(int argc, char **argv) ccputs(" unlocked"); ccputs("\n"); + if (reboot_at_shutdown) + ccprintf("Reboot at shutdown: %d\n", reboot_at_shutdown); + return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(sysinfo, command_sysinfo, @@ -659,27 +662,34 @@ DECLARE_CONSOLE_COMMAND(sysjump, command_sysjump, static int command_reboot(int argc, char **argv) { int flags = 0; + int i; - if (argc >= 2) { - if (!strcasecmp(argv[1], "hard") || - !strcasecmp(argv[1], "cold")) { - ccputs("Hard-"); + for (i = 1; i < argc; i++) { + if (!strcasecmp(argv[i], "hard") || + !strcasecmp(argv[i], "cold")) { flags |= SYSTEM_RESET_HARD; } else if (!strcasecmp(argv[1], "soft")) { - /* No extra flags */ + flags &= ~SYSTEM_RESET_HARD; + } else if (!strcasecmp(argv[1], "ap-off")) { + flags |= SYSTEM_RESET_LEAVE_AP_OFF; + } else if (!strcasecmp(argv[1], "cancel")) { + reboot_at_shutdown = EC_REBOOT_CANCEL; + return EC_SUCCESS; } else - return EC_ERROR_PARAM1; + return EC_ERROR_PARAM1 + i - 1; } if (argc >= 3 && !strcasecmp(argv[2], "preserve")) flags |= SYSTEM_RESET_PRESERVE_FLAGS; + if (flags & SYSTEM_RESET_HARD) + ccputs("Hard-"); ccputs("Rebooting!\n\n\n"); cflush(); system_reset(flags); return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(reboot, command_reboot, - "[hard|soft] [preserve]", + "[hard|soft] [preserve] [ap-off] [cancel]", "Reboot the EC", NULL); diff --git a/include/system.h b/include/system.h index 4e2fcdaabe..4bcde16aae 100644 --- a/include/system.h +++ b/include/system.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved. +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -23,6 +23,9 @@ #define RESET_FLAG_LOW_BATTERY (1 << 9) /* Low battery triggered wake */ #define RESET_FLAG_SYSJUMP (1 << 10) /* Jumped directly to this image */ #define RESET_FLAG_HARD (1 << 11) /* Hard reset from software */ +#define RESET_FLAG_AP_OFF (1 << 12) /* Do not power on AP */ +#define RESET_FLAG_PRESERVED (1 << 13) /* Some reset flags preserved from + * previous boot */ /* System images */ enum system_image_copy_t { @@ -134,6 +137,11 @@ const char *system_get_build_info(void); * needs to do a hard reset to clear write protect registers. */ #define SYSTEM_RESET_PRESERVE_FLAGS (1 << 1) +/* + * Leave AP off on next reboot, instead of powering it on to do EC software + * sync. + */ +#define SYSTEM_RESET_LEAVE_AP_OFF (1 << 2) void system_reset(int flags); -- cgit v1.2.1