summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2019-07-31 11:06:13 -0700
committerchrome-bot <chrome-bot@chromium.org>2019-08-10 16:55:19 -0700
commitfb0eb4d1b932ba469f7385e42cf43f5a11f09c85 (patch)
tree73a4fb7328b0871cfd7cc81f732cd34e5c9009e3
parent023fb69d7ff6cb35bbe05708205f357133d9365b (diff)
downloadchrome-ec-fb0eb4d1b932ba469f7385e42cf43f5a11f09c85.tar.gz
cr50: use dedicated region for info1 accesses
The INFO1 flash space is used for various purposes (endorsement key seed, Board ID and flags, serial number, etc.). Accessing these spaces in INFO1 is accompanied by managing the flash region registers, each time opening a window of the appropriate size, with appropriate permissions, etc, In fact none of these spaces contain a secret, to simplify things and preventing situations when concurrent accesses change the flash range window settings lets dedicate previously unused Region 7 register file to providing always open read access to INFO1. Write access will be enabled/disabled as required. In prod images write accesses will always happen from the vendor command context. In DBG images CLI commands will also have write access to INFO1. INFO1 window is accessed by other H1 based devices as well, this is why it is necessary to enable the window in the common chip code. BRANCH=cr50, cr50-mp BUG=b:138256149 TEST=the firmware_Cr50SetBoardId test now passes on Mistral. Cq-Depend: chrome-internal:1577866, chrome-internal:1581327 Change-Id: Id27348f3b04191f1b3b60fd838d06009f756baa2 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1730147 Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org> Reviewed-by: Mary Ruthven <mruthven@chromium.org>
-rw-r--r--board/cr50/tpm2/endorsement.c12
-rw-r--r--chip/g/board_id.c17
-rw-r--r--chip/g/flash.c66
-rw-r--r--chip/g/flash_info.h3
-rw-r--r--chip/g/sn_bits.c15
-rw-r--r--chip/g/system.c18
6 files changed, 16 insertions, 115 deletions
diff --git a/board/cr50/tpm2/endorsement.c b/board/cr50/tpm2/endorsement.c
index a9751d43fb..4167fe0745 100644
--- a/board/cr50/tpm2/endorsement.c
+++ b/board/cr50/tpm2/endorsement.c
@@ -443,11 +443,6 @@ static int store_cert(enum cros_perso_component_type component_type,
return 0;
}
-static void flash_info_read_disable(void)
-{
- GREG32(GLOBALSEC, FLASH_REGION7_CTRL) = 0;
-}
-
static void flash_cert_region_enable(void)
{
/* Enable R access to CERT block. */
@@ -472,10 +467,6 @@ static int get_decrypted_eps(uint8_t eps[PRIMARY_SEED_SIZE])
if (!DCRYPTO_ladder_compute_frk2(K_CROS_FW_MAJOR_VERSION, frk2))
return 0;
- /* Setup flash region mapping. */
- flash_info_read_enable(FLASH_INFO_MANUFACTURE_STATE_OFFSET,
- FLASH_INFO_MANUFACTURE_STATE_SIZE);
-
for (i = 0; i < INFO1_EPS_SIZE; i += sizeof(uint32_t)) {
uint32_t word;
@@ -487,9 +478,6 @@ static int get_decrypted_eps(uint8_t eps[PRIMARY_SEED_SIZE])
memcpy(eps + i, &word, sizeof(word));
}
- /* Remove flash region mapping. */
- flash_info_read_disable();
-
/* One-time-pad decrypt EPS. */
for (i = 0; i < PRIMARY_SEED_SIZE; i++)
eps[i] ^= frk2[i];
diff --git a/chip/g/board_id.c b/chip/g/board_id.c
index 1f46bd8226..c863a81fba 100644
--- a/chip/g/board_id.c
+++ b/chip/g/board_id.c
@@ -74,14 +74,6 @@ int read_board_id(struct board_id *id)
id_p = (uint32_t *)id;
- /* Make sure INFO1 board ID space is readable */
- if (flash_info_read_enable(INFO_BOARD_ID_OFFSET,
- INFO_BOARD_ID_PROTECT_SIZE) !=
- EC_SUCCESS) {
- CPRINTS("%s: failed to enable read access to info", __func__);
- return EC_ERROR_ACCESS_DENIED;
- }
-
for (i = 0; i < sizeof(*id); i += sizeof(uint32_t)) {
int rv;
@@ -156,13 +148,7 @@ static int write_board_id(const struct board_id *id, int clear_flags)
return EC_ERROR_ACCESS_DENIED;
}
- /* Enable write access */
- if (flash_info_write_enable(INFO_BOARD_ID_OFFSET,
- INFO_BOARD_ID_PROTECT_SIZE) !=
- EC_SUCCESS) {
- CPRINTS("%s: failed to enable write access", __func__);
- return EC_ERROR_ACCESS_DENIED;
- }
+ flash_info_write_enable();
/* Write Board ID */
rv = flash_info_physical_write(INFO_BOARD_ID_OFFSET +
@@ -171,7 +157,6 @@ static int write_board_id(const struct board_id *id, int clear_flags)
if (rv != EC_SUCCESS)
CPRINTS("%s: write failed", __func__);
- /* Disable write access */
flash_info_write_disable();
return rv;
diff --git a/chip/g/flash.c b/chip/g/flash.c
index 07573f7fd9..443ab23efe 100644
--- a/chip/g/flash.c
+++ b/chip/g/flash.c
@@ -103,6 +103,13 @@ int flash_pre_init(void)
GWRITE_FIELD(GLOBALSEC, FLASH_REGION5_CTRL, RD_EN, 1);
flash_log_register_flash_control_callback(flash_log_space_control);
#endif
+
+ /* Create a flash region window for INFO1 access. */
+ GREG32(GLOBALSEC, FLASH_REGION7_BASE_ADDR) = FLASH_INFO_MEMORY_BASE;
+ GREG32(GLOBALSEC, FLASH_REGION7_SIZE) = FLASH_INFO_SIZE - 1;
+ GWRITE_FIELD(GLOBALSEC, FLASH_REGION7_CTRL, EN, 1);
+ GWRITE_FIELD(GLOBALSEC, FLASH_REGION7_CTRL, RD_EN, 1);
+
return EC_SUCCESS;
}
@@ -388,62 +395,14 @@ int flash_physical_info_read_word(int byte_offset, uint32_t *dst)
return ret;
}
-/*
- * Verify that the range's size is power of 2, the range offset is aligned by
- * size, and the range does not cross the INFO space boundary.
- */
-static int valid_info_range(uint32_t offset, size_t size)
+void flash_info_write_enable(void)
{
- if (!size || (size & (size - 1)))
- return 0;
-
- if (offset & (size - 1))
- return 0;
-
- if ((offset + size) > FLASH_INFO_SIZE)
- return 0;
-
- return 1;
-
-}
-
-/* Write access is a superset of read access. */
-static int flash_info_configure_access(uint32_t offset,
- size_t size, int write_mode)
-{
- int mask;
-
- if (!valid_info_range(offset, size))
- return EC_ERROR_INVAL;
-
- mask = GREG32(GLOBALSEC, FLASH_REGION6_CTRL);
- mask |= GC_GLOBALSEC_FLASH_REGION6_CTRL_EN_MASK |
- GC_GLOBALSEC_FLASH_REGION6_CTRL_RD_EN_MASK;
- if (write_mode)
- mask |= GC_GLOBALSEC_FLASH_REGION6_CTRL_WR_EN_MASK;
-
- GREG32(GLOBALSEC, FLASH_REGION6_BASE_ADDR) =
- FLASH_INFO_MEMORY_BASE + offset;
-
- GREG32(GLOBALSEC, FLASH_REGION6_SIZE) = size - 1;
- GREG32(GLOBALSEC, FLASH_REGION6_CTRL) = mask;
-
- return EC_SUCCESS;
-}
-
-int flash_info_read_enable(uint32_t offset, size_t size)
-{
- return flash_info_configure_access(offset, size, 0);
-}
-
-int flash_info_write_enable(uint32_t offset, size_t size)
-{
- return flash_info_configure_access(offset, size, 1);
+ GWRITE_FIELD(GLOBALSEC, FLASH_REGION7_CTRL, WR_EN, 1);
}
void flash_info_write_disable(void)
{
- GWRITE_FIELD(GLOBALSEC, FLASH_REGION6_CTRL, WR_EN, 0);
+ GWRITE_FIELD(GLOBALSEC, FLASH_REGION7_CTRL, WR_EN, 0);
}
int flash_info_physical_write(int byte_offset, int num_bytes, const char *data)
@@ -516,9 +475,6 @@ static int command_erase_flash_info(int argc, char **argv)
return rv;
}
- flash_info_read_enable(0, 2048);
- flash_info_write_enable(0, 2048);
-
/* Read the entire info1. */
p = (uint32_t *)info1;
for (i = 0; i < (sizeof(*info1) / sizeof(*p)); i++) {
@@ -577,6 +533,8 @@ static int command_erase_flash_info(int argc, char **argv)
mutex_lock(&flash_mtx);
+ flash_info_write_enable();
+
rv = do_flash_op(OP_ERASE_BLOCK, 1, 0, 512);
mutex_unlock(&flash_mtx);
diff --git a/chip/g/flash_info.h b/chip/g/flash_info.h
index e07fac1ed7..464eb70dbd 100644
--- a/chip/g/flash_info.h
+++ b/chip/g/flash_info.h
@@ -30,9 +30,8 @@
#define INFO_BOARD_SPACE_OFFSET (INFO_RW_MAP_OFFSET + INFO_RW_MAP_SIZE)
-int flash_info_read_enable(uint32_t offset, size_t size);
/* This in fact enables both read and write. */
-int flash_info_write_enable(uint32_t offset, size_t size);
+void flash_info_write_enable(void);
void flash_info_write_disable(void);
int flash_info_physical_write(int byte_offset, int num_bytes, const char *data);
int flash_physical_info_read_word(int byte_offset, uint32_t *dst);
diff --git a/chip/g/sn_bits.c b/chip/g/sn_bits.c
index 0057d26299..23fb6ada7f 100644
--- a/chip/g/sn_bits.c
+++ b/chip/g/sn_bits.c
@@ -26,14 +26,6 @@ int read_sn_data(struct sn_data *sn)
id_p = (uint32_t *)sn;
- /* Make sure INFO1 sn bits space is readable */
- if (flash_info_read_enable(INFO_SN_DATA_OFFSET,
- INFO_SN_DATA_PROTECT_SIZE) !=
- EC_SUCCESS) {
- CPRINTS("%s: failed to enable read access to info", __func__);
- return EC_ERROR_ACCESS_DENIED;
- }
-
for (i = 0; i < sizeof(*sn); i += sizeof(uint32_t)) {
int rv;
@@ -54,12 +46,7 @@ static int write_sn_data(struct sn_data *sn_data, int header_only)
int rv = EC_SUCCESS;
/* Enable write access */
- if (flash_info_write_enable(INFO_SN_DATA_OFFSET,
- INFO_SN_DATA_PROTECT_SIZE) !=
- EC_SUCCESS) {
- CPRINTS("%s: failed to enable write access", __func__);
- return EC_ERROR_ACCESS_DENIED;
- }
+ flash_info_write_enable();
/* Write sn bits */
rv = flash_info_physical_write(INFO_SN_DATA_OFFSET,
diff --git a/chip/g/system.c b/chip/g/system.c
index f28e0a5c5d..d15ec42ebe 100644
--- a/chip/g/system.c
+++ b/chip/g/system.c
@@ -614,15 +614,6 @@ static void update_rollback_mask(const struct SignedHeader *header_a,
uint32_t header_mask = 0;
/*
- * Make sure INFO1 RW map space is readable.
- */
- if (flash_info_read_enable(INFO_RW_MAP_OFFSET, INFO_RW_MAP_SIZE) !=
- EC_SUCCESS) {
- CPRINTS("%s: failed to enable read access to info", __func__);
- return;
- }
-
- /*
* The infomap field in the image header has a matching space in the
* flash INFO1 section.
*
@@ -680,13 +671,7 @@ static void update_rollback_mask(const struct SignedHeader *header_a,
continue; /* This word has been zeroed already. */
if (!write_enabled) {
- if (flash_info_write_enable(
- INFO_RW_MAP_OFFSET,
- INFO_RW_MAP_SIZE) != EC_SUCCESS) {
- CPRINTS("%s: failed to enable write access to"
- " info", __func__);
- return;
- }
+ flash_info_write_enable();
write_enabled = 1;
}
@@ -739,7 +724,6 @@ void system_get_rollback_bits(char *value, size_t value_size)
get_program_memory_addr(SYSTEM_IMAGE_RW_B)},
};
- flash_info_read_enable(INFO_RW_MAP_OFFSET, INFO_RW_MAP_SIZE);
for (i = 0; i < INFO_MAX; i++) {
uint32_t w;