diff options
-rw-r--r-- | board/cr50/board.c | 33 | ||||
-rw-r--r-- | board/cr50/scratch_reg1.h | 9 | ||||
-rw-r--r-- | common/ccd_config.c | 27 | ||||
-rw-r--r-- | include/case_closed_debug.h | 31 |
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 */ |