aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2010-11-29 09:42:10 +0100
committerKevin O'Connor <kevin@koconnor.net>2010-12-05 12:23:22 -0500
commitf1f18ebd0336f8e7920bf70b2b20afacfe9265d9 (patch)
treef1694a4856288ef13755a0cdbd62b3d8f5ef0a3f
parentaf9629be3aeb3952ff432cf009394f10727ee0e8 (diff)
downloadseabios-f1f18ebd0336f8e7920bf70b2b20afacfe9265d9.tar.gz
pci: add helper functions for mmio bar access from real mode.
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>
-rw-r--r--src/pci.c51
-rw-r--r--src/pci.h4
2 files changed, 55 insertions, 0 deletions
diff --git a/src/pci.c b/src/pci.c
index 115689d..e43c83a 100644
--- 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);
+ }
+}
diff --git a/src/pci.h b/src/pci.h
index 64bd43b..46af207 100644
--- 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);