pci: add helper functions for mmio bar access from real mode.
authorGerd Hoffmann <kraxel@redhat.com>
Mon, 29 Nov 2010 08:42:10 +0000 (09:42 +0100)
committerKevin O'Connor <kevin@koconnor.net>
Sun, 5 Dec 2010 17:23:22 +0000 (12:23 -0500)
This patch adds helper pci_readl and pci_writel which can be used
to access pci mmio bars from real mode.  They work in 32bit mode
too.  ahci support needs this, also ohci for bulk transfers, and
probably more devices in the future.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
src/pci.c
src/pci.h

index 115689d0cee6d94317fa39fcc4e0115f69ea0f80..e43c83a9696e47a6d81720d61849e2738d86276d 100644 (file)
--- a/src/pci.c
+++ b/src/pci.c
@@ -9,6 +9,7 @@
 #include "ioport.h" // outl
 #include "util.h" // dprintf
 #include "config.h" // CONFIG_*
+#include "farptr.h" // CONFIG_*
 #include "pci_regs.h" // PCI_VENDOR_ID
 #include "pci_ids.h" // PCI_CLASS_DISPLAY_VGA
 
@@ -225,3 +226,53 @@ pci_reboot(void)
     outb(v|6, PORT_PCI_REBOOT); /* Actually do the reset */
     udelay(50);
 }
+
+// helper functions to access pci mmio bars from real mode
+
+extern u32 pci_readl_32(u32 addr);
+#if MODESEGMENT == 0
+u32 VISIBLE32FLAT
+pci_readl_32(u32 addr)
+{
+    dprintf(3, "32: pci read : %x\n", addr);
+    return readl((void*)addr);
+}
+#endif
+
+u32 pci_readl(u32 addr)
+{
+    if (MODESEGMENT) {
+        dprintf(3, "16: pci read : %x\n", addr);
+        return call32(pci_readl_32, addr, -1);
+    } else {
+        return pci_readl_32(addr);
+    }
+}
+
+struct reg32 {
+    u32 addr;
+    u32 data;
+};
+
+extern void pci_writel_32(struct reg32 *reg32);
+#if MODESEGMENT == 0
+void VISIBLE32FLAT
+pci_writel_32(struct reg32 *reg32)
+{
+    dprintf(3, "32: pci write: %x, %x (%p)\n", reg32->addr, reg32->data, reg32);
+    writel((void*)(reg32->addr), reg32->data);
+}
+#endif
+
+void pci_writel(u32 addr, u32 val)
+{
+    struct reg32 reg32 = { .addr = addr, .data = val };
+    if (MODESEGMENT) {
+        dprintf(3, "16: pci write: %x, %x (%x:%p)\n",
+                reg32.addr, reg32.data, GET_SEG(SS), &reg32);
+        void *flatptr = MAKE_FLATPTR(GET_SEG(SS), &reg32);
+        call32(pci_writel_32, (u32)flatptr, -1);
+    } else {
+        pci_writel_32(&reg32);
+    }
+}
index 64bd43b53774a57b611f6d019ed9a94b574c1b4c..46af207fa906973dbf85cc88d2f4fb1ac646336b 100644 (file)
--- a/src/pci.h
+++ b/src/pci.h
@@ -96,6 +96,10 @@ int pci_init_device(const struct pci_device_id *table, u16 bdf, void *arg);
 int pci_find_init_device(const struct pci_device_id *ids, void *arg);
 void pci_reboot(void);
 
+// helper functions to access pci mmio bars from real mode
+u32 pci_readl(u32 addr);
+void pci_writel(u32 addr, u32 val);
+
 // pirtable.c
 void create_pirtable(void);