summaryrefslogtreecommitdiffstats
path: root/sys/i386/pci/pci_cfgreg.c
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>2000-12-08 22:11:23 +0000
committermsmith <msmith@FreeBSD.org>2000-12-08 22:11:23 +0000
commitc27f2d3c492a3d78680bb4c52f0be2c345735e1d (patch)
treeab8e18698d3c3ee4b4443c78e8ba86065bed1ff3 /sys/i386/pci/pci_cfgreg.c
parent3e12cdd63653239c3c71bf1e7042f1149134e630 (diff)
downloadFreeBSD-src-c27f2d3c492a3d78680bb4c52f0be2c345735e1d.zip
FreeBSD-src-c27f2d3c492a3d78680bb4c52f0be2c345735e1d.tar.gz
Next phase in the PCI subsystem cleanup.
- Move PCI core code to dev/pci. - Split bridge code out into separate modules. - Remove the descriptive strings from the bridge drivers. If you want to know what a device is, use pciconf. Add support for broadly identifying devices based on class/subclass, and for parsing a preloaded device identification database so that if you want to waste the memory, you can identify *anything* we know about. - Remove machine-dependant code from the core PCI code. APIC interrupt mapping is performed by shadowing the intline register in machine- dependant code. - Bring interrupt routing support to the Alpha (although many platforms don't yet support routing or mapping interrupts entirely correctly). This resulted in spamming <sys/bus.h> into more places than it really should have gone. - Put sys/dev on the kernel/modules include path. This avoids having to change *all* the pci*.h includes.
Diffstat (limited to 'sys/i386/pci/pci_cfgreg.c')
-rw-r--r--sys/i386/pci/pci_cfgreg.c54
1 files changed, 52 insertions, 2 deletions
diff --git a/sys/i386/pci/pci_cfgreg.c b/sys/i386/pci/pci_cfgreg.c
index d83591a..ef5f65b 100644
--- a/sys/i386/pci/pci_cfgreg.c
+++ b/sys/i386/pci/pci_cfgreg.c
@@ -46,6 +46,10 @@
#include <machine/segments.h>
#include <machine/pc/bios.h>
+#ifdef APIC_IO
+#include <machine/smp.h>
+#endif /* APIC_IO */
+
#include "pcib_if.h"
static int cfgmech;
@@ -112,16 +116,62 @@ pci_cfgregopen(void)
}
/*
- * Read configuration space register
+ * Read configuration space register
*/
u_int32_t
-pci_cfgregread(int bus, int slot, int func, int reg, int bytes)
+pci_do_cfgregread(int bus, int slot, int func, int reg, int bytes)
{
return(usebios ?
pcibios_cfgread(bus, slot, func, reg, bytes) :
pcireg_cfgread(bus, slot, func, reg, bytes));
}
+u_int32_t
+pci_cfgregread(int bus, int slot, int func, int reg, int bytes)
+{
+#ifdef APIC_IO
+ /*
+ * If we are using the APIC, the contents of the intline register will probably
+ * be wrong (since they are set up for use with the PIC.
+ * Rather than rewrite these registers (maybe that would be smarter) we trap
+ * attempts to read them and translate to our private vector numbers.
+ */
+ if ((reg == PCIR_INTLINE) && (bytes == 1)) {
+ int pin, line, airq;
+
+ pin = pci_do_cfgregread(bus, slot, func, PCIR_INTPIN, 1);
+ line = pci_do_cfgregread(bus, slot, func, PCIR_INTLINE, 1);
+
+ if (pin != 0) {
+ int airq;
+
+ airq = pci_apic_irq(bus, slot, pin);
+ if (airq >= 0) {
+ /* PCI specific entry found in MP table */
+ if (airq != line)
+ undirect_pci_irq(line);
+ return(airq);
+ } else {
+ /*
+ * PCI interrupts might be redirected to the
+ * ISA bus according to some MP tables. Use the
+ * same methods as used by the ISA devices
+ * devices to find the proper IOAPIC int pin.
+ */
+ airq = isa_apic_irq(line);
+ if ((airq >= 0) && (airq != line)) {
+ /* XXX: undirect_pci_irq() ? */
+ undirect_isa_irq(line);
+ return(airq);
+ }
+ }
+ }
+ return(line);
+ }
+#endif /* APIC_IO */
+ return(pci_do_cfgregread(bus, slot, func, reg, bytes));
+}
+
/*
* Write configuration space register
*/
OpenPOWER on IntegriCloud