summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Laurie <dlaurie@chromium.org>2012-09-01 13:44:17 -0700
committerStefan Reinauer <stefan.reinauer@coreboot.org>2012-11-08 19:39:14 +0100
commit3beb6db6dda7795639d2bb8ec1a1aa3106a4c301 (patch)
tree14670c6e94f930a82c79f464ba41ccd80ed04fc4
parent00ba25decb105c4efd6e23ad985833e1d5d8b75d (diff)
downloadcoreboot-3beb6db6dda7795639d2bb8ec1a1aa3106a4c301.tar.xz
spi: fix erase in SMM while SPIBAR is locked
The handling of write enable was not entirely correct, the opcode needs to be skipped when the controller is locked down. Addresses were not getting set properly for erase commands which seemed to mostly work when the previous command had set an address. Tested by adding events to the event log at runtime on a freslhy flashed device (with locked down SPI controller) until the log log shrink happens to ensure it does not hang: hexdump -C elog.event.kernel_clean 00000000 01 00 00 00 ad de 00 00 00 00 for x in $(seq 1 232); do cat elog.event.kernel_clean > /sys/firmware/gsmi/append_to_eventlog done mosys eventlog list | tail -6 154 | 2012-09-01 13:54:43 | Kernel Event | Clean Shutdown 155 | 2012-09-01 13:54:43 | Kernel Event | Clean Shutdown 156 | 2012-09-01 13:54:43 | Kernel Event | Clean Shutdown 157 | 2012-09-01 13:54:43 | Kernel Event | Clean Shutdown 158 | 2012-09-01 13:54:43 | Log area cleared | 1030 159 | 2012-09-01 13:54:43 | Kernel Event | Clean Shutdown Change-Id: I3a50dae54422a9ff37daefce3632f8bcbe4eb89f Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: http://review.coreboot.org/1717 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
-rw-r--r--src/southbridge/intel/bd82x6x/spi.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/src/southbridge/intel/bd82x6x/spi.c b/src/southbridge/intel/bd82x6x/spi.c
index 2e88932c0b..53b9982192 100644
--- a/src/southbridge/intel/bd82x6x/spi.c
+++ b/src/southbridge/intel/bd82x6x/spi.c
@@ -627,13 +627,14 @@ int spi_xfer(struct spi_slave *slave, const void *dout,
if ((with_address = spi_setup_offset(&trans)) < 0)
return -1;
- if (!ichspi_lock && trans.opcode == SPI_OPCODE_WREN) {
+ if (trans.opcode == SPI_OPCODE_WREN) {
/*
* Treat Write Enable as Atomic Pre-Op if possible
* in order to prevent the Management Engine from
* issuing a transaction between WREN and DATA.
*/
- writew_(trans.opcode, cntlr.preop);
+ if (!ichspi_lock)
+ writew_(trans.opcode, cntlr.preop);
return 0;
}
@@ -645,6 +646,10 @@ int spi_xfer(struct spi_slave *slave, const void *dout,
control |= SPIC_ACS;
if (!trans.bytesout && !trans.bytesin) {
+ /* SPI addresses are 24 bit only */
+ if (with_address)
+ writel_(trans.offset & 0x00FFFFFF, cntlr.addr);
+
/*
* This is a 'no data' command (like Write Enable), its
* bitesout size was 1, decremented to zero while executing