Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <sys/io.h>
- #include <errno.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdbool.h>
- #include <values.h>
- #include "pci.h"
- //-------------------------Конец INCLUDES------------------------
- // Максимальное количество шин(256), устр подключенных к каждой шине и функция у кажд. устройства
- #define MAX_BUS 256
- #define MAX_DEVICE 32
- #define MAX_FUNCTIONS 8
- #define ID_REGISTER 0
- //На сколько сдвинуть чтобы получить нужную инфу
- #define DEVICEID_SHIFT 16
- #define BUS_SHIFT 16
- #define DEVICE_SHIFT 11
- #define FUNCTION_SHIFT 8
- #define REGISTER_SHIFT 2
- // Адреса портов Управления и Инфы соответственно
- #define CONTROL_PORT 0x0CF8
- #define DATA_PORT 0x0CFC
- //-------------------------Конец DEFINES------------------------
- void PrintInfo(int bus, int device, int function);
- bool IfBridge(int bus,int device, int function);
- long readRegister(int bus, int device, int function, int reg);
- void outputGeneralData(int bus, int device, int function, int regData);
- char *getDeviceName(int vendorID, int deviceID);
- char *getVendorName(int vendorID);
- void outputBusData(long regData);
- void outputInterruptData(long regData);
- FILE *out;
- //---------------------TASK 3 --------------------------------
- //Вывод информации базовых полей регистров памяти
- void outputBARsData(int bus, int device, int function) {
- int flag = 1;
- fputs("=============TASK 3=============\n", out);
- puts("=============TASK 3=============");
- fputs("Базовые регистры ввода/вывода:\n", out);
- puts("Базовые регистры ввода/вывода:\n");
- int i;
- for (i = 0; i < 6; i++) {
- long regData = readRegister(bus, device, function, 4 + i);
- if (regData) {
- // Если 0 бит = 0 -это Регистр баз адреса памяти, если = 1 - это регистр портов
- if ((regData & 1)) {
- fprintf(out, "\tРегистр ввода/вывода %d: ", i);
- printf("\tРегистр ввода/вывода %d: ", i);
- flag = 0;
- outputIOMemorySpaceBARData(regData);
- }
- }
- }
- if (flag)
- {
- printf("Отсутствую базовые регистры в\\в\n");
- fprintf(out, "Отсутствую базовые регистры в\\в\n");
- }
- }
- void outputIOMemorySpaceBARData(long regData) {
- unsigned long reg1Data=regData-1;
- fprintf(out, "%#lx, ", reg1Data);
- fputs("I/O space register\n", out);
- printf("%#lx, ", reg1Data);
- printf("I/O space register\n");
- }
- //---------------------TASK 4 --------------------------------
- void outputRomBaseAdrData(long regdata)
- {
- fputs("=============TASK 4=============\n", out);
- puts("=============TASK 4=============");
- int enabled = regdata & 1 ;
- if (enabled)
- {
- int BaseRomAdress = (regdata >> 11 ) & 0xFFFFF;
- printf("\nПзу зайдействовано");
- fprintf(out,"\nПзу зайдействовано");
- printf("\nБазовый адрес Пзу: %x\n",BaseRomAdress );
- fprintf(out,"\nБазовый адрес Пзу: %x\n",BaseRomAdress);
- }
- else
- {
- printf("\nПзу не зайдействовано\n");
- fprintf(out,"\nПзу не зайдействовано\n");
- }
- }
- //---------------------TASK 11 --------------------------------
- void outputClassCode(long regData) {
- fputs("=============TASK 11=============\n", out);
- puts("=============TASK 11=============");
- int classCode = (regData >> 24) & 0xFF;
- char *classData;
- switch (classCode) {
- case 0:
- classData = "devices before classification";
- break;
- case 1:
- classData = "storage controllers";
- break;
- case 2:
- classData = "network controllers";
- break;
- case 3:
- classData = "display controllers";
- break;
- case 4:
- classData = "multimedia devices";
- break;
- case 5:
- classData = "memory controllers";
- break;
- case 6:
- classData = "bridges";
- break;
- case 7:
- classData = "communication controllers";
- break;
- case 8:
- classData = "system peripherals";
- break;
- case 9:
- classData = "input device controllers";
- break;
- case 10:
- classData = "docking stations";
- break;
- case 11:
- classData = "processors";
- break;
- case 12:
- classData = "serial bus controllers";
- break;
- case 13:
- classData = "wireless interface controllers";
- break;
- default:
- classData = "invalid class number";
- break;
- }
- fprintf(out, "Class name: %s\n", classData);
- printf( "Class name: %s\n", classData);
- }
- //=======================GENERAL=======================================================================
- //Получаем производителя
- char *getVendorName(int vendorID) {
- int i;
- for (i = 0; i < PCI_VENTABLE_LEN; i++) {
- if (PciVenTable[i].VendorId == vendorID) {
- return PciVenTable[i].VendorName;
- }
- }
- return NULL;
- }
- // Получаем имя устройства из списка
- char *getDeviceName(int vendorID, int deviceID) {
- int i;
- for ( i = 0; i < PCI_DEVTABLE_LEN; i++) {
- if (PciDevTable[i].VendorId == vendorID && PciDevTable[i].DeviceId == deviceID) {
- return PciDevTable[i].DeviceName;
- }
- }
- return NULL;
- }
- void outputVendorData(int vendorID)
- {
- char *vendorName = getVendorName(vendorID);
- fprintf(out, "Vendor ID: %04d, %s\n", vendorID, vendorName ? vendorName : "unknown vendor");
- printf( "Vendor ID: %04d, %s\n", vendorID, vendorName ? vendorName : "Unknown vendor");
- }
- void outputDeviceData(int vendorID, int deviceID)
- {
- char *deviceName = getDeviceName(vendorID, deviceID);
- fprintf(out, "Device ID: %04d, %s\n", deviceID, deviceName ? deviceName : "unknown device");
- printf( "Device ID: %04d, %s\n", deviceID, deviceName ? deviceName : "Unknown device");
- }
- void outputGeneralData(int bus, int device, int function, int regData){
- //Выводим номер шины, устр и функции, Id and VendorId
- fprintf(out, "%x:%x:%x\n", bus, device, function);
- printf( "%x:%x:%x\n", bus, device, function);
- int deviceID = regData >> DEVICEID_SHIFT;
- int vendorID = regData & 0xFFFF;
- outputVendorData(vendorID);
- outputDeviceData(vendorID, deviceID);
- }
- //Чтение нужного регистра(reg) функции function девайса device шина bus
- long readRegister(int bus, int device, int function, int reg) {
- // C помощью сдвигов формирум адрес нужного регистра
- long configRegAddress = (1 << 31) | (bus << BUS_SHIFT) | (device << DEVICE_SHIFT) |(function << FUNCTION_SHIFT) | (reg << REGISTER_SHIFT);
- // загружаем получ. адрес в регистр управления
- outl(configRegAddress, CONTROL_PORT);
- // Читаем значение из реггистра данных
- return inl(DATA_PORT);
- return 0;
- }
- //=================IsBridge====================
- bool IfBridge(int bus,int device, int function){
- //Читаем 3 регистр из простр. конфигураций
- long htypeRegData = readRegister(bus, device, function, 3);
- //Если -0 бит HEader Type - 1 это мост, возвращаем этот бит
- return ((htypeRegData >> 16) & 0xFF) & 1;
- }
- // Функция выводит информацию о заданной функции, заданного уст и моста
- void PrintInfo(int bus, int device, int function) {
- long idRegData = readRegister(bus, device, function, ID_REGISTER);
- // Если записано это значение, значит нет устройства
- if (idRegData != 0xFFFFFFFF) {
- outputGeneralData(bus, device, function, idRegData);
- // Если это мост, выводим необх. информация, в ином случае выводим инфу о баз регистрах
- if (IfBridge(bus, device, function)) {
- fprintf(out, "\nIs bridge\n\n");
- printf("\nIs bridge\n\n");
- outputClassCode(readRegister(bus, device, function, 12));
- } else {
- fprintf(out, "\nNot a bridge\n\n");
- printf("\nNot a bridge\n\n");
- outputBARsData( bus, device, function);
- outputRomBaseAdrData(readRegister(bus, device, function, 1));
- }
- fputs("---------------------------------------------------\n", out);
- puts("---------------------------------------------------\n");
- }
- }
- int main() {
- // Изменение уровня привилегий программы
- if (iopl(3)) {
- printf("I/O Privilege level change error: %s\nTry running under ROOT user\n", strerror(errno));
- return 2;
- }
- int buses;
- int device;
- int function;
- // Файл вывода
- out = fopen("output.txt", "w");
- // Циклы проходящие по всех шинам, устр-вам и их функциям
- for ( buses = 0; buses < MAX_BUS; buses++){
- for (device = 0; device < MAX_DEVICE; device++){
- for ( function = 0; function < MAX_FUNCTIONS; function++){
- PrintInfo(buses,device,function);
- }
- }
- }
- fclose(out);
- return 0;
- }
Add Comment
Please, Sign In to add comment