// pci.h -- PCI configuration space access for DOS/DJGPP // // Provides functions to read/write PCI configuration registers and // enumerate devices on the PCI bus. Uses the standard mechanism 1 // (I/O ports 0xCF8/0xCFC) which is supported by all PCI-capable // systems from 1993 onward. // // All functions operate synchronously via inportl/outportl. No BIOS // calls (INT 1Ah) are used because mechanism 1 is faster, simpler, // and doesn't require a DPMI real-mode callback. #ifndef PCI_H #define PCI_H #include #include // PCI configuration space register offsets (common header) #define PCI_VENDOR_ID 0x00 #define PCI_DEVICE_ID 0x02 #define PCI_COMMAND 0x04 #define PCI_STATUS 0x06 #define PCI_REVISION_ID 0x08 #define PCI_CLASS_CODE 0x09 #define PCI_SUBCLASS 0x0A #define PCI_BASE_CLASS 0x0B #define PCI_HEADER_TYPE 0x0E #define PCI_BAR0 0x10 #define PCI_BAR1 0x14 #define PCI_BAR2 0x18 #define PCI_BAR3 0x1C #define PCI_BAR4 0x20 #define PCI_BAR5 0x24 #define PCI_SUBSYS_VENDOR 0x2C #define PCI_SUBSYS_ID 0x2E // PCI command register bits #define PCI_CMD_IO_ENABLE 0x0001 #define PCI_CMD_MEM_ENABLE 0x0002 #define PCI_CMD_BUS_MASTER 0x0004 // PCI base class for display controllers #define PCI_CLASS_DISPLAY 0x03 // Maximum PCI bus/device/function values #define PCI_MAX_BUS 256 #define PCI_MAX_DEV 32 #define PCI_MAX_FUNC 8 // PCI device descriptor returned by enumeration typedef struct { uint8_t bus; uint8_t dev; uint8_t func; uint16_t vendorId; uint16_t deviceId; uint8_t revision; uint8_t baseClass; uint8_t subClass; uint32_t bar[6]; } PciDeviceT; // Callback for pciEnumerate(). Return true to stop enumeration. typedef bool (*PciEnumCallbackT)(const PciDeviceT *device, void *userData); // ============================================================ // Prototypes // ============================================================ // Build a CONFIG_ADDRESS dword for the given bus/dev/func/register. uint32_t pciBuildAddress(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg); // Check whether PCI mechanism 1 is available. bool pciDetect(void); // Enumerate all PCI devices. Calls cb for each device found. // Stops early if cb returns true. Returns the number of devices found. int32_t pciEnumerate(PciEnumCallbackT cb, void *userData); // Find the first PCI device matching vendorId/deviceId. // Returns true if found (and fills out dev), false if not. bool pciFindDevice(uint16_t vendorId, uint16_t deviceId, PciDeviceT *dev); // Find the first PCI device matching any of the given vendor/device // pairs. The list is terminated by a {0, 0} entry. Returns true if // found (and fills out dev and matchIdx), false if not. bool pciFindDeviceList(const uint16_t *idPairs, PciDeviceT *dev, int32_t *matchIdx); // Read an 8/16/32-bit value from PCI configuration space. uint8_t pciRead8(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg); uint16_t pciRead16(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg); uint32_t pciRead32(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg); // Write an 8/16/32-bit value to PCI configuration space. void pciWrite8(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg, uint8_t val); void pciWrite16(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg, uint16_t val); void pciWrite32(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg, uint32_t val); #endif // PCI_H