On 11.07.2009 15:29, Carl-Daniel Hailfinger wrote:
More debugging for SB600/SB700 SPI. Some of this should be conditional on SB700. Anyway, it should be harmless on SB600.
Even more debugging and some scrubbing. I want to find out exactly how that bug manifests itself. It's entirely possible that this patch does corrupt input/output or yield undefined behaviour, so please don't try writing or erasing. ID and most probably read should be safe.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-spi_sb600_sb700_debug/chipset_enable.c =================================================================== --- flashrom-spi_sb600_sb700_debug/chipset_enable.c (Revision 653) +++ flashrom-spi_sb600_sb700_debug/chipset_enable.c (Arbeitskopie) @@ -692,7 +692,9 @@
/* Read SPI_BaseAddr */ tmp = pci_read_long(dev, 0xa0); - tmp &= 0xfffffff0; /* remove low 4 bits (reserved) */ + printf_debug("AltSpiCSEnable=%i, SpiRomEnable=%i, AbortEnable=%i\n", + tmp & 0x1, (tmp & 0x2) >> 1, (tmp & 0x4) >> 2); + tmp &= 0xffffffe0; /* remove bits 4-0 (reserved) */ printf_debug("SPI base address is at 0x%x\n", tmp);
/* If the BAR has address 0, it is unlikely SPI is used. */ @@ -704,6 +706,13 @@ /* The low bits of the SPI base address are used as offset into the mapped page */ sb600_spibar += tmp & 0xfff;
+ tmp = (pci_read_byte(dev, 0xba) & 0x4) >> 2; + printf_debug("PrefetchEnSPIFromIMC=%i, ", tmp); + + tmp = pci_read_byte(dev, 0xbb); + printf_debug("PrefetchEnSPIFromHost=%i, SpiOpEnInLpcMode=%i\n", + tmp & 0x1, (tmp & 0x20) >> 5); + /* Look for the SMBus device. */ smbus_dev = pci_dev_find(0x1002, 0x4385);
Index: flashrom-spi_sb600_sb700_debug/sb600spi.c =================================================================== --- flashrom-spi_sb600_sb700_debug/sb600spi.c (Revision 653) +++ flashrom-spi_sb600_sb700_debug/sb600spi.c (Arbeitskopie) @@ -104,6 +104,7 @@ const unsigned char *writearr, unsigned char *readarr) { int count; + int tmp; /* First byte is cmd which can not being sent through FIFO. */ unsigned char cmd = *writearr++;
@@ -124,15 +125,24 @@ return SPI_INVALID_LENGTH; }
+ tmp = mmio_readb(sb600_spibar + 1); + printf_debug("%s, old readcnt=%i, old writecnt=%i\n", + __func__, tmp >> 4, tmp & 0xf); + mmio_writeb(readcnt << 4 | (writecnt), sb600_spibar + 1); mmio_writeb(cmd, sb600_spibar + 0); - mmio_writeb(readcnt << 4 | (writecnt), sb600_spibar + 1);
/* Before we use the FIFO, reset it first. */ reset_internal_fifo_pointer();
+ /* Scrub the FIFO by writing a stream of 0xab. */ + for (count = 0; count < 8; count++) + mmio_writeb(0xab, sb600_spibar + 0xC); + reset_internal_fifo_pointer(); + /* Send the write byte to FIFO. */ for (count = 0; count < writecnt; count++, writearr++) { printf_debug(" [%x]", *writearr); + /* FIXME: Can we rely on auto-posting these writes or do we have to issue a read afterwards? */ mmio_writeb(*writearr, sb600_spibar + 0xC); } printf_debug("\n"); @@ -150,19 +160,28 @@ * received byte. Here we just reset the FIFO pointer, skip the * writecnt, is there anyone who have anther method to replace it? */ + printf_debug("The FIFO pointer before reset is %d.\n", mmio_readb(sb600_spibar + 0xd) & 0x07); reset_internal_fifo_pointer();
for (count = 0; count < writecnt; count++) { - cmd = mmio_readb(sb600_spibar + 0xC); /* Skip the byte we send. */ + cmd = mmio_readb(sb600_spibar + 0xC); /* Skip the bytes we send. */ printf_debug("[ %2x]", cmd); }
- printf_debug("The FIFO pointer 6 is %d.\n", mmio_readb(sb600_spibar + 0xd) & 0x07); + printf_debug("The FIFO pointer after skipping is %d.\n", mmio_readb(sb600_spibar + 0xd) & 0x07); for (count = 0; count < readcnt; count++, readarr++) { *readarr = mmio_readb(sb600_spibar + 0xC); printf_debug("[%02x]", *readarr); } printf_debug("\n");
+ printf_debug("The FIFO pointer after reading is %d.\n", mmio_readb(sb600_spibar + 0xd) & 0x07); + printf_debug("Dumping everything that's left in the FIFO\n"); + for (count = 0; count < 8; count++) { + cmd = mmio_readb(sb600_spibar + 0xC); + printf_debug("[ %2x]", cmd); + } + printf_debug("The FIFO pointer after dumping is %d.\n", mmio_readb(sb600_spibar + 0xd) & 0x07); + return 0; }