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