summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortsi <tsi>2008-03-26 18:57:48 +0000
committertsi <tsi>2008-03-26 18:57:48 +0000
commitddac60d1836ab7ba9d7dc7b2d5d853da8669a5e2 (patch)
tree760bb5109a72e6e24bae9acc38762c8c4b3d882d
parent92d15165327af807a34ac35beadae35d3e594f09 (diff)
32. Temporarily ignore 64-bit PCI memory address spaces on SPARC
(Marc La France). 31. For fault isolation purposes, on SPARC, bracket all PCI configuration space accesses with MEMBAR's (Marc La France). 30. Add PCI-X and PCI Express to the mix of PCI variants that are supported in a single system. Includes, but is not limited to, support for Sun's Ultra 25 and Ultra 45 systems. (Marc La France). 29. Remove assumption that all PCI entities have a function 0 (Marc La France).
-rw-r--r--programs/Xserver/hw/xfree86/CHANGELOG11
-rw-r--r--programs/Xserver/hw/xfree86/os-support/bus/Pci.c385
-rw-r--r--programs/Xserver/hw/xfree86/os-support/bus/Pci.h3
-rw-r--r--programs/Xserver/hw/xfree86/os-support/bus/sparcPci.c271
-rw-r--r--programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h123
5 files changed, 613 insertions, 180 deletions
diff --git a/programs/Xserver/hw/xfree86/CHANGELOG b/programs/Xserver/hw/xfree86/CHANGELOG
index b1ac5b7e3..df767c04c 100644
--- a/programs/Xserver/hw/xfree86/CHANGELOG
+++ b/programs/Xserver/hw/xfree86/CHANGELOG
@@ -1,4 +1,13 @@
XFree86 4.7.99.15 (xx April 2008)
+ 32. Temporarily ignore 64-bit PCI memory address spaces on SPARC
+ (Marc La France).
+ 31. For fault isolation purposes, on SPARC, bracket all PCI configuration
+ space accesses with MEMBAR's (Marc La France).
+ 30. Add PCI-X and PCI Express to the mix of PCI variants that are supported
+ in a single system. Includes, but is not limited to, support for Sun's
+ Ultra 25 and Ultra 45 systems. (Marc La France).
+ 29. Remove assumption that all PCI entities have a function 0
+ (Marc La France).
28. Update to 2008-03-26 pci.ids snapshot. Also add some more recent PCI
Radeon IDs. (Marc La France)
27. Fix integer wrap-arounds in XAA's wide line code path (Paul Mackerras).
@@ -20679,4 +20688,4 @@ XFree86 3.0a (28 April 1994)
XFree86 3.0 (26 April 1994)
-$XFree86: xc/programs/Xserver/hw/xfree86/CHANGELOG,v 3.3939 2008/03/26 17:45:59 tsi Exp $
+$XFree86: xc/programs/Xserver/hw/xfree86/CHANGELOG,v 3.3940 2008/03/26 18:39:08 tsi Exp $
diff --git a/programs/Xserver/hw/xfree86/os-support/bus/Pci.c b/programs/Xserver/hw/xfree86/os-support/bus/Pci.c
index 2d8b8ffe3..c1d9e7068 100644
--- a/programs/Xserver/hw/xfree86/os-support/bus/Pci.c
+++ b/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.98tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c,v 1.99tsi Exp $ */
/*
* Pci.c - New server PCI access functions
*
@@ -324,6 +324,7 @@ pciReadLong(PCITAG tag, int offset)
pciInit();
if ((bus >= 0) && ((bus < pciNumBuses) || inProbe) && pciBusInfo[bus] &&
+ (offset < pciBusInfo[bus]->pciMaxOffset) &&
pciBusInfo[bus]->funcs->pciReadLong) {
CARD32 rv = (*pciBusInfo[bus]->funcs->pciReadLong)(tag, offset);
@@ -372,6 +373,7 @@ pciWriteLong(PCITAG tag, int offset, CARD32 val)
pciInit();
if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] &&
+ (offset < pciBusInfo[bus]->pciMaxOffset) &&
pciBusInfo[bus]->funcs->pciWriteLong)
(*pciBusInfo[bus]->funcs->pciWriteLong)(tag, offset, val);
}
@@ -762,12 +764,20 @@ pciMfDev(int busnum, int devnum)
CARD32 id0, id1, val;
/* Detect a multi-function device that complies to the PCI 2.0 spec */
+ /* Unfortunately, some devices don't have a zero function */
+ while (1) {
+ tag0 = PCI_MAKE_TAG(busnum, devnum, pciFuncNum);
+ id0 = pciReadLong(tag0, PCI_ID_REG);
+ if ((CARD16)(id0 + 1) > (CARD16)1UL) {
+ if (pciFuncNum > 0)
+ return TRUE;
+ break;
+ }
+ if (++pciFuncNum >= 8)
+ return FALSE;
+ }
- tag0 = PCI_MAKE_TAG(busnum, devnum, 0);
- id0 = pciReadLong(tag0, PCI_ID_REG);
- if ((CARD16)(id0 + 1) <= (CARD16)1UL)
- return FALSE;
-
+ pciFuncNum = 1;
val = pciReadLong(tag0, PCI_HEADER_MISC) & 0x00ff0000;
if ((val != 0x00ff0000) && (val & PCI_HEADER_MULTIFUNCTION))
return TRUE;
@@ -775,7 +785,7 @@ pciMfDev(int busnum, int devnum)
/*
* Now, to find non-compliant devices...
* If there is a valid ID for function 1 and the ID for func 0 and 1
- * are different, or the base0 values of func 0 and 1 are differend,
+ * are different, or the base0 values of func 0 and 1 are different,
* then assume there is a multi-function device.
*/
tag1 = PCI_MAKE_TAG(busnum, devnum, 1);
@@ -830,6 +840,8 @@ pciGenFindNext(void)
for (pciBusNum = 0; !pciBusInfo[pciBusNum]; ++pciBusNum);
pciFuncNum = 0;
pciDevNum = 0;
+ if (pciBusInfo[pciBusNum]->pciMaxOffset == 0)
+ pciBusInfo[pciBusNum]->pciMaxOffset = 256;
previousBus = pciBusNum; /* make sure previousBus exists */
} else {
#ifdef PCI_MFDEV_SUPPORT
@@ -844,15 +856,14 @@ pciGenFindNext(void)
/*
* Is current dev a multifunction device?
*/
- if (!speculativeProbe && pciMfDev(pciBusNum, pciDevNum))
- /* Probe for other functions */
- pciFuncNum = 1;
- else
+ if (!pciMfDev(pciBusNum, pciDevNum)) {
/*
* No more functions this device. Next
* device please
*/
- pciDevNum ++;
+ pciDevNum++;
+ pciFuncNum = 0;
+ }
} else if (++pciFuncNum >= 8) {
/* No more functions for this device. Next device please */
pciFuncNum = 0;
@@ -920,24 +931,25 @@ pciGenFindNext(void)
if ((CARD16)(devid + 1U) <= (CARD16)1UL)
continue; /* Nobody home. Next device please */
- /*
- * Some devices mis-decode configuration cycles in such a way as to
- * create phantom buses.
- */
- if (speculativeProbe && (pciDevNum == 0) && (pciFuncNum == 0) &&
- (PCI_BUS_NO_DOMAIN(pciBusNum) > 0)) {
- for (;;) {
- if (++pciDevNum >= pciBusInfo[pciBusNum]->numDevices)
- goto NextSpeculativeBus;
- inProbe = TRUE;
- tmp = pciReadLong(PCI_MAKE_TAG(pciBusNum, pciDevNum, 0),
- PCI_ID_REG);
- inProbe = FALSE;
- if (devid != tmp)
- break;
- }
+ if ((pciDevNum == 0) && (pciFuncNum == 0)) {
+ /*
+ * Some devices mis-decode configuration cycles in such a way as to
+ * create phantom buses.
+ */
+ if (speculativeProbe && (PCI_BUS_NO_DOMAIN(pciBusNum) > 0)) {
+ for (;;) {
+ if (++pciDevNum >= pciBusInfo[pciBusNum]->numDevices)
+ goto NextSpeculativeBus;
+ inProbe = TRUE;
+ tmp = pciReadLong(PCI_MAKE_TAG(pciBusNum, pciDevNum, 0),
+ PCI_ID_REG);
+ inProbe = FALSE;
+ if (devid != tmp)
+ break;
+ }
- pciDevNum = 0;
+ pciDevNum = 0;
+ }
}
if (pciNumBuses <= pciBusNum)
@@ -987,6 +999,9 @@ pciGenFindNext(void)
*pciBusInfo[sec_bus] = *pciBusInfo[pri_bus];
}
+ pciBusInfo[sec_bus]->pciMaxOffset =
+ pciBusInfo[pri_bus]->pciMaxOffset;
+
/* ...but not everything same as parent */
pciBusInfo[sec_bus]->primary_bus = pri_bus;
pciBusInfo[sec_bus]->secondary = TRUE;
@@ -1006,14 +1021,14 @@ pciGenFindNext(void)
capptr = pciReadByte(pciDeviceTag, PCI_CB_CAP_PTR);
while (capptr &= ~0x03) {
- if (pciReadByte(pciDeviceTag, capptr + PCI_CAP_ID) !=
- PCI_CAP_PM_ID) {
- capptr = pciReadByte(pciDeviceTag,
- capptr + PCI_CAP_NEXT);
+ CARD32 PciReg = pciReadLong(pciDeviceTag, capptr);
+
+ if ((CARD8)PciReg != PCI_CAP_PM_ID) {
+ capptr = (CARD8)(PciReg >> 8);
continue;
}
- if (pciReadWord(pciDeviceTag, capptr + PCI_CAP_PM_CSR) &
+ if (pciReadLong(pciDeviceTag, capptr + PCI_CAP_PM_CSR) &
PCI_CAP_PM_MODE_MASK)
pciBusInfo[sec_bus]->numDevices = 0;
@@ -1154,6 +1169,23 @@ xf86scanpci(int flags)
if (devp->pci_header_type == 0xff)
devp->pci_header_type = 0;
+#ifdef OLD_FORMAT
+ xf86MsgVerb(X_INFO, 2, "PCI: BusID 0x%.2x,0x%02x,0x%1x "
+ "ID 0x%04x,0x%04x Rev 0x%02x Class 0x%02x,0x%02x\n",
+ devp->busnum, devp->devnum, devp->funcnum,
+ devp->pci_vendor, devp->pci_device, devp->pci_rev_id,
+ devp->pci_base_class, devp->pci_sub_class);
+#else
+ xf86MsgVerb(X_INFO, 2, "PCI: %.2x:%02x:%1x: chip %04x,%04x"
+ " card %04x,%04x rev %02x class %02x,%02x,%02x hdr %02x\n",
+ devp->busnum, devp->devnum, devp->funcnum,
+ devp->pci_vendor, devp->pci_device,
+ devp->pci_subsys_vendor, devp->pci_subsys_card,
+ devp->pci_rev_id, devp->pci_base_class,
+ devp->pci_sub_class, devp->pci_prog_if,
+ devp->pci_header_type);
+#endif
+
switch (devp->pci_header_type & 0x7f) {
case 0:
/* Get base address sizes for type 0 headers */
@@ -1172,14 +1204,7 @@ xf86scanpci(int flags)
devp->basesize[6] = /* Yep, the 6 & 7 are correct */
pciGetBaseSize(devp, 7, FALSE, &devp->minBasesize);
- /* Allow master aborts to complete normally on secondary buses */
- if (!(devp->pci_bridge_control & PCI_PCI_BRIDGE_MASTER_ABORT_EN))
- break;
- pciWriteWord(tag, PCI_PCI_BRIDGE_CONTROL_REG,
- devp->pci_bridge_control &
- ~(PCI_PCI_BRIDGE_MASTER_ABORT_EN |
- PCI_PCI_BRIDGE_SECONDARY_RESET));
- break;
+ goto bridge_control;
case 2:
/* Read more config space for this device */
@@ -1190,36 +1215,235 @@ xf86scanpci(int flags)
devp->basesize[0] =
pciGetBaseSize(devp, 0, FALSE, &devp->minBasesize);
+ bridge_control:
+ /*
+ * Note that, for PCI-X and PCI Express, the diddling of various
+ * error bits that is done below is ultimately ineffective at
+ * preventing interrupts. What it does do though is change the
+ * kind of interrupt that occurs. On Solaris at least, this makes
+ * the difference between being SIGKILL'ed rather than crashing the
+ * system.
+ */
+
/* Allow master aborts to complete normally on secondary buses */
- if (!(devp->pci_bridge_control & PCI_PCI_BRIDGE_MASTER_ABORT_EN))
- break;
- pciWriteWord(tag, PCI_PCI_BRIDGE_CONTROL_REG,
- devp->pci_bridge_control &
- ~(PCI_PCI_BRIDGE_MASTER_ABORT_EN |
- PCI_PCI_BRIDGE_SECONDARY_RESET));
- break;
+ if (devp->pci_bridge_control & PCI_PCI_BRIDGE_MASTER_ABORT_EN) {
+ pciWriteWord(tag, PCI_PCI_BRIDGE_CONTROL_REG,
+ devp->pci_bridge_control &
+ ~(PCI_PCI_BRIDGE_MASTER_ABORT_EN |
+ PCI_PCI_BRIDGE_SECONDARY_RESET));
+ if (pciReadWord(tag, PCI_PCI_BRIDGE_CONTROL_REG) &
+ PCI_PCI_BRIDGE_MASTER_ABORT_EN)
+ xf86Msg(X_WARNING, "Could not disable hard-failing of"
+ " master aborts through PCI bridge"
+ " %.2x:%02x:%02x\n",
+ devp->busnum, devp->devnum, devp->funcnum);
+ }
+
+ /*
+ * Unsupported request responses are the PCI Express equivalent to
+ * master aborts.
+ */
+ if (devp->pci_status_command & PCI_STAT_CAPABILITY) {
+ CARD16 capptr;
+
+ if ((devp->pci_header_type & 0x7f) == 1)
+ capptr = devp->pci_capptr;
+ else
+ capptr = devp->pci_cb_capptr;
+
+ /* Look for PCI Express capability */
+ while (capptr &= ~0xff03) {
+ CARD32 PciReg = pciReadLong(tag, capptr);
+ int sec_bus;
+
+ if ((CARD8)PciReg != PCI_CAP_PCIE_ID) {
+ capptr = (CARD8)(PciReg >> 8);
+ continue;
+ }
+
+ devp->pcie_cap_ptr = capptr;
+ devp->pcie_devtype = (PciReg >> 20) & 0x0f;
+
+ capptr += PCI_CAP_PCIE_DEV_CTL;
+ PciReg = pciReadLong(tag, capptr);
+ devp->pcie_dev_ctl = (CARD16)PciReg;
+
+ /*
+ * Disable reporting of unsupported requests. Grr, because
+ * these are _also_ reported as non-fatal errors, we must
+ * disable the port's SERR enable and its ability to
+ * forward same from downstream.
+ */
+ if (PciReg & (PCI_CAP_PCIE_URR_EN | PCI_CAP_PCIE_NFR_EN))
+ {
+ pciWriteLong(tag, capptr, PciReg &
+ ~(PCI_CAP_PCIE_URR_EN | PCI_CAP_PCIE_NFR_EN));
+ if (pciReadLong(tag, capptr) &
+ (PCI_CAP_PCIE_URR_EN | PCI_CAP_PCIE_NFR_EN))
+ xf86Msg(X_WARNING, "Could not disable reporting of"
+ " unsupported requests through PCI bridge"
+ " %.2x:%02x:%02x\n",
+ devp->busnum, devp->devnum, devp->funcnum);
+ }
+ if (devp->pci_status_command & PCI_CMD_SERR_ENABLE) {
+ pciWriteLong(tag, PCI_CMD_STAT_REG,
+ devp->pci_status_command & ~PCI_CMD_SERR_ENABLE);
+ if (pciReadLong(tag, PCI_CMD_STAT_REG) &
+ PCI_CMD_SERR_ENABLE)
+ xf86Msg(X_WARNING, "Could not disable SERR on PCI"
+ " bridge %.2x:%02x:%02x\n",
+ devp->busnum, devp->devnum, devp->funcnum);
+ }
+ if (devp->pci_bridge_control & PCI_PCI_BRIDGE_SERR_EN) {
+ pciWriteWord(tag, PCI_PCI_BRIDGE_CONTROL_REG,
+ devp->pci_bridge_control &
+ ~(PCI_PCI_BRIDGE_MASTER_ABORT_EN |
+ PCI_PCI_BRIDGE_SERR_EN |
+ PCI_PCI_BRIDGE_SECONDARY_RESET));
+ if (pciReadWord(tag, PCI_PCI_BRIDGE_CONTROL_REG) &
+ PCI_PCI_BRIDGE_SERR_EN)
+ xf86Msg(X_WARNING, "Could not disable SERR"
+ " forwarding through PCI bridge"
+ " %.2x:%02x:%02x\n",
+ devp->busnum, devp->devnum, devp->funcnum);
+ }
+
+ /* Setup for per-device configuration space size */
+ sec_bus =
+ PCI_SECONDARY_BUS_EXTRACT(devp->pci_pp_bus_register,
+ tag);
+ pciBusInfo[devp->busnum]->pciMaxOffset =
+ pciBusInfo[sec_bus]->pciMaxOffset = 4096;
+ if (devp->pcie_devtype == PCI_CAP_PCIE_DEVTYPE_PCIE_PCI) {
+ pciBusInfo[sec_bus]->pciMaxOffset = 256;
+
+ if ((devp->pci_header_type & 0x7f) == 1)
+ capptr = devp->pci_capptr;
+ else
+ capptr = devp->pci_cb_capptr;
+
+ /* Look for PCI-X capability */
+ while (capptr & ~0xff03) {
+ PciReg = pciReadLong(tag, capptr);
+ if ((CARD8)PciReg != PCI_CAP_PCIX_ID) {
+ capptr = (CARD8)(PciReg >> 8);
+ continue;
+ }
+
+ if ((PciReg & (PCI_CAP_PCIX_STAT_MODE << 16)) >=
+ (PCI_CAP_PCIX_STAT_PCIX2_MIN << 22))
+ pciBusInfo[sec_bus]->pciMaxOffset = 4096;
+
+ break;
+ }
+ }
+
+ /* Look for Advanced Error Reporting capability */
+ capptr = PCIE_CAP_FIRST;
+ while (capptr &= ~0xf003) {
+ PciReg = pciReadLong(tag, capptr);
+
+ if ((CARD16)(PciReg + 1) <= (CARD16)1UL)
+ break; /* Nothing there or not accessible */
+
+ if ((CARD16)(PciReg) != PCIE_CAP_AER_ID) {
+ capptr = PciReg >> 20;
+ continue;
+ }
+
+ devp->aer_cap_ptr = capptr;
+
+ /* Ensure unsupported request errors are not reported */
+ devp->aer_ue_mask =
+ pciReadLong(tag, capptr + PCIE_CAP_AER_UE_MASK);
+ if (!(devp->aer_ue_mask & PCIE_CAP_AER_UE_URE)) {
+ pciWriteLong(tag, capptr + PCIE_CAP_AER_UE_MASK,
+ devp->aer_ue_mask | PCIE_CAP_AER_UE_URE);
+ if (!(pciReadLong(tag,
+ capptr + PCIE_CAP_AER_UE_MASK) &
+ PCIE_CAP_AER_UE_URE))
+ xf86Msg(X_WARNING, "Could not disable extended"
+ " reporting of unsupported requests"
+ " through PCI bridge %.2x:%02x:%02x\n",
+ devp->busnum,
+ devp->devnum,
+ devp->funcnum);
+ }
+
+ /* Make unsupported request errors non-fatal */
+ devp->aer_ue_severity =
+ pciReadLong(tag, capptr + PCIE_CAP_AER_UE_SEV);
+ if (devp->aer_ue_severity & PCIE_CAP_AER_UE_URE) {
+ pciWriteLong(tag, capptr + PCIE_CAP_AER_UE_SEV,
+ devp->aer_ue_severity & ~PCIE_CAP_AER_UE_URE);
+ if (pciReadLong(tag, capptr + PCIE_CAP_AER_UE_SEV)
+ & PCIE_CAP_AER_UE_URE)
+ xf86Msg(X_WARNING, "Could not make unsupported"
+ " requests non-fatal through PCI"
+ " bridge %.2x:%02x:%02x\n",
+ devp->busnum,
+ devp->devnum,
+ devp->funcnum);
+ }
+
+ /* Deal with PCI Express to PCI/PCI-X bridges */
+ if (devp->pcie_devtype != PCI_CAP_PCIE_DEVTYPE_PCIE_PCI)
+ break;
+
+ /*
+ * Mask out master aborts from the PCI/PCI-X interface.
+ */
+ devp->aer_sue_mask =
+ pciReadLong(tag, capptr + PCIE_CAP_AER_SUE_MASK);
+ if ((devp->aer_sue_mask &
+ PCIE_CAP_AER_SUE_MASTER_ABORT) !=
+ PCIE_CAP_AER_SUE_MASTER_ABORT) {
+ pciWriteLong(tag, capptr + PCIE_CAP_AER_SUE_MASK,
+ devp->aer_sue_mask |
+ PCIE_CAP_AER_SUE_MASTER_ABORT);
+ if ((pciReadLong(tag,
+ capptr + PCIE_CAP_AER_SUE_MASK) &
+ PCIE_CAP_AER_SUE_MASTER_ABORT) !=
+ PCIE_CAP_AER_SUE_MASTER_ABORT)
+ xf86Msg(X_WARNING, "Could not disable"
+ " hard-failing of secondary master"
+ " aborts through PCI bridge"
+ "%.2x:%02x:%02x\n",
+ devp->busnum,
+ devp->devnum,
+ devp->funcnum);
+ }
+
+ /* Make master aborts non-fatal */
+ devp->aer_sue_severity =
+ pciReadLong(tag, capptr + PCIE_CAP_AER_SUE_SEV);
+ if (devp->aer_sue_severity &
+ PCIE_CAP_AER_SUE_MASTER_ABORT) {
+ pciWriteLong(tag, capptr + PCIE_CAP_AER_SUE_SEV,
+ devp->aer_sue_severity &
+ ~PCIE_CAP_AER_SUE_MASTER_ABORT);
+ if (pciReadLong(tag,
+ capptr + PCIE_CAP_AER_SUE_SEV) &
+ PCIE_CAP_AER_SUE_MASTER_ABORT)
+ xf86Msg(X_WARNING, "Could not make master"
+ " aborts non-fatal through PCI bridge"
+ "%.2x:%02x:%02x\n",
+ devp->busnum,
+ devp->devnum,
+ devp->funcnum);
+ }
+
+ break;
+ }
+
+ break;
+ }
+ }
default:
break;
}
-#ifdef OLD_FORMAT
- xf86MsgVerb(X_INFO, 2, "PCI: BusID 0x%.2x,0x%02x,0x%1x "
- "ID 0x%04x,0x%04x Rev 0x%02x Class 0x%02x,0x%02x\n",
- devp->busnum, devp->devnum, devp->funcnum,
- devp->pci_vendor, devp->pci_device, devp->pci_rev_id,
- devp->pci_base_class, devp->pci_sub_class);
-#else
- xf86MsgVerb(X_INFO, 2, "PCI: %.2x:%02x:%1x: chip %04x,%04x"
- " card %04x,%04x rev %02x class %02x,%02x,%02x hdr %02x\n",
- devp->busnum, devp->devnum, devp->funcnum,
- devp->pci_vendor, devp->pci_device,
- devp->pci_subsys_vendor, devp->pci_subsys_card,
- devp->pci_rev_id, devp->pci_base_class,
- devp->pci_sub_class, devp->pci_prog_if,
- devp->pci_header_type);
-#endif
-
pci_devp[idx++] = devp;
tag = pciFindNext();
@@ -1269,10 +1493,35 @@ xf86scanpci(int flags)
ARCH_PCI_PCI_BRIDGE(devp);
#endif
}
- if (!(devp->pci_bridge_control & PCI_PCI_BRIDGE_MASTER_ABORT_EN))
- break;
+
+ if (devp->aer_cap_ptr != 0) {
+ if (devp->pcie_devtype == PCI_CAP_PCIE_DEVTYPE_PCIE_PCI) {
+ pciWriteLong(devp->tag,
+ devp->aer_cap_ptr + PCIE_CAP_AER_SUE_MASK,
+ devp->aer_sue_mask);
+ pciWriteLong(devp->tag,
+ devp->aer_cap_ptr + PCIE_CAP_AER_SUE_SEV,
+ devp->aer_sue_severity);
+ }
+ pciWriteLong(devp->tag,
+ devp->aer_cap_ptr + PCIE_CAP_AER_UE_MASK,
+ devp->aer_ue_mask);
+ pciWriteLong(devp->tag,
+ devp->aer_cap_ptr + PCIE_CAP_AER_UE_SEV,
+ devp->aer_ue_severity);
+ }
+
+ if (devp->pcie_cap_ptr != 0) {
+ pciWriteWord(devp->tag,
+ devp->pcie_cap_ptr + PCI_CAP_PCIE_DEV_CTL,
+ devp->pcie_dev_ctl);
+ pciWriteLong(devp->tag, PCI_CMD_STAT_REG,
+ devp->pci_status_command);
+ }
+
pciWriteWord(devp->tag, PCI_PCI_BRIDGE_CONTROL_REG,
devp->pci_bridge_control & ~PCI_PCI_BRIDGE_SECONDARY_RESET);
+
break;
default:
diff --git a/programs/Xserver/hw/xfree86/os-support/bus/Pci.h b/programs/Xserver/hw/xfree86/os-support/bus/Pci.h
index 1719dd202..36f7649cd 100644
--- a/programs/Xserver/hw/xfree86/os-support/bus/Pci.h
+++ b/programs/Xserver/hw/xfree86/os-support/bus/Pci.h
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.h,v 1.56tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.h,v 1.57tsi Exp $ */
/*
* Copyright 1998 by Concurrent Computer Corporation
*
@@ -168,6 +168,7 @@
#define PCI_FUNC_FROM_TAG(tag) (((tag) & 0x00000700u) >> 8)
#define PCI_DFN_FROM_TAG(tag) (((tag) & 0x0000ff00u) >> 8)
+#define PCI_BDF_FROM_TAG(tag) (((tag) & 0x00ffff00u) >> 8)
#define PCI_BDEV_FROM_TAG(tag) ((tag) & 0x00fff800u)
#define PCI_DOM_FROM_BUS(bus) (((bus) >> 8) & (PCI_DOM_MASK))
diff --git a/programs/Xserver/hw/xfree86/os-support/bus/sparcPci.c b/programs/Xserver/hw/xfree86/os-support/bus/sparcPci.c
index 1156e73e0..6cc12df1a 100644
--- a/programs/Xserver/hw/xfree86/os-support/bus/sparcPci.c
+++ b/programs/Xserver/hw/xfree86/os-support/bus/sparcPci.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/sparcPci.c,v 1.30tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/sparcPci.c,v 1.31tsi Exp $ */
/*
* Copyright (C) 2001-2007 The XFree86 Project, Inc.
* All rights reserved.
@@ -117,7 +117,7 @@ typedef struct _sparcDomainRec {
pointer pci, io;
int bus_min, bus_max;
int tagMultiplier, maxOffset;
- unsigned char dfn_mask[256 / 8];
+ unsigned char *bdf_mask;
} sparcDomainRec, *sparcDomainPtr;
#define SetBitInMap(bit, map) \
@@ -142,23 +142,84 @@ static int pciNumDomains = 1;
*(volatile type *)(pointer)((char *)((domain)->pci) + \
((PCI_TAG_NO_DOMAIN(tag) * (domain)->tagMultiplier) | (off)))
+/*
+ * Functions to wrap PciReg accesses with membar's for fault isolation
+ * purposes.
+ */
+
+static __inline__ CARD8
+GetPciByte(sparcDomainPtr pDomain, PCITAG tag, int off)
+{
+ volatile CARD8 result; /* Must be volatile */
+
+ barrier();
+ result = PciReg(pDomain, tag, off, CARD8);
+ barrier();
+ return result;
+}
+
+static __inline__ CARD16
+GetPciWord(sparcDomainPtr pDomain, PCITAG tag, int off)
+{
+ volatile CARD16 result; /* Must be volatile */
+
+ barrier();
+ result = PciReg(pDomain, tag, off, CARD16);
+ barrier();
+ return result;
+}
+
+static __inline__ CARD32
+GetPciLong(sparcDomainPtr pDomain, PCITAG tag, int off)
+{
+ volatile CARD32 result; /* Must be volatile */
+
+ barrier();
+ result = PciReg(pDomain, tag, off, CARD32);
+ barrier();
+ return result;
+}
+
+static __inline__ void
+PutPciByte(sparcDomainPtr pDomain, PCITAG tag, int off, CARD8 val)
+{
+ barrier();
+ PciReg(pDomain, tag, off, CARD8) = val;
+ barrier();
+}
+
+static __inline__ void
+PutPciWord(sparcDomainPtr pDomain, PCITAG tag, int off, CARD16 val)
+{
+ barrier();
+ PciReg(pDomain, tag, off, CARD16) = val;
+ barrier();
+}
+
+static __inline void
+PutPciLong(sparcDomainPtr pDomain, PCITAG tag, int off, CARD32 val)
+{
+ barrier();
+ PciReg(pDomain, tag, off, CARD32) = val;
+ barrier();
+}
+
/* Generic SPARC PCI access functions */
static CARD32
sparcPciCfgRead32(PCITAG tag, int off)
{
- pciBusInfo_t *pBusInfo;
- sparcDomainPtr pDomain;
- volatile CARD32 result = (CARD32)(-1); /* Must be volatile */
- int bus;
+ pciBusInfo_t *pBusInfo;
+ sparcDomainPtr pDomain;
+ CARD32 result = (CARD32)(-1);
+ int bus;
if ((off >= 0) && !(off & 3) &&
((bus = PCI_BUS_FROM_TAG(tag)) < pciNumBuses) &&
(pBusInfo = pciBusInfo[bus]) && (pDomain = pBusInfo->pciBusPriv) &&
(off < pDomain->maxOffset) &&
(bus >= pDomain->bus_min) && (bus < pDomain->bus_max) &&
- ((bus > pDomain->bus_min) ||
- IsBitSetInMap(PCI_DFN_FROM_TAG(tag), pDomain->dfn_mask))) {
- result = PciReg(pDomain, tag, off, CARD32);
+ IsBitSetInMap(PCI_BDF_FROM_TAG(tag), pDomain->bdf_mask)) {
+ result = GetPciLong(pDomain, tag, off);
result = PCI_CPU(result);
}
@@ -178,12 +239,11 @@ sparcPciCfgWrite32(PCITAG tag, int off, CARD32 val)
!(pBusInfo = pciBusInfo[bus]) || !(pDomain = pBusInfo->pciBusPriv) ||
(off >= pDomain->maxOffset) ||
(bus < pDomain->bus_min) || (bus >= pDomain->bus_max) ||
- ((bus == pDomain->bus_min) &&
- !IsBitSetInMap(PCI_DFN_FROM_TAG(tag), pDomain->dfn_mask)))
+ !IsBitSetInMap(PCI_BDF_FROM_TAG(tag), pDomain->bdf_mask))
return;
val = PCI_CPU(val);
- PciReg(pDomain, tag, off, CARD32) = val;
+ PutPciLong(pDomain, tag, off, val);
}
static void
@@ -213,10 +273,10 @@ static pciBusFuncs_t sparcPCIFunctions =
static CARD32
sabrePciCfgRead32(PCITAG tag, int off)
{
- pciBusInfo_t *pBusInfo;
- sparcDomainPtr pDomain;
- volatile CARD32 result; /* Must be volatile */
- int bus;
+ pciBusInfo_t *pBusInfo;
+ sparcDomainPtr pDomain;
+ CARD32 result;
+ int bus;
if (PCI_BDEV_FROM_TAG(tag))
return sparcPciCfgRead32(tag, off);
@@ -228,15 +288,15 @@ sabrePciCfgRead32(PCITAG tag, int off)
return (CARD32)(-1);
if (off < 8) {
- result = (PciReg(pDomain, tag, off, CARD16) << 16) |
- PciReg(pDomain, tag, off + 2, CARD16);
+ result = (GetPciWord(pDomain, tag, off) << 16) |
+ GetPciWord(pDomain, tag, off + 2);
return PCI_CPU(result);
}
- result = (PciReg(pDomain, tag, off + 3, CARD8) << 24) |
- (PciReg(pDomain, tag, off + 2, CARD8) << 16) |
- (PciReg(pDomain, tag, off + 1, CARD8) << 8) |
- (PciReg(pDomain, tag, off , CARD8) );
+ result = (GetPciByte(pDomain, tag, off + 3) << 24) |
+ (GetPciByte(pDomain, tag, off + 2) << 16) |
+ (GetPciByte(pDomain, tag, off + 1) << 8) |
+ (GetPciByte(pDomain, tag, off ) );
return result;
}
@@ -257,13 +317,13 @@ sabrePciCfgWrite32(PCITAG tag, int off, CARD32 val)
(bus == pDomain->bus_min)) {
if (off < 8) {
val = PCI_CPU(val);
- PciReg(pDomain, tag, off , CARD16) = val >> 16;
- PciReg(pDomain, tag, off + 2, CARD16) = val;
+ PutPciWord(pDomain, tag, off , val >> 16);
+ PutPciWord(pDomain, tag, off + 2, val);
} else {
- PciReg(pDomain, tag, off , CARD8) = val;
- PciReg(pDomain, tag, off + 1, CARD8) = val >> 8;
- PciReg(pDomain, tag, off + 2, CARD8) = val >> 16;
- PciReg(pDomain, tag, off + 3, CARD8) = val >> 24;
+ PutPciByte(pDomain, tag, off , val);
+ PutPciByte(pDomain, tag, off + 1, val >> 8);
+ PutPciByte(pDomain, tag, off + 2, val >> 16);
+ PutPciByte(pDomain, tag, off + 3, val >> 24);
}
}
}
@@ -296,54 +356,69 @@ static struct {
static int nAddressSizes = 0;
/*
- * Extract base size information from "assigned-addresses" properties.
+ * Scan the PROM device tree rooted at 'node', accumulating a bit map of PCI
+ * devices that exist, and retrieving base size information.
*/
static void
-sparcAssignedAddresses(sparcDomainPtr pDomain, int node)
+sparcScanPciTree(sparcDomainPtr pDomain, int node)
{
char *prop_val;
int prop_len;
- /* Retrieve and validate "assigned-addresses" property */
- prop_val = promGetProperty("assigned-addresses", &prop_len);
- if (prop_val && !(prop_len % 20)) {
- prop_len /= 20;
- for (; prop_len--; prop_val += 20) {
- if (((unsigned char)prop_val[1] < pDomain->bus_min) ||
- ((unsigned char)prop_val[1] > pDomain->bus_max) ||
- (prop_val[3] & 0x3) || (prop_val[3] < PCI_MAP_REG_START) ||
- ((CARD32 *)prop_val)[1] || ((CARD32 *)prop_val)[3] ||
- (((CARD32 *)prop_val)[4] < 4) ||
- (((CARD32 *)prop_val)[4] & (((CARD32 *)prop_val)[4] - 1)) ||
- (((CARD32 *)prop_val)[2] & (((CARD32 *)prop_val)[4] - 1)))
- continue;
-
- if ((prop_val[3] >= PCI_MAP_REG_END) &&
- (prop_val[3] != PCI_MAP_ROM_REG) &&
- (prop_val[3] != PCI_PCI_BRIDGE_ROM_REG))
- continue;
+ for (node = promGetChild(node); node; node = promGetSibling(node)) {
+ /* Retrieve and validate "reg" property */
+ prop_val = promGetProperty("reg", &prop_len);
+ if (prop_val && !(prop_len % 20)) {
+ /*
+ * It's unnecessary to scan the entire "reg" property, but I'll do
+ * so anyway.
+ */
+ prop_len /= 20;
+ for (; prop_len--; prop_val += 20)
+ SetBitInMap(PCI_BDF_FROM_TAG(*(CARD32 *)prop_val),
+ pDomain->bdf_mask);
+ }
- prop_val[0] = pciNumDomains;
- pAddressSizes = xnfrealloc(pAddressSizes,
- sizeof(*pAddressSizes) * (nAddressSizes + 1));
- pAddressSizes[nAddressSizes].tag = ((CARD32 *)prop_val)[0];
- for (pAddressSizes[nAddressSizes].size = -1;
- ((CARD32 *)prop_val)[4];
- ((CARD32 *)prop_val)[4] >>= 1)
- pAddressSizes[nAddressSizes].size++;
- nAddressSizes++;
+ /* Retrieve and validate "assigned-addresses" property */
+ prop_val = promGetProperty("assigned-addresses", &prop_len);
+ if (prop_val && !(prop_len % 20)) {
+ prop_len /= 20;
+ for (; prop_len--; prop_val += 20) {
+ if (((unsigned char)prop_val[1] < pDomain->bus_min) ||
+ ((unsigned char)prop_val[1] > pDomain->bus_max) ||
+ (prop_val[3] & 0x3) || (prop_val[3] < PCI_MAP_REG_START) ||
+ ((CARD32 *)prop_val)[1] || ((CARD32 *)prop_val)[3] ||
+ (((CARD32 *)prop_val)[4] < 4) ||
+ (((CARD32 *)prop_val)[4] & (((CARD32 *)prop_val)[4] - 1)) ||
+ (((CARD32 *)prop_val)[2] & (((CARD32 *)prop_val)[4] - 1)))
+ continue;
+
+ if ((prop_val[3] >= PCI_MAP_REG_END) &&
+ (prop_val[3] != PCI_MAP_ROM_REG) &&
+ (prop_val[3] != PCI_PCI_BRIDGE_ROM_REG))
+ continue;
+
+ prop_val[0] = pciNumDomains;
+ pAddressSizes = xnfrealloc(pAddressSizes,
+ sizeof(*pAddressSizes) * (nAddressSizes + 1));
+ pAddressSizes[nAddressSizes].tag = ((CARD32 *)prop_val)[0];
+ for (pAddressSizes[nAddressSizes].size = -1;
+ ((CARD32 *)prop_val)[4];
+ ((CARD32 *)prop_val)[4] >>= 1)
+ pAddressSizes[nAddressSizes].size++;
+ nAddressSizes++;
+ }
}
- }
- /* Retrieve and validate "class-code" property */
- prop_val = promGetProperty("class-code", &prop_len);
- if (prop_val && (prop_len == 4) &&
- (prop_val[0] == 0) && (prop_val[1] == PCI_CLASS_BRIDGE) &&
- ((prop_val[2] == PCI_SUBCLASS_BRIDGE_PCI) ||
- (prop_val[2] == PCI_SUBCLASS_BRIDGE_CARDBUS)))
- for (node = promGetChild(node); node; node = promGetSibling(node))
- sparcAssignedAddresses(pDomain, node);
+ /* Retrieve and validate "class-code" property */
+ prop_val = promGetProperty("class-code", &prop_len);
+ if (prop_val && (prop_len == 4) &&
+ (prop_val[0] == 0) && (prop_val[1] == PCI_CLASS_BRIDGE) &&
+ ((prop_val[2] == PCI_SUBCLASS_BRIDGE_PCI) ||
+ (prop_val[2] == PCI_SUBCLASS_BRIDGE_CARDBUS)))
+ sparcScanPciTree(pDomain, node);
+ }
}
/* Return the PCI allocation sizes derived above */
@@ -381,7 +456,7 @@ xf86GetPciSizeFromOS(PCITAG tag, int Index, int *bits)
void
sparcPciInit(void)
{
- int node, node2;
+ int node;
if (!xf86LinearVidMem())
return;
@@ -405,7 +480,7 @@ sparcPciInit(void)
pciBusFuncs_p pFunctions;
char *prop_val;
int prop_len, bus;
- char shared_pci;
+ char shared_pci, pciex;
prop_val = promGetProperty("name", &prop_len);
if (!prop_val || (prop_len < 3))
@@ -442,6 +517,12 @@ sparcPciInit(void)
xf86Msg(X_INFO, "PCI host bridge found (\"%s\")\n", prop_val);
+ prop_val = promGetProperty("device_type", &prop_len);
+ if (prop_val && !strcmp("pciex", prop_val))
+ pciex = 1;
+ else
+ pciex = 0;
+
/* Get "bus-range" property */
prop_val = promGetProperty("bus-range", &prop_len);
if (!prop_val || (prop_len != 8) ||
@@ -504,8 +585,6 @@ sparcPciInit(void)
break;
case 2: /* 32-bit memory space */
- case 3: /* 64-bit memory space */
- default: /* Muffle compiler */
if ((domain.mem_addr == phys_addr) &&
(domain.mem_size == phys_size))
break;
@@ -515,6 +594,10 @@ sparcPciInit(void)
domain.mem_addr = phys_addr;
domain.mem_size = phys_size;
break;
+
+ case 3: /* 64-bit memory space */
+ default: /* Muffle compiler */
+ break; /* Ignore, for now */
}
}
@@ -550,6 +633,11 @@ sparcPciInit(void)
domain.pci = (char *)domain.pci - (phys_addr - pci_addr);
+ /* Allocate bus/device/function bit map */
+ domain.bdf_mask = (unsigned char *)xnfcalloc(1,
+ (domain.bus_max - domain.bus_min + 1) << 5) -
+ (domain.bus_min << 5);
+
xf86MsgVerb(X_INFO, 4, "Adding PCI domain %d:\n", pciNumDomains);
xf86MsgVerb(X_INFO, 4,
"PCI Configuration space: 0x%016llx, size: 0x%09llx\n",
@@ -581,6 +669,7 @@ sparcPciInit(void)
pciBusInfo[bus]->numDevices = 32;
pciBusInfo[bus]->funcs = pFunctions;
pciBusInfo[bus]->pciBusPriv = pDomain;
+ pciBusInfo[bus]->pciMaxOffset = domain.maxOffset;
while (++bus < pciNumBuses) {
pciBusInfo[bus] = xnfalloc(sizeof(pciBusInfo_t));
*(pciBusInfo[bus]) = *(pciBusInfo[bus - 1]);
@@ -652,30 +741,30 @@ sparcPciInit(void)
* VGA, or if a PCI device actually implements PCI disablement.
*
* --- TSI @ UQV 2001.09.19
+ *
+ * This has been changed to generate a bit map for all of an
+ * interface's buses, because it appears that probing for a PCI Express
+ * switch's downstream ports cannot be done without generating
+ * interrupts that are untrappable from userland. In effect, PCI
+ * Express has entrenched the hard-failing of unsupported requests
+ * (which include its equivalent to master aborts).
+ *
+ * --- TSI @ UQV 2008.01.31
*/
- for (node2 = promGetChild(node);
- node2;
- node2 = promGetSibling(node2)) {
- /* Get "reg" property */
- prop_val = promGetProperty("reg", &prop_len);
- if (prop_val && !(prop_len % 20)) {
-
- /*
- * It's unnecessary to scan the entire "reg" property, but I'll
- * do so anyway.
- */
- prop_len /= 20;
- for (; prop_len--; prop_val += 20)
- SetBitInMap(PCI_DFN_FROM_TAG(*(CARD32 *)prop_val),
- pDomain->dfn_mask);
- }
+ sparcScanPciTree(&domain, node);
- /* Scan "assigned-addresses" properties for resource sizes */
- sparcAssignedAddresses(&domain, node2);
- }
+ /*
+ * Assume the host bridge is device 0, function 0 on its bus. Note
+ * that this is valid for PCI Express as well, because the spec
+ * requires that the other end of the link from a root port, or any
+ * of a switch's downstream ports, be device 0, function 0.
+ */
+ SetBitInMap(domain.bus_min << 8, pDomain->bdf_mask);
- /* Assume the host bridge is device 0, function 0 on its bus */
- SetBitInMap(0, pDomain->dfn_mask);
+ if ((domain.bus_min < domain.bus_max) &&
+ (!pciex || (xf86Info.estimateSizesAggressively > 0)))
+ memset(domain.bdf_mask + ((domain.bus_min + 1) << 5), 0xff,
+ (domain.bus_max - domain.bus_min) << 5);
pciNumDomains++;
diff --git a/programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h b/programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h
index 06e02cf38..512e01b00 100644
--- a/programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h
+++ b/programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h,v 1.47tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h,v 1.48tsi Exp $ */
/*
* Copyright 1998 by Concurrent Computer Corporation
*
@@ -351,6 +351,13 @@
#define PCI_IF_SERIAL_USB_DEVICE 0xfe
#define PCI_SUBCLASS_SERIAL_FIBRECHANNEL 0x04
#define PCI_SUBCLASS_SERIAL_SMBUS 0x05
+#define PCI_SUBCLASS_SERIAL_INFINIBAND 0x06
+#define PCI_SUBCLASS_SERIAL_IPMI 0x07
+#define PCI_IF_SERIAL_IPMI_SMIC 0x00
+#define PCI_IF_SERIAL_IPMI_KYBD 0x01
+#define PCI_IF_SERIAL_IPMI_BLOCK 0x02
+#define PCI_SUBCLASS_SERIAL_SERCOS 0x08
+#define PCI_SUBCLASS_SERIAL_CANBUS 0x09
/* 0x0d wireless controller subclasses */
#define PCI_SUBCLASS_WIRELESS_IRDA 0x00
@@ -358,6 +365,8 @@
#define PCI_SUBCLASS_WIRELESS_RF 0x10
#define PCI_SUBCLASS_WIRELESS_BLUETOOTH 0x11
#define PCI_SUBCLASS_WIRELESS_BROADBAND 0x12
+#define PCI_SUBCLASS_WIRELESS_802_11A 0x20
+#define PCI_SUBCLASS_WIRELESS_802_11B 0x21
#define PCI_SUBCLASS_WIRELESS_MISC 0x80
/* 0x0e intelligent I/O controller subclasses */
@@ -430,7 +439,7 @@
/* Pointer to first capability */
#define PCI_CAP_PTR 0x34
-/* Interrupt configration register */
+/* Interrupt configuration register */
#define PCI_INTERRUPT_REG 0x3c
#define PCI_INTERRUPT_PIN_MASK 0x0000ff00
#define PCI_INTERRUPT_PIN_EXTRACT(x) \
@@ -465,19 +474,20 @@
#define PCI_PPB_MEMLIMIT_EXTRACT(x) (((x) << 0) & 0xFFFF0000)
#define PCI_PCI_BRIDGE_CONTROL_REG 0x3E
-#define PCI_PCI_BRIDGE_PARITY_EN 0x01
-#define PCI_PCI_BRIDGE_SERR_EN 0x02
-#define PCI_PCI_BRIDGE_ISA_EN 0x04
-#define PCI_PCI_BRIDGE_VGA_EN 0x08
-#define PCI_PCI_BRIDGE_MASTER_ABORT_EN 0x20
-#define PCI_PCI_BRIDGE_SECONDARY_RESET 0x40
-#define PCI_PCI_BRIDGE_FAST_B2B_EN 0x80
+#define PCI_PCI_BRIDGE_PARITY_EN 0x0001
+#define PCI_PCI_BRIDGE_SERR_EN 0x0002
+#define PCI_PCI_BRIDGE_ISA_EN 0x0004
+#define PCI_PCI_BRIDGE_VGA_EN 0x0008
+#define PCI_PCI_BRIDGE_VGA16_EN 0x0010
+#define PCI_PCI_BRIDGE_MASTER_ABORT_EN 0x0020
+#define PCI_PCI_BRIDGE_SECONDARY_RESET 0x0040
+#define PCI_PCI_BRIDGE_FAST_B2B_EN 0x0080
/* header type 2 extensions */
-#define PCI_CB_BRIDGE_CTL_CB_RESET 0x40 /* CardBus reset */
-#define PCI_CB_BRIDGE_CTL_16BIT_INT 0x80 /* Enable interrupt for 16-bit cards */
-#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100
-#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
-#define PCI_CB_BRIDGE_CTL_POST_WRITES 0x400
+#define PCI_CB_BRIDGE_CTL_CB_RESET 0x0040 /* CardBus reset */
+#define PCI_CB_BRIDGE_CTL_16BIT_INT 0x0080 /* Enable interrupt for 16-bit cards */
+#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x0100
+#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x0200
+#define PCI_CB_BRIDGE_CTL_POST_WRITES 0x0400
#define PCI_CB_CAP_PTR 0x14
#define PCI_CB_SEC_STATUS_REG 0x16 /* Secondary status */
@@ -514,8 +524,14 @@
#define PCI_CAP_MSI_ID 0x05 /* Message Signaled Interrupts */
#define PCI_CAP_CHSWP_ID 0x06 /* CompactPCI HotSwap */
#define PCI_CAP_PCIX_ID 0x07 /* PCI-X */
+#define PCI_CAP_HT_ID 0x08 /* HyperTransport */
+#define PCI_CAP_VENDOR_ID 0x09 /* Vendor-specific */
+#define PCI_CAP_DEBUG_ID 0x0a /* Debug port */
+#define PCI_CAP_CCRC 0x0b /* CompactPCI central resource cntrl */
#define PCI_CAP_SHPC_ID 0x0c /* Standard Hot-Plug Controller */
-#define PCI_CAP_EXPRESS_ID 0x10 /* PCI Express */
+#define PCI_CAP_AGP8_ID 0x0e /* AGP 8x */
+#define PCI_CAP_SECURE_ID 0x0f /* Secure device */
+#define PCI_CAP_PCIE_ID 0x10 /* PCI Express */
#define PCI_CAP_MSIX_ID 0x11 /* MSI-X */
/* Capability header */
@@ -527,6 +543,64 @@
#define PCI_CAP_PM_CSR 0x04 /* Control & Status */
#define PCI_CAP_PM_MODE_MASK 0x03 /* Current mode (D0 to D3) */
+/* PCI-X Capability (incomplete) */
+#define PCI_CAP_PCIX_STAT 0x02 /* PCI-X status register */
+#define PCI_CAP_PCIX_STAT_MODE 0x03C0 /* Secondary mode & frequency */
+#define PCI_CAP_PCIX_STAT_PCIX2_MIN 8 /* Min. of above for PCI-X mode 2 */
+
+/* PCI Express Capability (incomplete) */
+#define PCI_CAP_PCIE_REG 0x02 /* 16 bits of R/O information */
+#define PCI_CAP_PCIE_DEVTYPE 0x00F0 /* PCI Express device type */
+#define PCI_CAP_PCIE_DEVTYPE_END 0x0 /* Endpoint with no I/O */
+#define PCI_CAP_PCIE_DEVTYPE_END_IO 0x1 /* Endpoint with I/O */
+#define PCI_CAP_PCIE_DEVTYPE_ROOT 0x4 /* Root port */
+#define PCI_CAP_PCIE_DEVTYPE_UP 0x5 /* Upstream port of switch */
+#define PCI_CAP_PCIE_DEVTYPE_DOWN 0x6 /* Downstream port of switch */
+#define PCI_CAP_PCIE_DEVTYPE_PCIE_PCI 0x7 /* PCI Express to PCI/PCI-X bridge */
+#define PCI_CAP_PCIE_DEVTYPE_PCI_PCIE 0x8 /* PCI/PCI-X to PCI Express bridge */
+#define PCI_CAP_PCIE_DEV_CAP 0x04 /* 32 more bits of R/O information */
+#define PCI_CAP_PCIE_DEV_CTL 0x08 /* Device control */
+#define PCI_CAP_PCIE_CR_EN 0x0001 /* Correctable error reporting en */
+#define PCI_CAP_PCIE_NFR_EN 0x0002 /* Non-fatal error reporting enable */
+#define PCI_CAP_PCIE_FR_EN 0x0004 /* Fatal error reporting enable */
+#define PCI_CAP_PCIE_URR_EN 0x0008 /* Unsupported request reporting en */
+
+/* PCI Express extended capability IDs */
+#define PCIE_CAP_AER_ID 0x0001 /* Advanced Error Reporting */
+#define PCIE_CAP_VC_ID 0x0002 /* Virtual Channel */
+#define PCIE_CAP_DSN_ID 0x0003 /* Device Serial Number */
+#define PCIE_CAP_PB_ID 0x0004 /* Power Budgeting */
+
+#define PCIE_CAP_HEADER 0x000 /* Capability Header */
+#define PCIE_CAP_ID 0x0000FFFF /* Capability ID */
+#define PCIE_CAP_VERSION 0x000F0000 /* Capability Version */
+#define PCIE_CAP_NEXT 0xFFF00000 /* Next capability pointer */
+
+#define PCIE_CAP_FIRST 0x100 /* First capability pointer */
+
+/* Advanced Error Reporting Capability (incomplete) */
+#define PCIE_CAP_AER_UE_STATUS 0x004 /* Uncorrectable Error status */
+#define PCIE_CAP_AER_UE_MASK 0x008 /* Uncorrectable Error mask */
+#define PCIE_CAP_AER_UE_SEV 0x00c /* Uncorrectable Error severity */
+/* The following bit valid for all three of the preceeding (incomplete) */
+#define PCIE_CAP_AER_UE_URE 0x00100000 /* Unsupported Request Error */
+#define PCIE_CAP_AER_CE_STATUS 0x010 /* Correctable Error status */
+#define PCIE_CAP_AER_CE_MASK 0x014 /* Correctable Error mask */
+#define PCIE_CAP_AER_CTL 0x018 /* AER control */
+#define PCIE_CAP_AER_HEADERLOG 0x01c /* 4 Header Log registers */
+/* These exist only in PCI Express to PCI/PCI-X bridges */
+#define PCIE_CAP_AER_SUE_STATUS 0x02c /* UE Secondary status */
+#define PCIE_CAP_AER_SUE_MASK 0x030 /* UE Secondary mask */
+#define PCIE_CAP_AER_SUE_SEV 0x034 /* UE Secondary severity */
+/* The following bits valid for all three of the preceeding (incomplete) */
+#define PCIE_CAP_AER_SUE_MA_SPLIT 0x0002 /* Master Abort on split status */
+#define PCIE_CAP_AER_SUE_MA 0x0008 /* Master Abort */
+#define PCIE_CAP_AER_SUE_SAD 0x1000 /* SERR# Assertion detected */
+#define PCIE_CAP_AER_SUE_MASTER_ABORT /* Convenience macro */ \
+ (PCIE_CAP_AER_SUE_MA | \
+ PCIE_CAP_AER_SUE_MA_SPLIT | \
+ PCIE_CAP_AER_SUE_SAD)
+
/*
* Typedefs, etc...
*/
@@ -605,7 +679,8 @@ typedef struct pci_cfg_regs {
CARD32 cg_rsrvd1; /* 0x10 */
#if X_BYTE_ORDER == X_BIG_ENDIAN
CARD16 secondary_status; /* 0x16 */
- CARD16 cg_rsrvd2; /* 0x14 */
+ CARD8 cg_rsrvd2; /* 0x15 */
+ CARD8 cg_capptr; /* 0x14 */
union {
CARD32 cg_bus_reg;
@@ -617,7 +692,8 @@ typedef struct pci_cfg_regs {
} cgbr;
} cgbr;
#else
- CARD16 cg_rsrvd2; /* 0x14 */
+ CARD8 cg_capptr; /* 0x14 */
+ CARD8 cg_rsrvd2; /* 0x15 */
CARD16 secondary_status; /* 0x16 */
union {
@@ -726,11 +802,11 @@ typedef struct pci_cfg_regs {
} b_u_io;
} uio_rom;
#if X_BYTE_ORDER == X_BIG_ENDIAN
- CARD8 capptr; /* Offset 0x34 */
CARD8 rsvd3[3]; /* Offset 0x35 - 0x37 */
+ CARD8 capptr; /* Offset 0x34 */
#else
- CARD8 rsvd3[3]; /* Offset 0x35 - 0x37 */
CARD8 capptr; /* Offset 0x34 */
+ CARD8 rsvd3[3]; /* Offset 0x35 - 0x37 */
#endif
union {
CARD32 rsvd4; /* Offset 0x38 - 0x3b */
@@ -794,6 +870,14 @@ typedef struct pci_device {
CARD32 listed_class;
pointer businfo; /* pointer to secondary's bus info structure */
Bool fakeDevice; /* Device added by system chipset support */
+ CARD16 pcie_cap_ptr; /* PCI Express capability pointer */
+ CARD16 pcie_dev_ctl; /* PCI Express device control */
+ CARD16 pcie_devtype; /* PCI Express device type */
+ CARD16 aer_cap_ptr; /* Advanced Error Reporting capability ptr */
+ CARD32 aer_ue_mask; /* Uncorrectable Error mask */
+ CARD32 aer_ue_severity; /* Uncorrectable Error severity */
+ CARD32 aer_sue_mask; /* Uncorrectable Error Secondary mask */
+ CARD32 aer_sue_severity; /* Uncorrectable Error Secondary severity */
} pciDevice, *pciConfigPtr;
typedef enum {
@@ -824,6 +908,7 @@ typedef enum {
#define pci_header_type cfgspc.regs.bhlc.bhlc.header_type
#define pci_bist cfgspc.regs.bhlc.bhlc.bist
#define pci_cb_secondary_status cfgspc.regs.cx.cg.secondary_status
+#define pci_cb_capptr cfgspc.regs.cx.cg.cg_capptr
#define pci_cb_bus_register cfgspc.regs.cx.cg.cgbr.cg_bus_reg
#define pci_cb_primary_bus_number cfgspc.regs.cx.cg.cgbr.cgbr.primary_bus_number
#define pci_cb_cardbus_bus_number cfgspc.regs.cx.cg.cgbr.cgbr.cardbus_bus_number