summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/cr50/board.c33
-rw-r--r--board/cr50/scratch_reg1.h9
-rw-r--r--common/ccd_config.c27
-rw-r--r--include/case_closed_debug.h31
4 files changed, 82 insertions, 18 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c
index f3e3f59dcf..76b14b1f30 100644
--- a/board/cr50/board.c
+++ b/board/cr50/board.c
@@ -618,6 +618,12 @@ static void check_board_id_mismatch(void)
/* Initialize board. */
static void board_init(void)
{
+#ifdef CR50_DEV
+ static enum ccd_state ccd_init_state = CCD_STATE_OPENED;
+#else
+ static enum ccd_state ccd_init_state = CCD_STATE_LOCKED;
+#endif
+
/*
* Deep sleep resets should be considered valid and should not impact
* the rolling reboot count.
@@ -634,8 +640,19 @@ static void board_init(void)
nvmem_init();
/* Initialize the persistent storage. */
initvars();
+
+ /*
+ * If this was a low power wake and not a rollback, restore the ccd
+ * state from the long-life register.
+ */
+ if ((system_get_reset_flags() & RESET_FLAG_HIBERNATE) &&
+ !system_rollback_detected()) {
+ ccd_init_state = (GREG32(PMU, LONG_LIFE_SCRATCH1) &
+ BOARD_CCD_STATE) >> BOARD_CCD_SHIFT;
+ }
+
/* Load case-closed debugging config */
- ccd_config_init();
+ ccd_config_init(ccd_init_state);
system_update_rollback_mask_with_both_imgs();
@@ -661,6 +678,20 @@ static void board_init(void)
}
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
+/**
+ * Hook for CCD config loaded/changed.
+ */
+static void board_ccd_config_changed(void)
+{
+ /* Store the current CCD state so we can restore it after deep sleep */
+ GWRITE_FIELD(PMU, LONG_LIFE_SCRATCH_WR_EN, REG1, 1);
+ GREG32(PMU, LONG_LIFE_SCRATCH1) &= ~BOARD_CCD_STATE;
+ GREG32(PMU, LONG_LIFE_SCRATCH1) |= (ccd_get_state() << BOARD_CCD_SHIFT)
+ & BOARD_CCD_STATE;
+ GWRITE_FIELD(PMU, LONG_LIFE_SCRATCH_WR_EN, REG1, 0);
+}
+DECLARE_HOOK(HOOK_CCD_CHANGE, board_ccd_config_changed, HOOK_PRIO_DEFAULT);
+
#if defined(CONFIG_USB)
const void * const usb_strings[] = {
[USB_STR_DESC] = usb_string_desc,
diff --git a/board/cr50/scratch_reg1.h b/board/cr50/scratch_reg1.h
index 546cd43d62..23b03db546 100644
--- a/board/cr50/scratch_reg1.h
+++ b/board/cr50/scratch_reg1.h
@@ -38,6 +38,15 @@
#define BOARD_NO_RO_UART (1 << 10)
/*
+ * Bits to store current case-closed debug state across deep sleep.
+ *
+ * DO NOT examine these bits to determine the current CCD state. Call methods
+ * from case_closed_debug.h instead.
+ */
+#define BOARD_CCD_SHIFT 11
+#define BOARD_CCD_STATE (3 << BOARD_CCD_SHIFT)
+
+/*
* Macro to capture all properties related to board strapping pins. This must be
* updated if additional strap related properties are added.
*/
diff --git a/common/ccd_config.c b/common/ccd_config.c
index 2c465c6d68..021ae121f3 100644
--- a/common/ccd_config.c
+++ b/common/ccd_config.c
@@ -14,6 +14,7 @@
#include "nvmem_vars.h"
#include "physical_presence.h"
#include "system.h"
+#include "system_chip.h"
#include "task.h"
#include "timer.h"
#include "trng.h"
@@ -21,15 +22,6 @@
#define CPRINTS(format, args...) cprints(CC_CCD, format, ## args)
#define CPRINTF(format, args...) cprintf(CC_CCD, format, ## args)
-enum ccd_state {
- CCD_STATE_LOCKED = 0,
- CCD_STATE_UNLOCKED,
- CCD_STATE_OPENED,
-
- /* Number of CCD states */
- CCD_STATE_COUNT
-};
-
/* Restriction state for ccdunlock when no password is set */
enum ccd_unlock_restrict {
/* Unrestricted */
@@ -151,12 +143,7 @@ static const char *ccd_state_names[CCD_STATE_COUNT] = {
static const char *ccd_cap_state_names[CCD_CAP_STATE_COUNT] = {
"Default", "Always", "UnlessLocked", "IfOpened"};
-#ifdef CONFIG_CASE_CLOSED_DEBUG_V1_UNSAFE
-static enum ccd_state ccd_state = CCD_STATE_OPENED;
-#else
static enum ccd_state ccd_state = CCD_STATE_LOCKED;
-#endif
-
static struct ccd_config config;
static uint8_t ccd_config_loaded;
static struct mutex ccd_config_mutex;
@@ -630,8 +617,13 @@ static void ccd_testlab_toggle(void)
/******************************************************************************/
/* External interface */
-void ccd_config_init(void)
+void ccd_config_init(enum ccd_state state)
{
+ /* Set initial state, after making sure it's a valid one */
+ if (state != CCD_STATE_UNLOCKED && state != CCD_STATE_OPENED)
+ state = CCD_STATE_LOCKED;
+ ccd_state = state;
+
ccd_load_config();
}
@@ -683,6 +675,11 @@ int ccd_is_cap_enabled(enum ccd_capability cap)
}
}
+enum ccd_state ccd_get_state(void)
+{
+ return ccd_state;
+}
+
/******************************************************************************/
/* Console commands */
diff --git a/include/case_closed_debug.h b/include/case_closed_debug.h
index 0b2ec8b468..77ad0f496f 100644
--- a/include/case_closed_debug.h
+++ b/include/case_closed_debug.h
@@ -46,6 +46,16 @@ enum ccd_mode ccd_get_mode(void);
/******************************************************************************/
/* New CCD "V1" configuration. Eventually this will supersede the above code */
+/* Case-closed debugging state */
+enum ccd_state {
+ CCD_STATE_LOCKED = 0,
+ CCD_STATE_UNLOCKED,
+ CCD_STATE_OPENED,
+
+ /* Number of CCD states */
+ CCD_STATE_COUNT
+};
+
/* Flags */
enum ccd_flag {
/* Flags that can only be set internally; fill from bottom up */
@@ -128,8 +138,13 @@ enum ccd_capability {
* Initialize CCD configuration at boot.
*
* This must be called before any command which gets/sets the configuration.
+ *
+ * @param state Initial case-closed debugging state. This should be
+ * CCD_STATE_LOCKED unless this is a debug build, or if
+ * a previous value is being restored after a low-power
+ * resume.
*/
-void ccd_config_init(void);
+void ccd_config_init(enum ccd_state state);
/**
* Get a single CCD flag.
@@ -149,11 +164,23 @@ int ccd_get_flag(enum ccd_flag flag);
int ccd_set_flag(enum ccd_flag flag, int value);
/**
- * Check if a CCD capability is enabled in the current CCD mode
+ * Check if a CCD capability is enabled in the current CCD mode.
*
* @param cap Capability to check
* @return 1 if capability is enabled, 0 if disabled
*/
int ccd_is_cap_enabled(enum ccd_capability cap);
+/**
+ * Get the current CCD state.
+ *
+ * This is intended for use by the board if it needs to back up the CCD state
+ * across low-power states and then restore it when calling ccd_config_init().
+ * Do NOT use this to gate debug capabilities; use ccd_is_cap_enabled() or
+ * ccd_get_flag() instead.
+ *
+ * @return The current CCD state.
+ */
+enum ccd_state ccd_get_state(void);
+
#endif /* __CROS_EC_CASE_CLOSED_DEBUG_H */