summaryrefslogtreecommitdiff
path: root/chip/g/flash.c
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 /chip/g/flash.c
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>
Diffstat (limited to 'chip/g/flash.c')
-rw-r--r--chip/g/flash.c66
1 files changed, 12 insertions, 54 deletions
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);