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 | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/pci.h | 4 ++++ 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), ®32); + void *flatptr = MAKE_FLATPTR(GET_SEG(SS), ®32); + call32(pci_writel_32, (u32)flatptr, -1); + } else { + pci_writel_32(®32); + } +} 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);