intel/apollolake: Ensure SPI operations do not cross 256-byte boundary
BIOS needs to ensure that SPI write does not cross 256-byte boundary. Else, if the write is across 256-byte boundary, then it corrupts the block by wrapping write to start of current block. Thus, ensure nuclear_spi_{read,write} operate within a single 256-byte block only at a time. BUG=chrome-os-partner:59813 BRANCH=None TEST=Verified that elog writes do not corrupt the event log when write is across 256-byte blocks. Change-Id: I854ca2979d65b9f1232f93182cb84d4dee4f4139 Signed-off-by: Furquan Shaikh <furquan@chromium.org> Reviewed-on: https://review.coreboot.org/17419 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
parent
a2f1d18921
commit
0530b29921
1 changed files with 17 additions and 2 deletions
|
@ -259,6 +259,21 @@ static int nuclear_spi_erase(struct spi_flash *flash, uint32_t offset, size_t le
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure read/write xfer len is not greater than SPIBAR_FDATA_FIFO_SIZE and
|
||||
* that the operation does not cross 256-byte boundary.
|
||||
*/
|
||||
static size_t get_xfer_len(uint32_t addr, size_t len)
|
||||
{
|
||||
size_t xfer_len = min(len, SPIBAR_FDATA_FIFO_SIZE);
|
||||
size_t bytes_left = ALIGN_UP(addr, 256) - addr;
|
||||
|
||||
if (bytes_left)
|
||||
xfer_len = min(xfer_len, bytes_left);
|
||||
|
||||
return xfer_len;
|
||||
}
|
||||
|
||||
static int nuclear_spi_read(struct spi_flash *flash, uint32_t addr, size_t len, void *buf)
|
||||
{
|
||||
int ret;
|
||||
|
@ -268,7 +283,7 @@ static int nuclear_spi_read(struct spi_flash *flash, uint32_t addr, size_t len,
|
|||
BOILERPLATE_CREATE_CTX(ctx);
|
||||
|
||||
while (len) {
|
||||
xfer_len = min(len, SPIBAR_FDATA_FIFO_SIZE);
|
||||
xfer_len = get_xfer_len(addr, len);
|
||||
|
||||
ret = exec_sync_hwseq_xfer(ctx, SPIBAR_HSFSTS_CYCLE_READ,
|
||||
addr, xfer_len);
|
||||
|
@ -295,7 +310,7 @@ static int nuclear_spi_write(struct spi_flash *flash,
|
|||
BOILERPLATE_CREATE_CTX(ctx);
|
||||
|
||||
while (len) {
|
||||
xfer_len = min(len, SPIBAR_FDATA_FIFO_SIZE);
|
||||
xfer_len = get_xfer_len(addr, len);
|
||||
fill_xfer_fifo(ctx, data, xfer_len);
|
||||
|
||||
ret = exec_sync_hwseq_xfer(ctx, SPIBAR_HSFSTS_CYCLE_WRITE,
|
||||
|
|
Loading…
Reference in a new issue