Skip to content

Instantly share code, notes, and snippets.

@mafice
Created May 12, 2012 00:53
Show Gist options
  • Select an option

  • Save mafice/2663420 to your computer and use it in GitHub Desktop.

Select an option

Save mafice/2663420 to your computer and use it in GitHub Desktop.
PCI
#define PCI_IOPORT_CONFIG_ADDRESS 0x0cf8
#define PCI_IOPORT_CONFIG_DATA 0x0cfc
#define PCI_BUS_MAX 255
#define PCI_DEVICE_MAX 31
#define PCI_FUNC_MAX 7
#define PCI_CONFIGREG_VENDOR_AND_DEVICE_ID 0x00
#define PCI_CONFIGREG_INTERRUPT 0x3c
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
typedef struct PCIDevice_st{
u16 vendorID;
u16 deviceID;
u8 interruptLine;
} PCIDevice_st;
static void pci_findDevices (PCIDevice_st devices[], unsigned int devicesMax);
static u32 pci_readConfigRegister (u8 regAddr, u8 bus, u8 device, u8 func);
void pci_test (void){
PCIDevice_st devices[100];
pci_findDevices(devices, 100);
for(int i=0; i < 255 && devices[i].vendorID != 0xffff; i++){
if(devices[i].interruptLine == 0xff)
print("PCI: device found (vendor: 0x%x) (device: 0x%x) (interrupt: none)\n", devices[i].vendorID, devices[i].deviceID);
else
print("PCI: device found (vendor: 0x%x) (device: 0x%x) (interrupt: %d)\n", devices[i].vendorID, devices[i].deviceID, devices[i].interruptLine);
}
return;
}
static void pci_findDevices (PCIDevice_st devices[], unsigned int devicesMax){
u32 reg;
unsigned int i=0;
for(unsigned int j=0; j <= PCI_BUS_MAX; j++){
for(unsigned int k=0; k <= PCI_DEVICE_MAX; k++){
for(unsigned int l=0; l <= PCI_FUNC_MAX; l++){
// get Vendor ID and device ID
reg = pci_readConfigRegister(PCI_CONFIGREG_VENDOR_AND_DEVICE_ID, j, k, l);
// if vendor ID is 0xffff, the device (or function) is not exist
if((reg>>16) == 0xffff){
continue;
}
devices[i].vendorID = reg >> 16;
devices[i].deviceID = reg & 0xffff;
// get interrupt line
reg = pci_readConfigRegister(PCI_CONFIGREG_INTERRUPT, j, k, l);
// Notes: if the interrupt line is 0xff or the interrupt pin is 0, there is no connection
devices[i].interruptLine = (((reg>>8) == 0x00)? 0xff : (reg & 0xff));
i++;
// in order to prevent stack overflow
if(i+1 >= devicesMax){
break;
}
}
}
}
devices[i].vendorID = 0xffff;
devices[i].deviceID = 0xffff;
devices[i].interruptLine = 0xff;
return;
}
static u32 pci_readConfigRegister (u8 regAddr, u8 bus, u8 device, u8 func){
u32 ret;
// tell PCI what I want to read
asm_out32(PCI_IOPORT_CONFIG_ADDRESS,
((0 << 0) & 0x00000000) | // bit 0-1: must be 0
((regAddr << 0) & 0x000000fc) | // bit 2-7: register number
((func << 8) & 0x00000700) | // bit 8-10: function number
((device << 11) & 0x0000f800) | // bit 11-15: device number
((bus << 16) & 0x00ff0000) | // bit 16-23: bus number
((0 << 24) & 0x7f000000) | // bit 24-30: reserved
((1 << 31) & 0x80000000) // bit 31: enable bit
);
// read CONFIG_DATA
ret = asm_in32(PCI_IOPORT_CONFIG_DATA);
// clear enable bit
asm_out32(PCI_IOPORT_CONFIG_ADDRESS, 0x00000000);
return ret;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment