diff options
Diffstat (limited to 'chip/g/flash.c')
-rw-r--r-- | chip/g/flash.c | 62 |
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) |