summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c')
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c69
1 files changed, 51 insertions, 18 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c b/xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c
index 4d600aaf9..5fe6fa30a 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c,v 1.42 2000/12/07 15:43:45 tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c,v 1.43 2001/01/06 20:19:15 tsi Exp $ */
/*
* Pci.c - New server PCI access functions
*
@@ -1054,8 +1054,10 @@ readPciBIOS(unsigned long Offset, PCITAG Tag, int basereg,
unsigned char *Buf, int Len)
{
ADDRESS hostbase;
+ CARD8 *image = Buf;
+ unsigned long offset;
CARD32 romaddr, savebase = 0, romsave = 0, newbase = 0;
- int ret;
+ int ret, length, rlength, n;
/* XXX This assumes that memory access is enabled */
@@ -1067,24 +1069,23 @@ readPciBIOS(unsigned long Offset, PCITAG Tag, int basereg,
romsave = pciReadLong(Tag, PCI_MAP_ROM_REG);
romaddr = PCIGETROM(romsave);
if ((newbase = getValidBIOSBase(Tag, &basereg)) != romaddr) {
+RetryWithBase:
romaddr = PCIGETROM(newbase);
- if (romaddr != 0 && romaddr == newbase) {
-#if 1
- /* move mem base out of the way if in conflict with ROM */
+ if (romaddr) {
+ /* move mem base out of the way if in conflicts with ROM */
if ((basereg >= 0) && (basereg <= 5)) {
- savebase = pciReadLong(Tag, PCI_MAP_REG_START + (basereg << 2));
+ if (!savebase)
+ savebase = pciReadLong(Tag, PCI_MAP_REG_START+(basereg<<2));
if (PCIGETROM(savebase) == romaddr) {
xf86MsgVerb(X_INFO,5,"xf86ReadPciBios: modifying membase[%i]"
" for device %i:%i:%i\n", basereg,
PCI_BUS_FROM_TAG(Tag), PCI_DEV_FROM_TAG(Tag),
PCI_FUNC_FROM_TAG(Tag));
- pciWriteLong(Tag, PCI_MAP_REG_START + (basereg << 2), 0);
+ pciWriteLong(Tag, PCI_MAP_REG_START + (basereg << 2),
+ (CARD32)~0);
}
}
-#endif
- pciWriteLong(Tag, PCI_MAP_ROM_REG, romaddr);
- } else
- romaddr = 0;
+ }
}
@@ -1092,10 +1093,10 @@ readPciBIOS(unsigned long Offset, PCITAG Tag, int basereg,
xf86Msg(X_WARNING, "xf86ReadPciBIOS: cannot locate a BIOS address\n");
return -1;
}
- else
- xf86MsgVerb(X_INFO,5,"xf86ReadPciBIOS: found ValidBIOSBase for %i:%i:%i:"
- " %x\n", PCI_BUS_FROM_TAG(Tag), PCI_DEV_FROM_TAG(Tag),
- PCI_FUNC_FROM_TAG(Tag),newbase);
+ xf86MsgVerb(X_INFO, 5,
+ "xf86ReadPciBIOS: found ValidBIOSBase for %i:%i:%i: %x\n",
+ PCI_BUS_FROM_TAG(Tag), PCI_DEV_FROM_TAG(Tag), PCI_FUNC_FROM_TAG(Tag),
+ newbase);
hostbase = pciBusAddrToHostAddr(Tag, PCI_MEM, PCIGETROM(romaddr));
#ifdef DEBUG
@@ -1104,7 +1105,37 @@ readPciBIOS(unsigned long Offset, PCITAG Tag, int basereg,
/* Enable ROM address decoding */
pciWriteLong(Tag, PCI_MAP_ROM_REG, romaddr | PCI_MAP_ROM_DECODE_ENABLE);
- ret = xf86ReadBIOS(hostbase, Offset, Buf, Len);
+ /* Read BIOS in 64kB chunks */
+ ret = 0;
+ offset = Offset;
+ while ((length = Len) > 0) {
+ if (length > 0x10000) length = 0x10000;
+ rlength = xf86ReadBIOS(hostbase, offset, image, length);
+ if (rlength < 0) {
+ ret = rlength;
+ break;
+ }
+ ret += rlength;
+ if (rlength < length) break;
+ offset += length;
+ image += length;
+ Len -= length;
+ }
+
+ if ((ret != Len) || (Buf[0] != 0x55) || (Buf[1] != 0xaa) || !Buf[2] ||
+ (Len < (Buf[2] << 9))) {
+ n = 0;
+ if ((basereg >= 0) && (basereg <= 5) && xf86PciVideoInfo) do {
+ pciVideoPtr pvp;
+
+ if (!(pvp = xf86PciVideoInfo[n++])) break;
+ if (pciTag(pvp->bus, pvp->device, pvp->func) == Tag) {
+ if (newbase == pvp->memBase[basereg]) break;
+ newbase = pvp->memBase[basereg];
+ goto RetryWithBase;
+ }
+ } while (1);
+ }
/* Restore ROM address decoding */
pciWriteLong(Tag, PCI_MAP_ROM_REG, romsave);
@@ -1129,7 +1160,8 @@ xf86ReadPciBIOS(unsigned long Offset, PCITAG Tag, int basereg,
size = readPciBIOS(Offset,Tag,basereg,Buf,Len);
- if (size != -1 && Buf[0] == 0x55 && Buf[1] == 0xaa)
+ if ((size == Len) && (Buf[0] == 0x55) && (Buf[1] == 0xaa) && Buf[2] &&
+ (Len >= (Buf[2] << 9)))
return size;
num = pciTestMultiDeviceCard(PCI_BUS_FROM_TAG(Tag),
@@ -1149,7 +1181,8 @@ xf86ReadPciBIOS(unsigned long Offset, PCITAG Tag, int basereg,
PCI_CMD_STAT_REG,(Acc2 | PCI_ENA));
size = readPciBIOS(Offset,pTag[i],0,Buf,Len);
((WriteProcPtr)(pciLongFunc(pTag[i],WRITE)))(pTag[i],PCI_CMD_STAT_REG,Acc2);
- if (size != -1 && ((CARD8*)Buf)[0] == 0x55 && ((CARD8*)Buf)[1] == 0xaa)
+ if ((size == Len) && (Buf[0] == 0x55) && (Buf[1] == 0xaa) && Buf[2] &&
+ (Len >= (Buf[2] << 9)))
break;
}
((WriteProcPtr)(pciLongFunc(Tag,WRITE)))(Tag,PCI_CMD_STAT_REG,Acc1);