Split pci.c into pci.c and pcidevice.c. The low-level code that interacts directly with the PCI devices remains in pci.c, while functions dealing with the higher level pci_device cache move to pcidevice.c. Only pci.c is needed in 16bit mode.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- Makefile | 2 +- src/boot.c | 1 + src/fw/acpi.c | 2 +- src/fw/coreboot.c | 2 +- src/fw/csm.c | 3 +- src/fw/mptable.c | 5 +- src/fw/paravirt.c | 3 +- src/fw/pciinit.c | 1 + src/fw/smm.c | 1 + src/hw/ahci.c | 3 +- src/hw/ata.c | 3 +- src/hw/esp-scsi.c | 2 +- src/hw/floppy.c | 2 +- src/hw/lsi-scsi.c | 2 +- src/hw/megasas.c | 3 +- src/hw/pci.c | 213 +----------------------------------------- src/hw/pci.h | 89 ++---------------- src/hw/{pci.c => pcidevice.c} | 105 +-------------------- src/hw/{pci.h => pcidevice.h} | 56 ++--------- src/hw/pvscsi.c | 2 +- src/hw/sdcard.c | 2 +- src/hw/usb-ehci.c | 2 +- src/hw/usb-ohci.c | 2 +- src/hw/usb-uhci.c | 3 +- src/hw/usb-xhci.c | 2 +- src/hw/virtio-blk.c | 2 +- src/hw/virtio-pci.c | 1 + src/hw/virtio-scsi.c | 2 +- src/optionroms.c | 3 +- src/output.c | 1 + src/pcibios.c | 1 + src/vgahooks.c | 3 +- 32 files changed, 59 insertions(+), 465 deletions(-) copy src/hw/{pci.c => pcidevice.c} (72%) copy src/hw/{pci.h => pcidevice.h} (65%)
diff --git a/Makefile b/Makefile index cbe9454..b0eb239 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ SRCBOTH=misc.c stacks.c output.c string.c block.c cdrom.c disk.c mouse.c kbd.c \ SRC16=$(SRCBOTH) SRC32FLAT=$(SRCBOTH) post.c e820map.c malloc.c romfile.c x86.c optionroms.c \ pmm.c font.c boot.c bootsplash.c jpeg.c bmp.c tcgbios.c sha1.c \ - hw/ahci.c hw/pvscsi.c hw/usb-xhci.c hw/usb-hub.c hw/sdcard.c \ + hw/pcidevice.c hw/ahci.c hw/pvscsi.c hw/usb-xhci.c hw/usb-hub.c hw/sdcard.c \ fw/coreboot.c fw/lzmadecode.c fw/multiboot.c fw/csm.c fw/biostables.c \ fw/paravirt.c fw/shadow.c fw/pciinit.c fw/smm.c fw/smp.c fw/mtrr.c fw/xen.c \ fw/acpi.c fw/mptable.c fw/pirtable.c fw/smbios.c fw/romfile_loader.c \ diff --git a/src/boot.c b/src/boot.c index a045a8e..706b7df 100644 --- a/src/boot.c +++ b/src/boot.c @@ -10,6 +10,7 @@ #include "config.h" // CONFIG_* #include "fw/paravirt.h" // qemu_cfg_show_boot_menu #include "hw/pci.h" // pci_bdf_to_* +#include "hw/pcidevice.h" // struct pci_device #include "hw/rtc.h" // rtc_read #include "hw/usb.h" // struct usbdevice_s #include "list.h" // hlist_node diff --git a/src/fw/acpi.c b/src/fw/acpi.c index b805b44..8bc2ca6 100644 --- a/src/fw/acpi.c +++ b/src/fw/acpi.c @@ -10,7 +10,7 @@ #include "config.h" // CONFIG_* #include "dev-q35.h" #include "dev-piix.h" -#include "hw/pci.h" // pci_find_init_device +#include "hw/pcidevice.h" // pci_find_init_device #include "hw/pci_ids.h" // PCI_VENDOR_ID_INTEL #include "hw/pci_regs.h" // PCI_INTERRUPT_LINE #include "malloc.h" // free diff --git a/src/fw/coreboot.c b/src/fw/coreboot.c index 4fe1292..4957b80 100644 --- a/src/fw/coreboot.c +++ b/src/fw/coreboot.c @@ -8,7 +8,7 @@ #include "byteorder.h" // be32_to_cpu #include "config.h" // CONFIG_* #include "e820map.h" // e820_add -#include "hw/pci.h" // pci_probe_devices +#include "hw/pcidevice.h" // pci_probe_devices #include "lzmadecode.h" // LzmaDecode #include "malloc.h" // free #include "output.h" // dprintf diff --git a/src/fw/csm.c b/src/fw/csm.c index b01f181..03b4bb8 100644 --- a/src/fw/csm.c +++ b/src/fw/csm.c @@ -8,7 +8,8 @@ #include "config.h" // CONFIG_* #include "e820map.h" // e820_add #include "farptr.h" // MAKE_FLATPTR -#include "hw/pci.h" // pci_probe_devices +#include "hw/pci.h" // pci_to_bdf +#include "hw/pcidevice.h" // pci_probe_devices #include "hw/pic.h" // pic_irqmask_read #include "malloc.h" // malloc_csm_preinit #include "memmap.h" // SYMBOL diff --git a/src/fw/mptable.c b/src/fw/mptable.c index 8e01e00..47385cc 100644 --- a/src/fw/mptable.c +++ b/src/fw/mptable.c @@ -7,8 +7,9 @@ // This file may be distributed under the terms of the GNU LGPLv3 license.
#include "config.h" // CONFIG_* -#include "hw/pci.h" -#include "hw/pci_regs.h" +#include "hw/pci.h" // pci_bdf_to_bus +#include "hw/pcidevice.h" // foreachpci +#include "hw/pci_regs.h" // PCI_INTERRUPT_PIN #include "malloc.h" // free #include "output.h" // dprintf #include "romfile.h" // romfile_loadint diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c index 3fae13a..8ed4380 100644 --- a/src/fw/paravirt.c +++ b/src/fw/paravirt.c @@ -11,7 +11,8 @@ #include "byteorder.h" // be32_to_cpu #include "config.h" // CONFIG_QEMU #include "e820map.h" // e820_add -#include "hw/pci.h" // create_pirtable +#include "hw/pci.h" // pci_config_readw +#include "hw/pcidevice.h" // pci_probe_devices #include "hw/pci_regs.h" // PCI_DEVICE_ID #include "hw/rtc.h" // CMOS_* #include "malloc.h" // malloc_tmp diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index ead2c1a..0ed5dfb 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -12,6 +12,7 @@ #include "e820map.h" // e820_add #include "hw/ata.h" // PORT_ATA1_CMD_BASE #include "hw/pci.h" // pci_config_readl +#include "hw/pcidevice.h" // pci_probe_devices #include "hw/pci_ids.h" // PCI_VENDOR_ID_INTEL #include "hw/pci_regs.h" // PCI_COMMAND #include "list.h" // struct hlist_node diff --git a/src/fw/smm.c b/src/fw/smm.c index 8f042ee..95f6ba7 100644 --- a/src/fw/smm.c +++ b/src/fw/smm.c @@ -9,6 +9,7 @@ #include "dev-q35.h" #include "dev-piix.h" #include "hw/pci.h" // pci_config_writel +#include "hw/pcidevice.h" // pci_find_device #include "hw/pci_ids.h" // PCI_VENDOR_ID_INTEL #include "hw/pci_regs.h" // PCI_DEVICE_ID #include "output.h" // dprintf diff --git a/src/hw/ahci.c b/src/hw/ahci.c index bd21bf6..9310850 100644 --- a/src/hw/ahci.c +++ b/src/hw/ahci.c @@ -10,7 +10,8 @@ #include "blockcmd.h" // CDB_CMD_READ_10 #include "malloc.h" // free #include "output.h" // dprintf -#include "pci.h" // foreachpci +#include "pci.h" // pci_config_readb +#include "pcidevice.h" // foreachpci #include "pci_ids.h" // PCI_CLASS_STORAGE_OTHER #include "pci_regs.h" // PCI_INTERRUPT_LINE #include "stacks.h" // yield diff --git a/src/hw/ata.c b/src/hw/ata.c index 12dab96..9a4b435 100644 --- a/src/hw/ata.c +++ b/src/hw/ata.c @@ -12,7 +12,8 @@ #include "byteorder.h" // be16_to_cpu #include "malloc.h" // malloc_fseg #include "output.h" // dprintf -#include "pci.h" // foreachpci +#include "pci.h" // pci_config_readb +#include "pcidevice.h" // foreachpci #include "pci_ids.h" // PCI_CLASS_STORAGE_OTHER #include "pci_regs.h" // PCI_INTERRUPT_LINE #include "pic.h" // enable_hwirq diff --git a/src/hw/esp-scsi.c b/src/hw/esp-scsi.c index 9abc361..086a032 100644 --- a/src/hw/esp-scsi.c +++ b/src/hw/esp-scsi.c @@ -17,7 +17,7 @@ #include "fw/paravirt.h" // runningOnQEMU #include "malloc.h" // free #include "output.h" // dprintf -#include "pci.h" // foreachpci +#include "pcidevice.h" // foreachpci #include "pci_ids.h" // PCI_DEVICE_ID #include "pci_regs.h" // PCI_VENDOR_ID #include "std/disk.h" // DISK_RET_SUCCESS diff --git a/src/hw/floppy.c b/src/hw/floppy.c index a14f7e0..98ed9bb 100644 --- a/src/hw/floppy.c +++ b/src/hw/floppy.c @@ -11,7 +11,7 @@ #include "config.h" // CONFIG_FLOPPY #include "malloc.h" // malloc_fseg #include "output.h" // dprintf -#include "pci.h" // pci_to_bdf +#include "pcidevice.h" // pci_find_class #include "pci_ids.h" // PCI_CLASS_BRIDGE_ISA #include "pic.h" // pic_eoi1 #include "romfile.h" // romfile_loadint diff --git a/src/hw/lsi-scsi.c b/src/hw/lsi-scsi.c index 5d872a2..564c9f1 100644 --- a/src/hw/lsi-scsi.c +++ b/src/hw/lsi-scsi.c @@ -17,7 +17,7 @@ #include "fw/paravirt.h" // runningOnQEMU #include "malloc.h" // free #include "output.h" // dprintf -#include "pci.h" // foreachpci +#include "pcidevice.h" // foreachpci #include "pci_ids.h" // PCI_DEVICE_ID_VIRTIO_BLK #include "pci_regs.h" // PCI_VENDOR_ID #include "std/disk.h" // DISK_RET_SUCCESS diff --git a/src/hw/megasas.c b/src/hw/megasas.c index 71af3c3..2ee457b 100644 --- a/src/hw/megasas.c +++ b/src/hw/megasas.c @@ -16,7 +16,8 @@ #include "config.h" // CONFIG_* #include "malloc.h" // free #include "output.h" // dprintf -#include "pci.h" // foreachpci +#include "pci.h" // pci_config_readl +#include "pcidevice.h" // foreachpci #include "pci_ids.h" // PCI_DEVICE_ID_XXX #include "pci_regs.h" // PCI_VENDOR_ID #include "stacks.h" // yield diff --git a/src/hw/pci.c b/src/hw/pci.c index dcf240c..506ee56 100644 --- a/src/hw/pci.c +++ b/src/hw/pci.c @@ -5,16 +5,16 @@ // // This file may be distributed under the terms of the GNU LGPLv3 license.
-#include "malloc.h" // malloc_tmp #include "output.h" // dprintf #include "pci.h" // pci_config_writel #include "pci_regs.h" // PCI_VENDOR_ID -#include "romfile.h" // romfile_loadint -#include "stacks.h" // wait_preempt -#include "string.h" // memset #include "util.h" // udelay #include "x86.h" // outl
+#define PORT_PCI_CMD 0x0cf8 +#define PORT_PCI_REBOOT 0x0cf9 +#define PORT_PCI_DATA 0x0cfc + void pci_config_writel(u16 bdf, u32 addr, u32 val) { outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD); @@ -87,9 +87,6 @@ pci_next(int bdf, int bus) } }
-struct hlist_head PCIDevices VARVERIFY32INIT; -int MaxPCIBus VARFSEG; - // Check if PCI is available at all int pci_probe_host(void) @@ -102,208 +99,6 @@ pci_probe_host(void) return 0; }
-// Find all PCI devices and populate PCIDevices linked list. -void -pci_probe_devices(void) -{ - dprintf(3, "PCI probe\n"); - struct pci_device *busdevs[256]; - memset(busdevs, 0, sizeof(busdevs)); - struct hlist_node **pprev = &PCIDevices.first; - int extraroots = romfile_loadint("etc/extra-pci-roots", 0); - int bus = -1, lastbus = 0, rootbuses = 0, count=0; - while (bus < 0xff && (bus < MaxPCIBus || rootbuses < extraroots)) { - bus++; - int bdf; - foreachbdf(bdf, bus) { - // Create new pci_device struct and add to list. - struct pci_device *dev = malloc_tmp(sizeof(*dev)); - if (!dev) { - warn_noalloc(); - return; - } - memset(dev, 0, sizeof(*dev)); - hlist_add(&dev->node, pprev); - pprev = &dev->node.next; - count++; - - // Find parent device. - int rootbus; - struct pci_device *parent = busdevs[bus]; - if (!parent) { - if (bus != lastbus) - rootbuses++; - lastbus = bus; - rootbus = rootbuses; - if (bus > MaxPCIBus) - MaxPCIBus = bus; - } else { - rootbus = parent->rootbus; - } - - // Populate pci_device info. - dev->bdf = bdf; - dev->parent = parent; - dev->rootbus = rootbus; - u32 vendev = pci_config_readl(bdf, PCI_VENDOR_ID); - dev->vendor = vendev & 0xffff; - dev->device = vendev >> 16; - u32 classrev = pci_config_readl(bdf, PCI_CLASS_REVISION); - dev->class = classrev >> 16; - dev->prog_if = classrev >> 8; - dev->revision = classrev & 0xff; - dev->header_type = pci_config_readb(bdf, PCI_HEADER_TYPE); - u8 v = dev->header_type & 0x7f; - if (v == PCI_HEADER_TYPE_BRIDGE || v == PCI_HEADER_TYPE_CARDBUS) { - u8 secbus = pci_config_readb(bdf, PCI_SECONDARY_BUS); - dev->secondary_bus = secbus; - if (secbus > bus && !busdevs[secbus]) - busdevs[secbus] = dev; - if (secbus > MaxPCIBus) - MaxPCIBus = secbus; - } - dprintf(4, "PCI device %pP (vd=%04x:%04x c=%04x)\n" - , dev, dev->vendor, dev->device, dev->class); - } - } - dprintf(1, "Found %d PCI devices (max PCI bus is %02x)\n", count, MaxPCIBus); -} - -// Search for a device with the specified vendor and device ids. -struct pci_device * -pci_find_device(u16 vendid, u16 devid) -{ - struct pci_device *pci; - foreachpci(pci) { - if (pci->vendor == vendid && pci->device == devid) - return pci; - } - return NULL; -} - -// Search for a device with the specified class id. -struct pci_device * -pci_find_class(u16 classid) -{ - struct pci_device *pci; - foreachpci(pci) { - if (pci->class == classid) - return pci; - } - return NULL; -} - -int pci_init_device(const struct pci_device_id *ids - , struct pci_device *pci, void *arg) -{ - while (ids->vendid || ids->class_mask) { - if ((ids->vendid == PCI_ANY_ID || ids->vendid == pci->vendor) && - (ids->devid == PCI_ANY_ID || ids->devid == pci->device) && - !((ids->class ^ pci->class) & ids->class_mask)) { - if (ids->func) - ids->func(pci, arg); - return 0; - } - ids++; - } - return -1; -} - -struct pci_device * -pci_find_init_device(const struct pci_device_id *ids, void *arg) -{ - struct pci_device *pci; - foreachpci(pci) { - if (pci_init_device(ids, pci, arg) == 0) - return pci; - } - return NULL; -} - -u8 pci_find_capability(struct pci_device *pci, u8 cap_id, u8 cap) -{ - int i; - u16 status = pci_config_readw(pci->bdf, PCI_STATUS); - - if (!(status & PCI_STATUS_CAP_LIST)) - return 0; - - if (cap == 0) { - /* find first */ - cap = pci_config_readb(pci->bdf, PCI_CAPABILITY_LIST); - } else { - /* find next */ - cap = pci_config_readb(pci->bdf, cap + PCI_CAP_LIST_NEXT); - } - for (i = 0; cap && i <= 0xff; i++) { - if (pci_config_readb(pci->bdf, cap + PCI_CAP_LIST_ID) == cap_id) - return cap; - cap = pci_config_readb(pci->bdf, cap + PCI_CAP_LIST_NEXT); - } - - return 0; -} - -// Enable PCI bus-mastering (ie, DMA) support on a pci device -void -pci_enable_busmaster(struct pci_device *pci) -{ - ASSERT32FLAT(); - wait_preempt(); - pci_config_maskw(pci->bdf, PCI_COMMAND, 0, PCI_COMMAND_MASTER); - pci->have_driver = 1; -} - -// Verify an IO bar and return it to the caller -u16 -pci_enable_iobar(struct pci_device *pci, u32 addr) -{ - ASSERT32FLAT(); - wait_preempt(); - u32 bar = pci_config_readl(pci->bdf, addr); - if (!(bar & PCI_BASE_ADDRESS_SPACE_IO)) { - warn_internalerror(); - return 0; - } - bar &= PCI_BASE_ADDRESS_IO_MASK; - if (bar == 0 || bar > 0xffff) { - warn_internalerror(); - return 0; - } - pci_config_maskw(pci->bdf, PCI_COMMAND, 0, PCI_COMMAND_IO); - pci->have_driver = 1; - return bar; -} - -// Verify a memory bar and return it to the caller -void * -pci_enable_membar(struct pci_device *pci, u32 addr) -{ - ASSERT32FLAT(); - wait_preempt(); - u32 bar = pci_config_readl(pci->bdf, addr); - if (bar & PCI_BASE_ADDRESS_SPACE_IO) { - warn_internalerror(); - return NULL; - } - if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) { - u32 high = pci_config_readl(pci->bdf, addr+4); - if (high) { - dprintf(1, "Can not map memory bar over 4Gig\n"); - return NULL; - } - } - bar &= PCI_BASE_ADDRESS_MEM_MASK; - if (bar + 4*1024*1024 < 20*1024*1024) { - // Bar doesn't look valid (it is in last 4M or first 16M) - warn_internalerror(); - return NULL; - } - pci_config_maskw(pci->bdf, PCI_COMMAND, 0, PCI_COMMAND_MEMORY); - pci->have_driver = 1; - return (void*)bar; -} - void pci_reboot(void) { diff --git a/src/hw/pci.h b/src/hw/pci.h index 61eb1f3..bf50430 100644 --- a/src/hw/pci.h +++ b/src/hw/pci.h @@ -2,11 +2,6 @@ #define __PCI_H
#include "types.h" // u32 -#include "list.h" // hlist_node - -#define PORT_PCI_CMD 0x0cf8 -#define PORT_PCI_REBOOT 0x0cf9 -#define PORT_PCI_DATA 0x0cfc
static inline u8 pci_bdf_to_bus(u16 bdf) { return bdf >> 8; @@ -30,6 +25,11 @@ static inline u16 pci_bus_devfn_to_bdf(int bus, u16 devfn) { return (bus << 8) | devfn; }
+#define foreachbdf(BDF, BUS) \ + for (BDF=pci_next(pci_bus_devfn_to_bdf((BUS), 0)-1, (BUS)) \ + ; BDF >= 0 \ + ; BDF=pci_next(BDF, (BUS))) + void pci_config_writel(u16 bdf, u32 addr, u32 val); void pci_config_writew(u16 bdf, u32 addr, u16 val); void pci_config_writeb(u16 bdf, u32 addr, u8 val); @@ -37,83 +37,8 @@ u32 pci_config_readl(u16 bdf, u32 addr); u16 pci_config_readw(u16 bdf, u32 addr); u8 pci_config_readb(u16 bdf, u32 addr); void pci_config_maskw(u16 bdf, u32 addr, u16 off, u16 on); - -struct pci_device *pci_find_device(u16 vendid, u16 devid); -struct pci_device *pci_find_class(u16 classid); - -struct pci_device { - u16 bdf; - u8 rootbus; - struct hlist_node node; - struct pci_device *parent; - - // Configuration space device information - u16 vendor, device; - u16 class; - u8 prog_if, revision; - u8 header_type; - u8 secondary_bus; - - // Local information on device. - int have_driver; -}; -extern struct hlist_head PCIDevices; -extern int MaxPCIBus; -int pci_probe_host(void); -void pci_probe_devices(void); -static inline u32 pci_classprog(struct pci_device *pci) { - return (pci->class << 8) | pci->prog_if; -} - -#define foreachpci(PCI) \ - hlist_for_each_entry(PCI, &PCIDevices, node) - int pci_next(int bdf, int bus); -#define foreachbdf(BDF, BUS) \ - for (BDF=pci_next(pci_bus_devfn_to_bdf((BUS), 0)-1, (BUS)) \ - ; BDF >= 0 \ - ; BDF=pci_next(BDF, (BUS))) - -#define PCI_ANY_ID (~0) -struct pci_device_id { - u32 vendid; - u32 devid; - u32 class; - u32 class_mask; - void (*func)(struct pci_device *pci, void *arg); -}; - -#define PCI_DEVICE(vendor_id, device_id, init_func) \ - { \ - .vendid = (vendor_id), \ - .devid = (device_id), \ - .class = PCI_ANY_ID, \ - .class_mask = 0, \ - .func = (init_func) \ - } - -#define PCI_DEVICE_CLASS(vendor_id, device_id, class_code, init_func) \ - { \ - .vendid = (vendor_id), \ - .devid = (device_id), \ - .class = (class_code), \ - .class_mask = ~0, \ - .func = (init_func) \ - } - -#define PCI_DEVICE_END \ - { \ - .vendid = 0, \ - } - -int pci_init_device(const struct pci_device_id *ids - , struct pci_device *pci, void *arg); -struct pci_device *pci_find_init_device(const struct pci_device_id *ids - , void *arg); -u8 pci_find_capability(struct pci_device *pci, u8 cap_id, u8 cap); -void pci_enable_busmaster(struct pci_device *pci); -u16 pci_enable_iobar(struct pci_device *pci, u32 addr); -void *pci_enable_membar(struct pci_device *pci, u32 addr); +int pci_probe_host(void); void pci_reboot(void);
-#endif +#endif // pci.h diff --git a/src/hw/pci.c b/src/hw/pcidevice.c similarity index 72% copy from src/hw/pci.c copy to src/hw/pcidevice.c index dcf240c..cfebf66 100644 --- a/src/hw/pci.c +++ b/src/hw/pcidevice.c @@ -1,107 +1,21 @@ -// PCI config space access functions. +// Code to maintain and access the pci_device cache // -// Copyright (C) 2008 Kevin O'Connor kevin@koconnor.net -// Copyright (C) 2002 MandrakeSoft S.A. +// Copyright (C) 2008-2016 Kevin O'Connor kevin@koconnor.net // // This file may be distributed under the terms of the GNU LGPLv3 license.
#include "malloc.h" // malloc_tmp #include "output.h" // dprintf #include "pci.h" // pci_config_writel +#include "pcidevice.h" // pci_probe_devices #include "pci_regs.h" // PCI_VENDOR_ID #include "romfile.h" // romfile_loadint #include "stacks.h" // wait_preempt #include "string.h" // memset -#include "util.h" // udelay -#include "x86.h" // outl - -void pci_config_writel(u16 bdf, u32 addr, u32 val) -{ - outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD); - outl(val, PORT_PCI_DATA); -} - -void pci_config_writew(u16 bdf, u32 addr, u16 val) -{ - outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD); - outw(val, PORT_PCI_DATA + (addr & 2)); -} - -void pci_config_writeb(u16 bdf, u32 addr, u8 val) -{ - outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD); - outb(val, PORT_PCI_DATA + (addr & 3)); -} - -u32 pci_config_readl(u16 bdf, u32 addr) -{ - outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD); - return inl(PORT_PCI_DATA); -} - -u16 pci_config_readw(u16 bdf, u32 addr) -{ - outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD); - return inw(PORT_PCI_DATA + (addr & 2)); -} - -u8 pci_config_readb(u16 bdf, u32 addr) -{ - outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD); - return inb(PORT_PCI_DATA + (addr & 3)); -} - -void -pci_config_maskw(u16 bdf, u32 addr, u16 off, u16 on) -{ - u16 val = pci_config_readw(bdf, addr); - val = (val & ~off) | on; - pci_config_writew(bdf, addr, val); -} - -// Helper function for foreachbdf() macro - return next device -int -pci_next(int bdf, int bus) -{ - if (pci_bdf_to_fn(bdf) == 0 - && (pci_config_readb(bdf, PCI_HEADER_TYPE) & 0x80) == 0) - // Last found device wasn't a multi-function device - skip to - // the next device. - bdf += 8; - else - bdf += 1; - - for (;;) { - if (pci_bdf_to_bus(bdf) != bus) - return -1; - - u16 v = pci_config_readw(bdf, PCI_VENDOR_ID); - if (v != 0x0000 && v != 0xffff) - // Device is present. - return bdf; - - if (pci_bdf_to_fn(bdf) == 0) - bdf += 8; - else - bdf += 1; - } -}
struct hlist_head PCIDevices VARVERIFY32INIT; int MaxPCIBus VARFSEG;
-// Check if PCI is available at all -int -pci_probe_host(void) -{ - outl(0x80000000, PORT_PCI_CMD); - if (inl(PORT_PCI_CMD) != 0x80000000) { - dprintf(1, "Detected non-PCI system\n"); - return -1; - } - return 0; -} - // Find all PCI devices and populate PCIDevices linked list. void pci_probe_devices(void) @@ -248,7 +162,6 @@ u8 pci_find_capability(struct pci_device *pci, u8 cap_id, u8 cap) void pci_enable_busmaster(struct pci_device *pci) { - ASSERT32FLAT(); wait_preempt(); pci_config_maskw(pci->bdf, PCI_COMMAND, 0, PCI_COMMAND_MASTER); pci->have_driver = 1; @@ -258,7 +171,6 @@ pci_enable_busmaster(struct pci_device *pci) u16 pci_enable_iobar(struct pci_device *pci, u32 addr) { - ASSERT32FLAT(); wait_preempt(); u32 bar = pci_config_readl(pci->bdf, addr); if (!(bar & PCI_BASE_ADDRESS_SPACE_IO)) { @@ -279,7 +191,6 @@ pci_enable_iobar(struct pci_device *pci, u32 addr) void * pci_enable_membar(struct pci_device *pci, u32 addr) { - ASSERT32FLAT(); wait_preempt(); u32 bar = pci_config_readl(pci->bdf, addr); if (bar & PCI_BASE_ADDRESS_SPACE_IO) { @@ -303,13 +214,3 @@ pci_enable_membar(struct pci_device *pci, u32 addr) pci->have_driver = 1; return (void*)bar; } - -void -pci_reboot(void) -{ - u8 v = inb(PORT_PCI_REBOOT) & ~6; - outb(v|2, PORT_PCI_REBOOT); /* Request hard reset */ - udelay(50); - outb(v|6, PORT_PCI_REBOOT); /* Actually do the reset */ - udelay(50); -} diff --git a/src/hw/pci.h b/src/hw/pcidevice.h similarity index 65% copy from src/hw/pci.h copy to src/hw/pcidevice.h index 61eb1f3..354b549 100644 --- a/src/hw/pci.h +++ b/src/hw/pcidevice.h @@ -1,46 +1,9 @@ -#ifndef __PCI_H -#define __PCI_H +#ifndef __PCIDEVICE_H +#define __PCIDEVICE_H
#include "types.h" // u32 #include "list.h" // hlist_node
-#define PORT_PCI_CMD 0x0cf8 -#define PORT_PCI_REBOOT 0x0cf9 -#define PORT_PCI_DATA 0x0cfc - -static inline u8 pci_bdf_to_bus(u16 bdf) { - return bdf >> 8; -} -static inline u8 pci_bdf_to_devfn(u16 bdf) { - return bdf & 0xff; -} -static inline u16 pci_bdf_to_busdev(u16 bdf) { - return bdf & ~0x07; -} -static inline u8 pci_bdf_to_dev(u16 bdf) { - return (bdf >> 3) & 0x1f; -} -static inline u8 pci_bdf_to_fn(u16 bdf) { - return bdf & 0x07; -} -static inline u16 pci_to_bdf(int bus, int dev, int fn) { - return (bus<<8) | (dev<<3) | fn; -} -static inline u16 pci_bus_devfn_to_bdf(int bus, u16 devfn) { - return (bus << 8) | devfn; -} - -void pci_config_writel(u16 bdf, u32 addr, u32 val); -void pci_config_writew(u16 bdf, u32 addr, u16 val); -void pci_config_writeb(u16 bdf, u32 addr, u8 val); -u32 pci_config_readl(u16 bdf, u32 addr); -u16 pci_config_readw(u16 bdf, u32 addr); -u8 pci_config_readb(u16 bdf, u32 addr); -void pci_config_maskw(u16 bdf, u32 addr, u16 off, u16 on); - -struct pci_device *pci_find_device(u16 vendid, u16 devid); -struct pci_device *pci_find_class(u16 classid); - struct pci_device { u16 bdf; u8 rootbus; @@ -59,8 +22,7 @@ struct pci_device { }; extern struct hlist_head PCIDevices; extern int MaxPCIBus; -int pci_probe_host(void); -void pci_probe_devices(void); + static inline u32 pci_classprog(struct pci_device *pci) { return (pci->class << 8) | pci->prog_if; } @@ -68,12 +30,6 @@ static inline u32 pci_classprog(struct pci_device *pci) { #define foreachpci(PCI) \ hlist_for_each_entry(PCI, &PCIDevices, node)
-int pci_next(int bdf, int bus); -#define foreachbdf(BDF, BUS) \ - for (BDF=pci_next(pci_bus_devfn_to_bdf((BUS), 0)-1, (BUS)) \ - ; BDF >= 0 \ - ; BDF=pci_next(BDF, (BUS))) - #define PCI_ANY_ID (~0) struct pci_device_id { u32 vendid; @@ -106,6 +62,9 @@ struct pci_device_id { .vendid = 0, \ }
+void pci_probe_devices(void); +struct pci_device *pci_find_device(u16 vendid, u16 devid); +struct pci_device *pci_find_class(u16 classid); int pci_init_device(const struct pci_device_id *ids , struct pci_device *pci, void *arg); struct pci_device *pci_find_init_device(const struct pci_device_id *ids @@ -114,6 +73,5 @@ u8 pci_find_capability(struct pci_device *pci, u8 cap_id, u8 cap); void pci_enable_busmaster(struct pci_device *pci); u16 pci_enable_iobar(struct pci_device *pci, u32 addr); void *pci_enable_membar(struct pci_device *pci, u32 addr); -void pci_reboot(void);
-#endif +#endif // pcidevice.h diff --git a/src/hw/pvscsi.c b/src/hw/pvscsi.c index b1dd03f..e1685b3 100644 --- a/src/hw/pvscsi.c +++ b/src/hw/pvscsi.c @@ -13,7 +13,7 @@ #include "malloc.h" // free #include "memmap.h" // PAGE_SHIFT, virt_to_phys #include "output.h" // dprintf -#include "pci.h" // foreachpci +#include "pcidevice.h" // foreachpci #include "pci_ids.h" // PCI_DEVICE_ID_VMWARE_PVSCSI #include "pci_regs.h" // PCI_VENDOR_ID #include "pvscsi.h" // pvscsi_setup diff --git a/src/hw/sdcard.c b/src/hw/sdcard.c index 1524b51..7e0875f 100644 --- a/src/hw/sdcard.c +++ b/src/hw/sdcard.c @@ -7,7 +7,7 @@ #include "block.h" // struct drive_s #include "malloc.h" // malloc_fseg #include "output.h" // znprintf -#include "pci.h" // foreachpci +#include "pcidevice.h" // foreachpci #include "pci_ids.h" // PCI_CLASS_SYSTEM_SDHCI #include "pci_regs.h" // PCI_BASE_ADDRESS_0 #include "romfile.h" // romfile_findprefix diff --git a/src/hw/usb-ehci.c b/src/hw/usb-ehci.c index 1d1eb57..7eca55b 100644 --- a/src/hw/usb-ehci.c +++ b/src/hw/usb-ehci.c @@ -9,7 +9,7 @@ #include "output.h" // dprintf #include "malloc.h" // free #include "memmap.h" // PAGE_SIZE -#include "pci.h" // pci_bdf_to_bus +#include "pcidevice.h" // foreachpci #include "pci_ids.h" // PCI_CLASS_SERIAL_USB_UHCI #include "pci_regs.h" // PCI_BASE_ADDRESS_0 #include "string.h" // memset diff --git a/src/hw/usb-ohci.c b/src/hw/usb-ohci.c index b586575..90f60e6 100644 --- a/src/hw/usb-ohci.c +++ b/src/hw/usb-ohci.c @@ -9,7 +9,7 @@ #include "malloc.h" // free #include "memmap.h" // PAGE_SIZE #include "output.h" // dprintf -#include "pci.h" // pci_bdf_to_bus +#include "pcidevice.h" // foreachpci #include "pci_ids.h" // PCI_CLASS_SERIAL_USB_OHCI #include "pci_regs.h" // PCI_BASE_ADDRESS_0 #include "string.h" // memset diff --git a/src/hw/usb-uhci.c b/src/hw/usb-uhci.c index ed7c39a..075ed02 100644 --- a/src/hw/usb-uhci.c +++ b/src/hw/usb-uhci.c @@ -8,7 +8,8 @@ #include "config.h" // CONFIG_* #include "malloc.h" // free #include "output.h" // dprintf -#include "pci.h" // pci_bdf_to_bus +#include "pci.h" // pci_config_writew +#include "pcidevice.h" // foreachpci #include "pci_ids.h" // PCI_CLASS_SERIAL_USB_UHCI #include "pci_regs.h" // PCI_BASE_ADDRESS_4 #include "string.h" // memset diff --git a/src/hw/usb-xhci.c b/src/hw/usb-xhci.c index 6c1720d..5e2f071 100644 --- a/src/hw/usb-xhci.c +++ b/src/hw/usb-xhci.c @@ -9,7 +9,7 @@ #include "malloc.h" // memalign_low #include "memmap.h" // PAGE_SIZE #include "output.h" // dprintf -#include "pci.h" // pci_bdf_to_bus +#include "pcidevice.h" // foreachpci #include "pci_ids.h" // PCI_CLASS_SERIAL_USB_XHCI #include "pci_regs.h" // PCI_BASE_ADDRESS_0 #include "string.h" // memcpy diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c index cd0cbe9..2dfd0c3 100644 --- a/src/hw/virtio-blk.c +++ b/src/hw/virtio-blk.c @@ -12,7 +12,7 @@ #include "block.h" // struct drive_s #include "malloc.h" // free #include "output.h" // dprintf -#include "pci.h" // foreachpci +#include "pcidevice.h" // foreachpci #include "pci_ids.h" // PCI_DEVICE_ID_VIRTIO_BLK #include "pci_regs.h" // PCI_VENDOR_ID #include "std/disk.h" // DISK_RET_SUCCESS diff --git a/src/hw/virtio-pci.c b/src/hw/virtio-pci.c index 378d901..ce15672 100644 --- a/src/hw/virtio-pci.c +++ b/src/hw/virtio-pci.c @@ -19,6 +19,7 @@ #include "malloc.h" // free #include "output.h" // dprintf #include "pci.h" // pci_config_readl +#include "pcidevice.h" // pci_find_capability #include "pci_regs.h" // PCI_BASE_ADDRESS_0 #include "string.h" // memset #include "virtio-pci.h" diff --git a/src/hw/virtio-scsi.c b/src/hw/virtio-scsi.c index f7f01cd..322d469 100644 --- a/src/hw/virtio-scsi.c +++ b/src/hw/virtio-scsi.c @@ -13,7 +13,7 @@ #include "config.h" // CONFIG_* #include "malloc.h" // free #include "output.h" // dprintf -#include "pci.h" // foreachpci +#include "pcidevice.h" // foreachpci #include "pci_ids.h" // PCI_DEVICE_ID_VIRTIO_BLK #include "pci_regs.h" // PCI_VENDOR_ID #include "std/disk.h" // DISK_RET_SUCCESS diff --git a/src/optionroms.c b/src/optionroms.c index a389dd9..9897753 100644 --- a/src/optionroms.c +++ b/src/optionroms.c @@ -8,7 +8,8 @@ #include "bregs.h" // struct bregs #include "config.h" // CONFIG_* #include "farptr.h" // FLATPTR_TO_SEG -#include "hw/pci.h" // foreachpci +#include "hw/pci.h" // pci_config_readl +#include "hw/pcidevice.h" // foreachpci #include "hw/pci_ids.h" // PCI_CLASS_DISPLAY_VGA #include "hw/pci_regs.h" // PCI_ROM_ADDRESS #include "malloc.h" // rom_confirm diff --git a/src/output.c b/src/output.c index 9a8a130..ec51f5e 100644 --- a/src/output.c +++ b/src/output.c @@ -11,6 +11,7 @@ #include "config.h" // CONFIG_* #include "biosvar.h" // GET_GLOBAL #include "hw/pci.h" // pci_bdf_to_bus +#include "hw/pcidevice.h" // pci_device #include "hw/serialio.h" // serial_debug_putc #include "malloc.h" // malloc_tmp #include "output.h" // dprintf diff --git a/src/pcibios.c b/src/pcibios.c index 7e5d972..81735e3 100644 --- a/src/pcibios.c +++ b/src/pcibios.c @@ -8,6 +8,7 @@ #include "biosvar.h" // GET_GLOBAL #include "bregs.h" // struct bregs #include "hw/pci.h" // pci_config_readl +#include "hw/pcidevice.h" // MaxPCIBus #include "hw/pci_regs.h" // PCI_VENDOR_ID #include "output.h" // dprintf #include "std/pirtable.h" // struct pir_header diff --git a/src/vgahooks.c b/src/vgahooks.c index 48efb08..1f14953 100644 --- a/src/vgahooks.c +++ b/src/vgahooks.c @@ -7,7 +7,8 @@ #include "biosvar.h" // GET_GLOBAL #include "bregs.h" // set_code_invalid #include "config.h" // CONFIG_* -#include "hw/pci.h" // pci_find_device +#include "hw/pci.h" // pci_config_readb +#include "hw/pcidevice.h" // pci_find_device #include "hw/pci_ids.h" // PCI_VENDOR_ID_VIA #include "hw/pci_regs.h" // PCI_VENDOR_ID #include "output.h" // dprintf