diff --git a/board/cr50/wp.c b/board/cr50/wp.c index ab8d363a35..246b56179b 100644 --- a/board/cr50/wp.c +++ b/board/cr50/wp.c @@ -107,6 +107,35 @@ static void force_write_protect(int force, int wp_en) set_wp_state(wp_en); } +static enum vendor_cmd_rc vc_set_wp(enum vendor_cmd_cc code, + void *buf, + size_t input_size, + size_t *response_size) +{ + uint8_t response = 0; + + *response_size = 0; + /* There shouldn't be any args */ + if (input_size) + return VENDOR_RC_BOGUS_ARGS; + + /* Get current wp settings */ + if (GREG32(PMU, LONG_LIFE_SCRATCH1) & BOARD_FORCING_WP) + response |= WPV_FORCE; + if (get_wp_state()) + response |= WPV_ENABLE; + /* Get atboot wp settings */ + if (ccd_get_flag(CCD_FLAG_OVERRIDE_WP_AT_BOOT)) { + response |= WPV_ATBOOT_SET; + if (ccd_get_flag(CCD_FLAG_OVERRIDE_WP_STATE_ENABLED)) + response |= WPV_ATBOOT_ENABLE; + } + ((uint8_t *)buf)[0] = response; + *response_size = sizeof(response); + return VENDOR_RC_SUCCESS; +} +DECLARE_VENDOR_COMMAND(VENDOR_CC_WP, vc_set_wp); + static int command_wp(int argc, char **argv) { int val = 1; diff --git a/include/tpm_vendor_cmds.h b/include/tpm_vendor_cmds.h index b6b32c3ef7..2ecef80e57 100644 --- a/include/tpm_vendor_cmds.h +++ b/include/tpm_vendor_cmds.h @@ -63,6 +63,12 @@ enum vendor_cmd_cc { * the 'ccd reset' console command is run. */ VENDOR_CC_RESET_FACTORY = 38, + /* + * Get the write protect setting. This will return a single byte with + * bits communicating the write protect setting as described by the + * WPV subcommands. + */ + VENDOR_CC_WP = 39, LAST_VENDOR_COMMAND = 65535, }; @@ -154,4 +160,13 @@ struct vendor_cc_spi_hash_request { /* Maximum size of a response = SHA-256 hash or 1-32 bytes of data */ #define SPI_HASH_MAX_RESPONSE_BYTES 32 +/* + * Subcommand code, used to set write protect. + */ +#define WPV_UPDATE (1 << 0) +#define WPV_ENABLE (1 << 1) +#define WPV_FORCE (1 << 2) +#define WPV_ATBOOT_SET (1 << 3) +#define WPV_ATBOOT_ENABLE (1 << 4) + #endif /* __INCLUDE_TPM_VENDOR_CMDS_H */