summaryrefslogtreecommitdiff
path: root/src/arch/i386/lib/pci_ops_conf2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/i386/lib/pci_ops_conf2.c')
-rw-r--r--src/arch/i386/lib/pci_ops_conf2.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/arch/i386/lib/pci_ops_conf2.c b/src/arch/i386/lib/pci_ops_conf2.c
new file mode 100644
index 0000000000..9fa03f18a8
--- /dev/null
+++ b/src/arch/i386/lib/pci_ops_conf2.c
@@ -0,0 +1,80 @@
+#include <console/console.h>
+#include <arch/io.h>
+#include <arch/pciconf.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+/*
+ * Functions for accessing PCI configuration space with type 2 accesses
+ */
+
+#define IOADDR(devfn, where) ((0xC000 | ((devfn & 0x78) << 5)) + where)
+#define FUNC(devfn) (((devfn & 7) << 1) | 0xf0)
+#define SET(bus,devfn) outb(FUNC(devfn), 0xCF8); outb(bus, 0xCFA);
+
+static uint8_t pci_conf2_read_config8(unsigned char bus, int devfn, int where)
+{
+ uint8_t value;
+ SET(bus, devfn);
+ value = inb(IOADDR(devfn, where));
+ outb(0, 0xCF8);
+ return value;
+}
+
+static uint16_t pci_conf2_read_config16(unsigned char bus, int devfn, int where)
+{
+ uint16_t value;
+ SET(bus, devfn);
+ value = inw(IOADDR(devfn, where));
+ outb(0, 0xCF8);
+ return value;
+}
+
+static uint32_t pci_conf2_read_config32(unsigned char bus, int devfn, int where)
+{
+ uint32_t value;
+ SET(bus, devfn);
+ value = inl(IOADDR(devfn, where));
+ outb(0, 0xCF8);
+ return value;
+}
+
+static void pci_conf2_write_config8(unsigned char bus, int devfn, int where, uint8_t value)
+{
+ SET(bus, devfn);
+ outb(value, IOADDR(devfn, where));
+ outb(0, 0xCF8);
+}
+
+static void pci_conf2_write_config16(unsigned char bus, int devfn, int where, uint16_t value)
+{
+ SET(bus, devfn);
+ outw(value, IOADDR(devfn, where));
+ outb(0, 0xCF8);
+}
+
+static void pci_conf2_write_config32(unsigned char bus, int devfn, int where, uint32_t value)
+{
+ SET(bus, devfn);
+ outl(value, IOADDR(devfn, where));
+ outb(0, 0xCF8);
+}
+
+#undef SET
+#undef IOADDR
+#undef FUNC
+
+static const struct pci_ops pci_direct_conf2 =
+{
+ .read8 = pci_conf2_read_config8,
+ .read16 = pci_conf2_read_config16,
+ .read32 = pci_conf2_read_config32,
+ .write8 = pci_conf2_write_config8,
+ .write16 = pci_conf2_write_config16,
+ .write32 = pci_conf2_write_config32,
+};
+
+void pci_set_method_conf2(void)
+{
+ conf = &pci_direct_conf2;
+}