summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/cr50/build.mk1
-rw-r--r--board/cr50/recovery_button.c73
-rw-r--r--include/tpm_vendor_cmds.h1
3 files changed, 75 insertions, 0 deletions
diff --git a/board/cr50/build.mk b/board/cr50/build.mk
index 4babeef552..dd99f31380 100644
--- a/board/cr50/build.mk
+++ b/board/cr50/build.mk
@@ -33,6 +33,7 @@ board-y = board.o ec_state.o
board-${CONFIG_RDD} += rdd.o
board-${CONFIG_USB_SPI} += usb_spi.o
board-${CONFIG_USB_I2C} += usb_i2c.o
+board-y += recovery_button.o
board-y += tpm2/NVMem.o
board-y += tpm2/aes.o
board-y += tpm2/ecc.o
diff --git a/board/cr50/recovery_button.c b/board/cr50/recovery_button.c
new file mode 100644
index 0000000000..af4d4d7c87
--- /dev/null
+++ b/board/cr50/recovery_button.c
@@ -0,0 +1,73 @@
+/* Copyright 2017 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.
+ */
+
+/* Recovery button override module. */
+
+#include "common.h"
+#include "console.h"
+#include "extension.h"
+#include "registers.h"
+#include "util.h"
+
+/*
+ * The recovery button, on some systems only, is wired to KEY0 in rbox. For
+ * testing, we need to be able override the value. We'll have a vendor command
+ * such that the AP can query the state of the recovery button. However, the
+ * reported state can only be overridden with a console command given sufficient
+ * privileges.
+ */
+static uint8_t rec_btn_force_pressed;
+
+static uint8_t is_rec_btn_pressed(void)
+{
+ if (rec_btn_force_pressed)
+ return 1;
+
+ /*
+ * If not force pressed, check the actual state of button. Note,
+ * the value is inverted because the button is active low.
+ */
+ return !GREAD_FIELD(RBOX, CHECK_INPUT, KEY0_IN);
+}
+
+static int command_recbtnforce(int argc, char **argv)
+{
+ int val;
+
+ if (argc > 2)
+ return EC_ERROR_PARAM_COUNT;
+
+ if (argc == 2) {
+ /* Make sure we're allowed to override the recovery button. */
+ if (console_is_restricted())
+ return EC_ERROR_ACCESS_DENIED;
+
+ if (!parse_bool(argv[1], &val))
+ return EC_ERROR_PARAM1;
+
+ rec_btn_force_pressed = val;
+ }
+
+ ccprintf("RecBtn: %s pressed\n",
+ rec_btn_force_pressed ? "forced" :
+ is_rec_btn_pressed() ? "" : "not");
+
+ return EC_SUCCESS;
+}
+DECLARE_SAFE_CONSOLE_COMMAND(recbtnforce, command_recbtnforce,
+ "[enable | disable]",
+ "Force enable the reported recbtn state.");
+
+static enum vendor_cmd_rc vc_get_rec_btn(enum vendor_cmd_cc code,
+ void *buf,
+ size_t input_size,
+ size_t *response_size)
+{
+ *(uint8_t *)buf = is_rec_btn_pressed();
+ *response_size = 1;
+
+ return VENDOR_RC_SUCCESS;
+}
+DECLARE_VENDOR_COMMAND(VENDOR_CC_GET_REC_BTN, vc_get_rec_btn);
diff --git a/include/tpm_vendor_cmds.h b/include/tpm_vendor_cmds.h
index f76685373c..59331313d9 100644
--- a/include/tpm_vendor_cmds.h
+++ b/include/tpm_vendor_cmds.h
@@ -42,6 +42,7 @@ enum vendor_cmd_cc {
VENDOR_CC_SET_BOARD_ID = 26,
VENDOR_CC_U2F_APDU = 27,
VENDOR_CC_POP_LOG_ENTRY = 28,
+ VENDOR_CC_GET_REC_BTN = 29,
LAST_VENDOR_COMMAND = 65535,
};