Hi Martin,
On 23.04.2010 22:17, RayeR wrote:
The big problem here is that gettimeofday() apparently does not have any usable precision on your machine (maybe DOS/DJGPP related). Sometimes (always?) the time has not changed at all even after we delay for 10000 us and that causes the timer code to bail out.
Yes this function in DJGPP probably use standard timer at 18,2Hz (55ms) So I recomended uclock()...
Ah yes. I'll change that soon. For now, the delay function will complain, but it should work.
To summarize:
- gettimeofday() has precision worse than 10 ms and that triggers timer
recalculation.
- Low uncached memory access is still broken on DOS or our SB600 SPI
code has a bug. It would be cool if you could run flashrom under Linux on that machine (no read/write needed) and post the output in verbose mode. OTOH, it is possible that the BIOS screwed up caching of the SB600 SPI MMIO region and in this case we can't do anything about it because checking MTRRs is infeasible.
Today I tried linux version (static linked by Rudolf) and it hanged at probing of the same chip, see log. So it's not DJGPP releated problem.
Great, thanks for checking. The patch below will allow you to relocate the SB600/SB700 SPI memory BAR to a location that is less problematic. Basically, you want a memory address which is not used by other memory BARs and not backed by RAM. And the address should be in a region which is routed to the southbridge. If you have such an address (the free region needs to be at least 4kB in size), please run flashrom -p internal:sb600spibar=addr and replace addr with the address you want (e.g. 0xfd000000)
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-sb600_spibar/flashrom.8 =================================================================== --- flashrom-sb600_spibar/flashrom.8 (Revision 994) +++ flashrom-sb600_spibar/flashrom.8 (Arbeitskopie) @@ -222,12 +222,20 @@ .sp If your mainboard uses an ITE IT87 series Super I/O for LPC<->SPI flash bus translation, flashrom should autodetect that configuration. You can use +.sp .B "flashrom -p internal:it87spiport=portnum" syntax as explained in the .B it87spi programmer section to use a non-default port for controlling the IT87 series Super I/O. In the unlikely case flashrom doesn't detect an active IT87 LPC<->SPI bridge, you can try to force recognition by using the it87spi programmer. +.sp +If your mainboard uses a SB600/SB700 family southbridge and the default SPI +memory BAR is placed at an inconvenient location (e.g. in cached memory), +you can use +.sp +.B "flashrom -p internal:sb600spibar=addr" +syntax with addr being the memory address you want to have the SPI BAR at. .TP .BR "dummy " programmer An optional parameter specifies the bus types it Index: flashrom-sb600_spibar/chipset_enable.c =================================================================== --- flashrom-sb600_spibar/chipset_enable.c (Revision 994) +++ flashrom-sb600_spibar/chipset_enable.c (Arbeitskopie) @@ -809,9 +809,11 @@ static int enable_flash_sb600(struct pci_dev *dev, const char *name) { uint32_t tmp, prot; + uint8_t sb600_spiconfig; uint8_t reg; struct pci_dev *smbus_dev; int has_spi = 1; + char *sb600_spibar_text = NULL;
/* Clear ROM protect 0-3. */ for (reg = 0x50; reg < 0x60; reg += 4) { @@ -837,8 +839,24 @@
/* Read SPI_BaseAddr */ tmp = pci_read_long(dev, 0xa0); + sb600_spiconfig = tmp & 0x1f; tmp &= 0xffffffe0; /* remove bits 4-0 (reserved) */ printf_debug("SPI base address is at 0x%x\n", tmp); + if (programmer_param && !strlen(programmer_param)) { + free(programmer_param); + programmer_param = NULL; + } + if (programmer_param) { + sb600_spibar_text = extract_param(&programmer_param, + "sb600spibar=", ",:"); + if (sb600_spibar_text) { + tmp = strtoul(sb600_spibar_text, (char **)NULL, 0); + msg_pinfo("Forcing SB600 flash BAR to 0x%08x\n", + tmp); + pci_write_long(dev, 0xa0, tmp | sb600_spiconfig); + free(sb600_spibar_text); + } + }
/* If the BAR has address 0, it is unlikely SPI is used. */ if (!tmp) @@ -849,14 +867,15 @@ sb600_spibar = physmap("SB600 SPI registers", tmp & 0xfffff000, 0x1000); /* The low bits of the SPI base address are used as offset into - * the mapped page. + * the mapped page. The BAR can never be outside the allocated + * area due to BAR alignment rules. */ sb600_spibar += tmp & 0xfff;
- tmp = pci_read_long(dev, 0xa0); printf_debug("AltSpiCSEnable=%i, SpiRomEnable=%i, " - "AbortEnable=%i\n", tmp & 0x1, (tmp & 0x2) >> 1, - (tmp & 0x4) >> 2); + "AbortEnable=%i\n", sb600_spiconfig & 0x1, + (sb600_spiconfig & 0x2) >> 1, + (sb600_spiconfig & 0x4) >> 2); tmp = (pci_read_byte(dev, 0xba) & 0x4) >> 2; printf_debug("PrefetchEnSPIFromIMC=%i, ", tmp);