summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott <scollyer@chromium.org>2016-03-02 13:10:51 -0800
committerchrome-bot <chrome-bot@chromium.org>2016-03-02 20:26:31 -0800
commit99ab107819fe2726e9dfe4fde084408e097acada (patch)
tree838df5cfabaa6e0bd8a034e4ecc4b79d10549128
parent3f85f1be7e3f9b4b8b6c4e4b98fcced962e181a1 (diff)
downloadchrome-ec-99ab107819fe2726e9dfe4fde084408e097acada.tar.gz
Cr50: Modify flash write to account for erase block boundaries
Flash writes must have starting offsets and byte lengths that are multiples of 4 bytes. This requirement is already covered. One additional requirement is that a batch write not cross a flash block boundary. Added a check in flash_physical_write() to check if this boundary would be crossed and if so to reduce the write size so that it ends at the block boundary. BUG=chrome-os-partner:44745 BRANCH=none TEST=manual Used the TPM NVMem section and executed flash writes/reads using a console command utility that I created to test NVMem accesses. Note that the console output only exists in the console command related functions. This test has the offset 12 bytes from the block boundary and 64 bytes long. The counting pattern shows that the write fills the last 12 bytes, then moves to the next block as expected. > nvmem wr 0xff4 0x40 3 nvmem wr: o = ff4, s = 64|0x40 start = 0xff4, end = 0x1034 block 0: block_offset = 0x40800 Call Erase(0x80800, 0x800) block 1: block_offset = 0x41000 Call Erase(0x81000, 0x800) Nvmem: writing 64 bytes, start = 0x80ff4 > nvmem rd 0xfe0 0x80 nvmem rd: o = fe0, s = 128|0x80 0x80fe0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x80ff0: ff ff ff ff 00 01 02 03 04 05 06 07 08 09 0a 0b 0x81000: 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 0x81010: 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 0x81020: 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 0x81030: 3c 3d 3e 3f ff ff ff ff ff ff ff ff ff ff ff ff Also tested the case where a write should end exactly at the block boundary. > nvmem wr 0xff0 16 3 nvmem wr: o = ff0, s = 16|0x10 start = 0xff0, end = 0x1000 block 0: block_offset = 0x40800 Call Erase(0x80800, 0x800) Nvmem: writing 16 bytes, start = 0x80ff0 > > nvmem rd 0xfe0 0x80 nvmem rd: o = fe0, s = 128|0x80 0x80fe0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x80ff0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 0x81000: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 0x81010: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 Change-Id: Icbe66d3f79d84ed29ecc6207537ea0bf42781f3c Signed-off-by: Scott <scollyer@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/330175 Commit-Ready: Scott Collyer <scollyer@chromium.org> Tested-by: Scott Collyer <scollyer@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
-rw-r--r--chip/g/flash.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/chip/g/flash.c b/chip/g/flash.c
index 52d7499294..f8da752cf3 100644
--- a/chip/g/flash.c
+++ b/chip/g/flash.c
@@ -287,6 +287,12 @@ int flash_physical_write(int byte_offset, int num_bytes, const char *data)
while (num_bytes) {
num = MIN(num_bytes, CONFIG_FLASH_WRITE_IDEAL_SIZE);
+ /*
+ * Make sure that the write operation will not go
+ * past a CONFIG_FLASH_ERASE_SIZE boundary.
+ */
+ num = MIN(num, CONFIG_FLASH_ERASE_SIZE -
+ byte_offset % CONFIG_FLASH_ERASE_SIZE);
ret = write_batch(byte_offset,
num / 4, /* word count */
(const uint8_t *)data);