[coreboot-gerrit] New patch to review for coreboot: intel/apollolake: Ensure SPI operations do not cross 256-byte boundary

Furquan Shaikh (furquan@google.com) gerrit at coreboot.org
Mon Nov 14 22:53:27 CET 2016


Furquan Shaikh (furquan at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17419

-gerrit

commit b0a9876f877d9bcf0d17ce97597729fc4f34de48
Author: Furquan Shaikh <furquan at chromium.org>
Date:   Mon Nov 14 13:49:56 2016 -0800

    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 at chromium.org>
---
 src/soc/intel/apollolake/spi.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/src/soc/intel/apollolake/spi.c b/src/soc/intel/apollolake/spi.c
index 8cb8aa5..d60176a 100644
--- a/src/soc/intel/apollolake/spi.c
+++ b/src/soc/intel/apollolake/spi.c
@@ -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,



More information about the coreboot-gerrit mailing list