diff options
author | Scott <scollyer@chromium.org> | 2016-03-02 13:10:51 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-03-02 20:26:31 -0800 |
commit | 99ab107819fe2726e9dfe4fde084408e097acada (patch) | |
tree | 838df5cfabaa6e0bd8a034e4ecc4b79d10549128 | |
parent | 3f85f1be7e3f9b4b8b6c4e4b98fcced962e181a1 (diff) | |
download | chrome-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.c | 6 |
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); |