summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@google.com>2017-02-28 17:52:23 -0800
committerchrome-bot <chrome-bot@chromium.org>2017-03-02 16:50:05 -0800
commitb1afdd76bc3f7b35a2cdca817684ebe224a4c9a9 (patch)
tree454b243ceeb6c687de114463cbcc4bd4f622c81f
parent899fba96494e022f8e083611c328e7b57cf18079 (diff)
downloadchrome-ec-b1afdd76bc3f7b35a2cdca817684ebe224a4c9a9.tar.gz
g: enhance flash INFO api
Flash INFO access API presently is hardcoded to access the endorsement space. To enable INFO map based rollback protection one needs to be able to access different areas of the INFO. The FLASH REGION3 register used by the API is in fact used for NVMEM flash accesses too, so it is better to leave it alone and use REGION6 for the purpose of accessing of the INFO space. The API now requires the user to specify flash offset and region size, the size must be power of 2, the offset must be aligned at size, and the region must not spill beyond the INFO space address range. BRANCH=cr50 BUG=b:35774863 TEST=with the rest of the patches applied it is possible to erase the base word in the info map segment; reading of the endorsement space at startup still works fine. Change-Id: I008165ee9e11a7b49985d2b30683509cf6699431 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/447965 Reviewed-by: Nagendra Modadugu <ngm@google.com> Reviewed-by: Mary Ruthven <mruthven@chromium.org>
-rw-r--r--board/cr50/tpm2/endorsement.c15
-rw-r--r--chip/g/flash.c62
-rw-r--r--chip/g/flash_info.h5
3 files changed, 57 insertions, 25 deletions
diff --git a/board/cr50/tpm2/endorsement.c b/board/cr50/tpm2/endorsement.c
index 617400edc0..468a74f485 100644
--- a/board/cr50/tpm2/endorsement.c
+++ b/board/cr50/tpm2/endorsement.c
@@ -407,18 +407,6 @@ static int store_cert(enum cros_perso_component_type component_type,
return 0;
}
-static void flash_info_read_enable(void)
-{
- /* Enable R access to INFO. */
- GREG32(GLOBALSEC, FLASH_REGION7_BASE_ADDR) = FLASH_INFO_MEMORY_BASE +
- FLASH_INFO_MANUFACTURE_STATE_OFFSET;
- GREG32(GLOBALSEC, FLASH_REGION7_SIZE) =
- FLASH_INFO_MANUFACTURE_STATE_SIZE - 1;
- GREG32(GLOBALSEC, FLASH_REGION7_CTRL) =
- GC_GLOBALSEC_FLASH_REGION7_CTRL_EN_MASK |
- GC_GLOBALSEC_FLASH_REGION7_CTRL_RD_EN_MASK;
-}
-
static void flash_info_read_disable(void)
{
GREG32(GLOBALSEC, FLASH_REGION7_CTRL) = 0;
@@ -449,7 +437,8 @@ static int get_decrypted_eps(uint8_t eps[PRIMARY_SEED_SIZE])
return 0;
/* Setup flash region mapping. */
- flash_info_read_enable();
+ 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;
diff --git a/chip/g/flash.c b/chip/g/flash.c
index 3b02a5d014..c0b1f72979 100644
--- a/chip/g/flash.c
+++ b/chip/g/flash.c
@@ -352,22 +352,62 @@ int flash_physical_info_read_word(int byte_offset, uint32_t *dst)
return EC_SUCCESS;
}
-void flash_info_write_enable(void)
+/*
+ * 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)
+{
+ if (!size || (size & (size - 1)))
+ return 0;
+
+ if (offset & (size - 1))
+ return 0;
+
+ if ((offset + size) > FLASH_INFO_SIZE)
+ return 0;
+
+ return 1;
+
+}
+
+static int flash_info_configure_access(uint32_t offset,
+ size_t size, int read_mode)
+{
+ int mask;
+
+ if (!valid_info_range(offset, size))
+ return EC_ERROR_INVAL;
+
+ if (read_mode)
+ mask = GC_GLOBALSEC_FLASH_REGION6_CTRL_EN_MASK |
+ GC_GLOBALSEC_FLASH_REGION6_CTRL_RD_EN_MASK;
+ else
+ mask = GC_GLOBALSEC_FLASH_REGION6_CTRL_EN_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, 1);
+}
+
+int flash_info_write_enable(uint32_t offset, size_t size)
{
- /* Enable R/W access to INFO. */
- GREG32(GLOBALSEC, FLASH_REGION3_BASE_ADDR) = FLASH_INFO_MEMORY_BASE +
- FLASH_INFO_MANUFACTURE_STATE_OFFSET;
- GREG32(GLOBALSEC, FLASH_REGION3_SIZE) =
- FLASH_INFO_MANUFACTURE_STATE_SIZE - 1;
- GREG32(GLOBALSEC, FLASH_REGION3_CTRL) =
- GC_GLOBALSEC_FLASH_REGION3_CTRL_EN_MASK |
- GC_GLOBALSEC_FLASH_REGION3_CTRL_WR_EN_MASK |
- GC_GLOBALSEC_FLASH_REGION3_CTRL_RD_EN_MASK;
+ return flash_info_configure_access(offset, size, 0);
}
void flash_info_write_disable(void)
{
- GREG32(GLOBALSEC, FLASH_REGION3_CTRL) = 0;
+ GWRITE_FIELD(GLOBALSEC, FLASH_REGION6_CTRL, WR_EN, 0);
}
int flash_info_physical_write(int byte_offset, int num_bytes, const char *data)
diff --git a/chip/g/flash_info.h b/chip/g/flash_info.h
index fae622c24b..308446df4d 100644
--- a/chip/g/flash_info.h
+++ b/chip/g/flash_info.h
@@ -6,7 +6,10 @@
#ifndef __EC_CHIP_G_FLASH_INFO_H
#define __EC_CHIP_G_FLASH_INFO_H
-void flash_info_write_enable(void);
+#include <stddef.h>
+
+int flash_info_read_enable(uint32_t offset, size_t size);
+int flash_info_write_enable(uint32_t offset, size_t size);
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);