diff options
-rw-r--r-- | board/cr50/tpm2/endorsement.c | 15 | ||||
-rw-r--r-- | chip/g/flash.c | 62 | ||||
-rw-r--r-- | chip/g/flash_info.h | 5 |
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); |