On Tuesday 16 December 2008 10:18:16 am John Baldwin wrote: > So the real fix is that we need to disable memory and I/O decoding int > the PCI command register when messing with the BARs. One thing to be > careful with is we can't do any console I/O (i.e. printfs) while the > BAR is disabled. I will come up with a proper patch when I get back to > a real computer. Please try this instead (compiled, but not run-tested): --- //depot/vendor/freebsd/src/sys/dev/pci/pci.c 2008/11/13 20:00:29 +++ //depot/user/jhb/acpipci/dev/pci/pci.c 2009/01/15 21:40:48 _at__at_ -2291,9 +2291,27 _at__at_ struct resource *res; map = PCIB_READ_CONFIG(pcib, b, s, f, reg, 4); + + /* + * Disable decoding via the command register before + * determining the BAR's length since we will be placing them + * in a weird state. + */ + cmd = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_COMMAND, 2); + PCIB_WRITE_CONFIG(pcib, b, s, f, PCIR_COMMAND, + cmd & ~(PCI_BAR_MEM(map) ? PCIM_CMD_MEMEN : PCIM_CMD_PORTEN), 2); + + /* + * Determine the BAR's length by writing all 1's. The bottom + * log_2(size) bits of the BAR will stick as 0 when we read + * the value back. + */ PCIB_WRITE_CONFIG(pcib, b, s, f, reg, 0xffffffff, 4); testval = PCIB_READ_CONFIG(pcib, b, s, f, reg, 4); + + /* Restore the BAR and command register. */ PCIB_WRITE_CONFIG(pcib, b, s, f, reg, map, 4); + PCIB_WRITE_CONFIG(pcib, b, s, f, PCIR_COMMAND, cmd, 2); if (PCI_BAR_MEM(map)) type = SYS_RES_MEMORY; -- John BaldwinReceived on Thu Jan 15 2009 - 21:47:16 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:40 UTC