summaryrefslogtreecommitdiff
path: root/chip/g/flash.c
diff options
context:
space:
mode:
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)