Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdio.h"
- #include "pci_c.h"
- #include "stdbool.h"
- #include "sys/io.h"
- #include "string.h"
- #include "errno.h"
- /* define start */
- #define REQUIRED_PRIVILEGE_LEVEL 3
- #define CONFIG_ADDRESS_PORT 0xCF8
- #define CONFIG_DATA_PORT 0xCFC
- #define ENABLE_BIT 0x80000000
- #define BUS_OFFSET 16
- #define DEVICE_OFFSET 11
- #define FUNCTION_OFFSET 8
- #define DEVICE_ID_OFFSET 2
- #define VENDOR_ID_OFFSET 0
- #define PCI_PORT_VMWARE_DEV "PCI Express Root Port"
- #define PCI_X_VMWARE_DEV "PCI-X Fusion-MPT Dual Ultra320 SCSI"
- #define USB_VMWARE_DEV "USB1.1 UHCI Controller"
- #define SATA_VMWARE_DEV "SATA AHCI controller"
- #define UNKNOWN_MSG "Unknown"
- #define NUM_OF_VENDORS (sizeof(PciVenTable) / sizeof(PCI_VENTABLE))
- #define NUM_OF_DEVICES (sizeof(PciDevTable) / sizeof(PCI_DEVTABLE))
- #define NUM_OF_CLASSES (sizeof(PciClassCodeTable) / sizeof(PCI_CLASSCODETABLE))
- #define BUS_NUM 256
- #define DEVICE_NUM 32
- #define FUNCTION_NUM 8
- /* define end */
- /* PCI methods start */
- int calculateAddress(const int bus, const int device, const int function)
- {
- return ENABLE_BIT + (bus << BUS_OFFSET) + (device << DEVICE_OFFSET) + (function << FUNCTION_OFFSET);
- }
- int getPCIData(const int address)
- {
- outl(address, CONFIG_ADDRESS_PORT); // прочитать по адресу
- return inl(CONFIG_DATA_PORT); // записать по адресу
- }
- int readPCIDataField(const int data, const int offset)
- {
- return (int)((data >> ((offset & 2) * 8)) & 0xFFFF);
- }
- /* PCI methods end */
- /* device methods start */
- bool DoesDeviceExist(const int data)
- {
- return data != -1;
- }
- char *getVendorName(const int vendorID)
- {
- for (int i = 0; i < NUM_OF_VENDORS; i++)
- if (PciVenTable[i].VenId == vendorID)
- return PciVenTable[i].VenFull;
- return UNKNOWN_MSG; // в случае, если не находится имя, выводится Unknown
- }
- char *getDeviceName(const int vendorID, const int deviceID)
- {
- for (int i = 0; i < NUM_OF_DEVICES; i++)
- {
- if (PciDevTable[i].VenId == vendorID && PciDevTable[i].DevId == deviceID)
- return PciDevTable[i].Chip;
- if (vendorID == 0x15AD && deviceID == 0x07a0)
- return PCI_PORT_VMWARE_DEV;
- if (vendorID == 0x15AD && deviceID == 0x0790)
- return PCI_X_VMWARE_DEV;
- if (vendorID == 0x15AD && deviceID == 0x0774)
- return USB_VMWARE_DEV;
- if (vendorID == 0x15AD && deviceID == 0x07e0)
- return SATA_VMWARE_DEV;
- }
- return UNKNOWN_MSG; // в случае, если не находится имя, выводится Unknown
- }
- bool isBridge(const unsigned address)
- {
- outl(address + 0x0C, CONFIG_ADDRESS_PORT);
- //return (inl(CONFIG_DATA_PORT) >> 16) != 0;
- return (inl(CONFIG_DATA_PORT) >> 16) & 1;
- }
- int decodeROMBaseRegisters(const int address)
- {
- if (!isBridge(address))
- {
- outl(address + 0x1C, CONFIG_ADDRESS_PORT);
- int inter = inl(CONFIG_DATA_PORT);
- return inter >> 11;
- }
- else
- return 0;
- }
- int decodeInputRegs(const int address)
- {
- if (!isBridge(address))
- {
- for (int i = 0; i < 6; i++)
- {
- outl(address + 0x10 + i * 4, CONFIG_ADDRESS_PORT);
- unsigned barValue = inl(CONFIG_DATA_PORT);
- if ((barValue & 1) == 1) //является ли регистром ввода-вывода
- return barValue >> 2;
- }
- return 0;
- }
- else
- return 0;
- }
- int decodeClassCode(const int address)
- {
- if (isBridge(address))
- {
- outl(address + 0x08, CONFIG_ADDRESS_PORT);
- int inter = inl(CONFIG_DATA_PORT);
- return inter >> 8; //Prog. I/F(8..15) + SubClass Code(16..23) + ClassCode(24..31)
- }
- else
- return 0;
- }
- char *getClassName(const int classCode)
- {
- int baseClass = classCode / 0x10000;
- int subClass = (classCode / 0x100) % 0x100;
- int prog = classCode % 0x100;
- for (int i = 0; i < NUM_OF_CLASSES; i++)
- {
- if (classCode == 0x0)
- return UNKNOWN_MSG;
- if (PciClassCodeTable[i].BaseClass == baseClass && PciClassCodeTable[i].SubClass == subClass && PciClassCodeTable[i].ProgIf == prog)
- return PciClassCodeTable[i].SubDesc;
- }
- return UNKNOWN_MSG; // в случае, если не находится имя, выводится Unknown
- }
- // device structure
- typedef struct
- {
- int bus;
- int device;
- int function;
- int vendorID;
- int deviceID;
- char *vendorName;
- char *deviceName;
- int ROMBR; // ROM Base Registers
- int IOBReg; // I/O Base Registers
- int clCode; // ClassCode
- char* clCodeName;
- } deviceStruct;
- deviceStruct constructor(const int bus, const int device, const int function, const int data, const int address)
- {
- int vendorID = readPCIDataField(data, VENDOR_ID_OFFSET);
- int deviceID = readPCIDataField(data, DEVICE_ID_OFFSET);
- char *vendorName = getVendorName(vendorID);
- char *deviceName = getDeviceName(vendorID, deviceID);
- int ROMBaseReg = decodeROMBaseRegisters(address);
- int inputBaseRegs = decodeInputRegs(address);
- int classCode = decodeClassCode(address);
- char *classCodeName = getClassName(classCode);
- deviceStruct temp = {bus, device, function, vendorID, deviceID, vendorName, deviceName, ROMBaseReg, inputBaseRegs, classCode, classCodeName};
- return temp;
- }
- /* device methods end */
- /* print procedures start */
- void printTaskInfo()
- {
- printf("\n\tДанная программа формирует цикл опроса и идентификации устройств PCI, затем выводит информацию о них в сводной таблице.\n \t\t\t\t\t\tДоп. задания:\n");
- printf("3. \tЕсли устройство не мост(0-бит поля Header Type = 0) вывести и расшифровать значение полей базовых регистров ввода/вывода.\n");
- printf("4. \tЕсли устройство не мост(0-бит поля Header Type = 0) вывести и расшифровать значение полей базовых регистров постоянной (ROM) памяти.\n");
- printf("11. Если устройство мост(0-бит поля Header Type = 1) вывести и расшифровать значение поля Сlass Code.\n\n");
- }
- void printTableSplitter()
- {
- printf("---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");
- }
- void printTableStart()
- {
- printTableSplitter();
- printf(" Bus | Device | Function | Vendor ID | Device ID |\tVendor Name\t| \t\tDevice Name\t\t | ROM B.Reg. | I/O B.Reg. | ClassCode | ClassCode Name |\n");
- printTableSplitter();
- }
- void printDevice(const deviceStruct device, const int address)
- {
- printf(" %02x | %02x | %01x\t |%8x |%8x |%20s | %36s | %9x | %4x | %9x | %14s |\n", device.bus, device.device, device.function, device.vendorID, device.deviceID, device.vendorName, device.deviceName, device.ROMBR, device.IOBReg, device.clCode, device.clCodeName);
- }
- /* print procedures end */
- int main(void)
- {
- errno = 0;
- if (iopl(REQUIRED_PRIVILEGE_LEVEL)) // проверка уровня привилегий
- {
- printf("Ошибка изменения уровня привилегий ввода-вывода: %s\nПопробуйте запустить программу, используя пользователя ROOT\n", (char *)strerror(errno));
- return 1;
- }
- printTaskInfo();
- printTableStart();
- for (int busIndex = 0; busIndex < BUS_NUM; busIndex++)
- {
- for (int deviceIndex = 0; deviceIndex < DEVICE_NUM; deviceIndex++)
- {
- for (int functionIndex = 0; functionIndex < FUNCTION_NUM; functionIndex++)
- {
- int address = calculateAddress(busIndex, deviceIndex, functionIndex);
- int data = getPCIData(address);
- if (DoesDeviceExist(data))
- {
- deviceStruct device = constructor(busIndex, deviceIndex, functionIndex, data, address);
- printDevice(device, address);
- }
- }
- }
- }
- printTableSplitter();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement