summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);