diff options
author | Sameer Nanda <snanda@chromium.org> | 2012-08-30 17:40:02 -0700 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-08-31 08:48:50 -0700 |
commit | f7c03d5dba1047bb948cd4b1f51a595ff943ca53 (patch) | |
tree | 0be07fb89c3e66acaec8663e9caef6d81d3d8764 /chip | |
parent | 1276132c33795f9188b429e73d1402589280b04e (diff) | |
download | chrome-ec-f7c03d5dba1047bb948cd4b1f51a595ff943ca53.tar.gz |
lm4: add warm reboot key combination
Added a warm reboot key combination that resets the CPU while preserving
RAM contents. This will be helpful in debugging CPU/OS hard hangs since
in conjunction with PSTORE_CONSOLE in the kernel, the kernel log
messages from the previous boot will be preserved.
BUG=chrome-os-partner:12780
TEST=reboot the system using alt-volume_up-r key combination. Upon
rebooting, check pstore contents with "cat /dev/pstore/console-ramoops"
and ensure that they are same as dmesg from the previous boot.
BRANCH=link
Change-Id: I0ec835a4646f442997c04dc3a086d4fac0cf01cf
Signed-off-by: Sameer Nanda <snanda@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/31992
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/lm4/keyboard_scan.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/chip/lm4/keyboard_scan.c b/chip/lm4/keyboard_scan.c index e661ef3068..3163724f41 100644 --- a/chip/lm4/keyboard_scan.c +++ b/chip/lm4/keyboard_scan.c @@ -17,6 +17,7 @@ #include "task.h" #include "timer.h" #include "util.h" +#include "x86_power.h" /* Console output macros */ #define CPUTS(outstr) cputs(CC_KEYSCAN, outstr) @@ -60,6 +61,16 @@ static const uint8_t actual_key_masks[4][KB_COLS] = { #define MASK_INDEX_REFRESH 2 #define MASK_VALUE_REFRESH 0x04 +/* Key masks and values for warm reboot combination */ +#define MASK_INDEX_KEYR 3 +#define MASK_VALUE_KEYR 0x80 +#define MASK_INDEX_VOL_UP 4 +#define MASK_VALUE_VOL_UP 0x01 +#define MASK_INDEX_RIGHT_ALT 10 +#define MASK_VALUE_RIGHT_ALT 0x01 +#define MASK_INDEX_LEFT_ALT 10 +#define MASK_VALUE_LEFT_ALT 0x40 + static void wait_for_interrupt(void) { CPRINTF("[%T KB wait]\n"); @@ -119,12 +130,24 @@ static void print_raw_state(const char *msg) CPUTS("]\n"); } +static int check_warm_reboot_keys(void) +{ + if (raw_state[MASK_INDEX_KEYR] == MASK_VALUE_KEYR && + raw_state[MASK_INDEX_VOL_UP] == MASK_VALUE_VOL_UP && + (raw_state[MASK_INDEX_RIGHT_ALT] == MASK_VALUE_RIGHT_ALT || + raw_state[MASK_INDEX_LEFT_ALT] == MASK_VALUE_LEFT_ALT)) + return 1; + + return 0; +} + /* Return 1 if any key is still pressed, 0 if no key is pressed. */ static int check_keys_changed(void) { int c, c2; uint8_t r; int change = 0; + int num_press = 0; uint8_t keys[KB_COLS]; for (c = 0; c < KB_COLS; c++) { @@ -188,8 +211,19 @@ static int check_keys_changed(void) } } - if (change) + /* Count number of key pressed */ + for (c = 0; c < KB_COLS; c++) { + if (raw_state[c]) + ++num_press; + } + + if (change) { + if (num_press == 3) { + if (check_warm_reboot_keys()) + x86_power_reset(0); + } print_raw_state("state"); + } out: /* Return non-zero if at least one key is pressed */ |