98 lines
3.5 KiB
C
98 lines
3.5 KiB
C
// 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 <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
// 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
|