summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorSameer Nanda <snanda@chromium.org>2012-08-30 17:40:02 -0700
committerGerrit <chrome-bot@google.com>2012-08-31 08:48:50 -0700
commitf7c03d5dba1047bb948cd4b1f51a595ff943ca53 (patch)
tree0be07fb89c3e66acaec8663e9caef6d81d3d8764 /chip
parent1276132c33795f9188b429e73d1402589280b04e (diff)
downloadchrome-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.c36
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 */