Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdio.h"
- #include "stdbool.h"
- #include "string.h"
- #include "stdlib.h"
- #include "sys/io.h"
- #include "pci.h"
- #define BASE_ADDRESS_REGISTERS_NUM 6
- #define DEVICE_ID_OFFSET 0x2
- #define INTERRUPT_PIN_OFFSET 0x8
- #define ID_REGISTER_OFFSET 0x0
- #define BASE_ADDRESS_REGISTER_OFFSET 4
- #define PCI_VENDORS_TABLE_LENGHT (sizeof(PciVenTable) / sizeof(PCI_VENTABLE))
- #define PCI_DEVICE_TABLE_LENGHT (sizeof(PciDevTable) / sizeof(PCI_DEVTABLE))
- #define INTERRUPT_PIN_NOT_USED_MESSAGE "NOT USED"
- #define INTERRUPT_PIN_NOT_USED 0
- #define INTERRUPT_PIN_A_MESSAGE "INTA#"
- #define INTERRUPT_PIN_A 1
- #define INTERRUPT_PIN_B_MESSAGE "INTB#"
- #define INTERRUPT_PIN_B 2
- #define INTERRUPT_PIN_C_MESSAGE "INTC#"
- #define INTERRUPT_PIN_C 3
- #define INTERRUPT_PIN_D_MESSAGE "INTD#"
- #define INTERRUPT_PIN_D 4
- #define INVALID_INTERRUPT_PIN "INVALID PIN"
- #define IRQ_MESSAGE "IRQ%d"
- #define INVALID_INTERRUPT_LINE_MESSAGE "INVALID INTERRUPT LINE"
- int calculateAddress(int bus, int device, int function, int _register)
- {
- return (1 << 31) | (bus << 16) | (device << 11) | (function << 8) | (_register << 2);
- }
- int readRegister(int bus, int device, int function, int _register)
- {
- int address = calculateAddress(bus, device, function, _register);
- outl(address, 0xCF8);//write//controlling
- return inl(0xCFC);//read//data
- }
- bool isFunctionAvailable(long idRegisterData)
- {
- return idRegisterData != -1;
- }
- int getDeviceId(int idRegisterData)
- {
- return idRegisterData >> 0x2 * 8;
- }
- int getVendorId(int idRegisterData)
- {
- return idRegisterData & 0xFFFF;
- }
- char* getVendorName(int vendorId) {
- for (int i = 0; i < PCI_VENDORS_TABLE_LENGHT; i++)
- {
- if (PciVenTable[i].VendorId == vendorId) {
- return PciVenTable[i].VendorName;
- }
- }
- return "UNKNOWN VENDOR";
- }
- char* getDeviceName(int vendorId, int deviceId)
- {
- for (int i = 0; i < PCI_DEVICE_TABLE_LENGHT; i++)
- {
- if (PciDevTable[i].VendorId == vendorId && PciDevTable[i].DeviceId == deviceId)
- {
- return PciDevTable[i].DeviceName;
- }
- }
- return "UNKNOWN DEVICE";
- }
- void printGeneralInfo(int bus, int device, int function, int idRegisterData)
- {
- int deviceId = getDeviceId(idRegisterData);
- int vendorId = getVendorId(idRegisterData);
- char* deviceName = getDeviceName(vendorId, deviceId);
- char* vendorName = getVendorName(vendorId);
- printf("%02x:%02x.%x %0x %0x %s %s ", bus, device, function, vendorId, deviceId, vendorName, deviceName);
- }
- bool checkOnBridge(int bus, int device, int function)
- {
- int headerTypeRegisterData = readRegister(bus, device, function, 0x3);
- return ((headerTypeRegisterData >> 16) & 0xFF) & 1;
- }
- int getInterruptLineData(int bus, int device, int function)
- {
- return readRegister(bus, device, function, 15) & 0xFF;
- }
- char* decodeInterruptLineData(int interruptLineData)
- {
- char* interruptLine = malloc (sizeof (char) * 255);
- if (interruptLineData == 0xFF)
- {
- strcpy(interruptLine, "RESERVED");
- }
- else if (interruptLineData < 16)
- {
- sprintf(interruptLine, IRQ_MESSAGE, interruptLineData);
- }
- else {
- strcpy(interruptLine, INVALID_INTERRUPT_LINE_MESSAGE);
- }
- return interruptLine;
- }
- void printInterruptLineData(int bus, int device, int function)
- {
- int interruptLineData = getInterruptLineData(bus, device, function);
- char* interruptLine = decodeInterruptLineData(interruptLineData);
- printf("%s", interruptLine);
- }
- char* decodeInterruptPinData(int interruptPinData)
- {
- char* interruptPin;
- switch (interruptPinData)
- {
- case INTERRUPT_PIN_NOT_USED:
- interruptPin = INTERRUPT_PIN_NOT_USED_MESSAGE;
- break;
- case INTERRUPT_PIN_A:
- interruptPin = INTERRUPT_PIN_A_MESSAGE;
- break;
- case INTERRUPT_PIN_B:
- interruptPin = INTERRUPT_PIN_B_MESSAGE;
- break;
- case INTERRUPT_PIN_C:
- interruptPin = INTERRUPT_PIN_C_MESSAGE;
- break;
- case INTERRUPT_PIN_D:
- interruptPin = INTERRUPT_PIN_D_MESSAGE;
- break;
- default:
- interruptPin = INVALID_INTERRUPT_PIN;
- break;
- }
- return interruptPin;
- }
- int getInterruptPinData(int bus, int device, int function)
- {
- return (readRegister(bus, device, function, 15) >> INTERRUPT_PIN_OFFSET) & 0xFF;
- }
- void printInterruptPinData(int bus, int device, int function)
- {
- int interruptPinData = getInterruptPinData(bus, device, function);
- char* interruptPin = decodeInterruptPinData(interruptPinData);
- printf("%s ", interruptPin);
- }
- int readPCIConfigWord(int bus, int device, int function, int offset)
- {
- int address = 0x80000000 | (bus << 16) | (device << 11) | (function << 8) | (offset & 0xFC);
- outl(address, 0xCF8);
- return inw(0xCFC + (offset & 2));
- }
- // Basic loop
- void checkFunction(int bus, int device, int function)
- {
- int idRegisterData = readRegister(bus, device, function, ID_REGISTER_OFFSET);
- if (isFunctionAvailable(idRegisterData))
- {
- printGeneralInfo(bus, device, function, idRegisterData);
- if (!checkOnBridge(bus, device, function))
- {
- printf("\nInterrupt pin:\n");
- printInterruptPinData(bus, device, function);
- printf("\nInterrupt line:\n");
- printInterruptLineData(bus, device, function);
- }
- else
- {
- printf("\nBus numbers:\n");
- int primaryBusNumber = readPCIConfigWord(bus, device, function, 0x18);
- int secondaryBusNumber = readPCIConfigWord(bus, device, function, 0x19);
- int subordinateBusNumber = readPCIConfigWord(bus, device, function, 0x1A);
- printf("%d-%d-%d\n", primaryBusNumber, secondaryBusNumber, subordinateBusNumber);
- }
- printf("\n");
- }
- }
- int main(void)
- {
- if (iopl(3))
- {
- printf("I/O privilege level change error: try running under root user! \n");
- return 1;
- }
- for (int bus = 0; bus < 256; bus++)
- {
- for (int device = 0; device < 32; device++)
- {
- for (int function = 0; function < 8; function++)
- {
- checkFunction(bus, device, function);
- }
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement