diff --git a/api/hw/pci_device.hpp b/api/hw/pci_device.hpp index cc65890f8..40921708c 100644 --- a/api/hw/pci_device.hpp +++ b/api/hw/pci_device.hpp @@ -22,10 +22,31 @@ #include #include -#define PCI_CAP_ID_AF 0x13 /* PCI Advanced Features */ -#define PCI_CAP_ID_MAX PCI_CAP_ID_AF -#define PCI_EXT_CAP_ID_PASID 0x1B /* Process Address Space ID */ -#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PASID +/* PCI Register Config Space */ +#define PCI_DEV_VEND_REG 0x00 /* for the 32 bit read of dev/vend */ +#define PCI_VENDID_REG 0x00 +#define PCI_DEVID_REG 0x02 +#define PCI_CMD_REG 0x04 +#define PCI_STATUS_REG 0x06 +#define PCI_REVID_REG 0x08 +#define PCI_PROGIF_REG 0x09 +#define PCI_SUBCLASS_REG 0x0a +#define PCI_CLASS_REG 0x0b +#define PCI_CLSZ_REG 0x0c +#define PCI_LATTIM_REG 0x0d +#define PCI_HEADER_REG 0x0e +#define PCI_BIST_REG 0x0f +#define PCI_CAPABILITY_REG 0x34 + +#define PCI_COMMAND_IO 0x01 +#define PCI_COMMAND_MEM 0x02 +#define PCI_COMMAND_MASTER 0x04 + +#define PCI_CAP_ID_VNDR 0x09 +#define PCI_CAP_ID_AF 0x13 /* PCI Advanced Features */ +#define PCI_CAP_ID_MAX PCI_CAP_ID_AF +#define PCI_EXT_CAP_ID_PASID 0x1B /* Process Address Space ID */ +#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PASID namespace PCI { diff --git a/api/hw/pci_manager.hpp b/api/hw/pci_manager.hpp index 74238799e..bde11c08b 100644 --- a/api/hw/pci_manager.hpp +++ b/api/hw/pci_manager.hpp @@ -25,12 +25,19 @@ namespace hw { +struct pcidev_info { + const uintptr_t pci_addr; + uint32_t vendor; + hw::PCI_Device::class_revision_t dev_class; +}; + class PCI_manager { public: // a <...> driver is constructed from a PCI device, // and returns a unique_ptr to itself using NIC_driver = delegate< std::unique_ptr (PCI_Device&, uint16_t) >; using Device_vector = std::vector; + using Devinfo_vector = std::vector; static void register_nic(uint16_t, uint16_t, NIC_driver); using BLK_driver = delegate< std::unique_ptr (PCI_Device&) >; @@ -38,7 +45,11 @@ class PCI_manager { static void init(); static void init_devices(uint8_t classcode); - static Device_vector devices(); + /* Returns devices that were attempted to be initialized */ + static Device_vector devices(); + /* Returns all PCI device information except PCI bridges. + Useful for testing driver code outside of src. */ + static const Devinfo_vector &devinfos(); private: static void scan_bus(int bus); diff --git a/src/hw/pci_device.cpp b/src/hw/pci_device.cpp index 6cf89fd2d..508ffea81 100644 --- a/src/hw/pci_device.cpp +++ b/src/hw/pci_device.cpp @@ -21,25 +21,6 @@ #include #include -/* PCI Register Config Space */ -#define PCI_DEV_VEND_REG 0x00 /* for the 32 bit read of dev/vend */ -#define PCI_VENDID_REG 0x00 -#define PCI_DEVID_REG 0x02 -#define PCI_CMD_REG 0x04 -#define PCI_STATUS_REG 0x06 -#define PCI_REVID_REG 0x08 -#define PCI_PROGIF_REG 0x09 -#define PCI_SUBCLASS_REG 0x0a -#define PCI_CLASS_REG 0x0b -#define PCI_CLSZ_REG 0x0c -#define PCI_LATTIM_REG 0x0d -#define PCI_HEADER_REG 0x0e -#define PCI_BIST_REG 0x0f - -#define PCI_COMMAND_IO 0x01 -#define PCI_COMMAND_MEM 0x02 -#define PCI_COMMAND_MASTER 0x04 - namespace hw { static constexpr std::array bridge_subclasses { @@ -190,7 +171,7 @@ namespace hw { //printf("read16 %#x status %#x\n", PCI_STATUS_REG, status); if ((status & 0x10) == 0) return; // this offset works for non-cardbus bridges - uint32_t offset = 0x34; + uint32_t offset = PCI_CAPABILITY_REG; // read first capability offset = read16(offset) & 0xff; offset &= ~0x3; // lower 2 bits reserved diff --git a/src/hw/pci_manager.cpp b/src/hw/pci_manager.cpp index 19a5a8183..fa0ce103e 100644 --- a/src/hw/pci_manager.cpp +++ b/src/hw/pci_manager.cpp @@ -30,13 +30,7 @@ using Driver_entry = std::pair; template using fixed_factory_t = std::vector>; -struct pcidev_info { - const uintptr_t pci_addr; - uint32_t vendor; - hw::PCI_Device::class_revision_t dev_class; -}; static std::vector devinfos_; - static std::vector devices_; static std::vector> nic_fact; static std::vector> blk_fact; @@ -75,6 +69,10 @@ PCI_manager::Device_vector PCI_manager::devices () { return device_vec; } +const PCI_manager::Devinfo_vector& PCI_manager::devinfos() { + return devinfos_; +} + void PCI_manager::scan_bus(const int bus) { INFO2("|");