MadCortez

Untitled

Dec 15th, 2021
284
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.95 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <sys/io.h>
  3.  
  4. #include <errno.h>
  5. #include <stdlib.h>
  6.  
  7. #include <string.h>
  8. #include <stdbool.h>
  9. #include <values.h>
  10. #include "pci.h"
  11.  
  12. //-------------------------Конец INCLUDES------------------------
  13.  
  14. // Максимальное количество шин(256), устр подключенных к каждой шине и функция у кажд. устройства
  15. #define MAX_BUS 256
  16. #define MAX_DEVICE 32
  17. #define MAX_FUNCTIONS 8
  18.  
  19. #define ID_REGISTER 0
  20.  
  21. //На сколько сдвинуть чтобы получить нужную инфу
  22. #define DEVICEID_SHIFT 16
  23. #define BUS_SHIFT 16
  24. #define DEVICE_SHIFT 11
  25. #define FUNCTION_SHIFT 8
  26. #define REGISTER_SHIFT 2
  27.  
  28. // Адреса портов Управления и Инфы соответственно
  29. #define CONTROL_PORT 0x0CF8
  30. #define DATA_PORT 0x0CFC
  31.  
  32. //-------------------------Конец DEFINES------------------------
  33.  
  34.  
  35.  
  36.  
  37. void PrintInfo(int bus, int device, int function);
  38. bool IfBridge(int bus,int device, int function);
  39. long readRegister(int bus, int device, int function, int reg);
  40. void outputGeneralData(int bus, int device, int function, int regData);
  41. char *getDeviceName(int vendorID, int deviceID);
  42. char *getVendorName(int vendorID);
  43. void outputBusData(long regData);
  44. void outputInterruptData(long regData);
  45.  
  46.  
  47. FILE *out;
  48.  
  49. //---------------------TASK 3 --------------------------------
  50.  
  51.  
  52. //Вывод информации базовых полей регистров памяти
  53. void outputBARsData(int bus, int device, int function) {
  54.      int flag = 1;
  55.      fputs("=============TASK 3=============\n", out);
  56.      puts("=============TASK 3=============");
  57.      fputs("Базовые регистры ввода/вывода:\n", out);
  58.      puts("Базовые регистры ввода/вывода:\n");
  59.      int i;
  60.      for (i = 0; i < 6; i++) {
  61.         long regData = readRegister(bus, device, function, 4 + i);
  62.         if (regData) {
  63.            
  64.             // Если 0 бит = 0 -это Регистр баз адреса памяти, если = 1 - это регистр портов
  65.             if ((regData & 1)) {
  66.               fprintf(out, "\tРегистр ввода/вывода %d: ", i);
  67.               printf("\tРегистр ввода/вывода %d: ", i);
  68.        
  69.          flag = 0;
  70.                    
  71.               outputIOMemorySpaceBARData(regData);
  72.             }
  73.         }
  74.     }
  75.    
  76.     if (flag)
  77.     {
  78.       printf("Отсутствую базовые регистры в\\в\n");
  79.       fprintf(out, "Отсутствую базовые регистры в\\в\n");
  80.    
  81.     }
  82.    
  83. }
  84.  
  85. void outputIOMemorySpaceBARData(long regData) {
  86.   unsigned long reg1Data=regData-1;
  87.     fprintf(out, "%#lx, ", reg1Data);
  88.     fputs("I/O space register\n", out);
  89.     printf("%#lx, ", reg1Data);
  90.     printf("I/O space register\n");
  91. }
  92.  
  93. //---------------------TASK 4 --------------------------------
  94.  
  95. void outputRomBaseAdrData(long regdata)
  96. {
  97.        fputs("=============TASK 4=============\n", out);
  98.      puts("=============TASK 4=============");
  99.  
  100.     int enabled = regdata & 1 ;
  101.     if (enabled)
  102.     {
  103.       int BaseRomAdress = (regdata >> 11 ) & 0xFFFFF;
  104.      
  105.       printf("\nПзу  зайдействовано");
  106.       fprintf(out,"\nПзу  зайдействовано");
  107.       printf("\nБазовый адрес Пзу: %x\n",BaseRomAdress  );
  108.       fprintf(out,"\nБазовый адрес Пзу: %x\n",BaseRomAdress);
  109.      
  110.      
  111.     }
  112.     else
  113.     {
  114.       printf("\nПзу не зайдействовано\n");
  115.       fprintf(out,"\nПзу не зайдействовано\n");
  116.     }
  117.    
  118.      
  119. }
  120.  
  121.  
  122. //---------------------TASK 11 --------------------------------
  123.  
  124. void outputClassCode(long regData) {
  125.     fputs("=============TASK 11=============\n", out);
  126.     puts("=============TASK 11=============");
  127.  
  128.  
  129.     int classCode = (regData >> 24) & 0xFF;
  130.     char *classData;
  131.     switch (classCode) {
  132.     case 0:
  133.         classData = "devices before classification";
  134.         break;
  135.     case 1:
  136.         classData = "storage controllers";
  137.         break;
  138.     case 2:
  139.         classData = "network controllers";
  140.         break;
  141.     case 3:
  142.         classData = "display controllers";
  143.         break;
  144.     case 4:
  145.         classData = "multimedia devices";
  146.         break;
  147.     case 5:
  148.         classData = "memory controllers";
  149.         break;
  150.     case 6:
  151.         classData = "bridges";
  152.         break;
  153.     case 7:
  154.         classData = "communication controllers";
  155.         break;
  156.     case 8:
  157.         classData = "system peripherals";
  158.         break;
  159.     case 9:
  160.         classData = "input device controllers";
  161.         break;
  162.     case 10:
  163.         classData = "docking stations";
  164.         break;
  165.     case 11:
  166.         classData = "processors";
  167.         break;
  168.     case 12:
  169.         classData = "serial bus controllers";
  170.         break;
  171.     case 13:
  172.         classData = "wireless interface controllers";
  173.         break;
  174.     default:
  175.         classData = "invalid class number";
  176.         break;
  177.     }
  178.     fprintf(out, "Class name: %s\n", classData);
  179.     printf( "Class name: %s\n", classData);
  180. }
  181.  
  182. //=======================GENERAL=======================================================================
  183.  
  184. //Получаем производителя
  185. char *getVendorName(int vendorID) {
  186. int i;
  187.     for (i = 0; i < PCI_VENTABLE_LEN; i++) {
  188.         if (PciVenTable[i].VendorId == vendorID) {
  189.             return PciVenTable[i].VendorName;
  190.         }
  191.     }
  192.     return NULL;
  193. }
  194.  
  195. // Получаем имя устройства из списка
  196. char *getDeviceName(int vendorID, int deviceID) {
  197. int i;
  198.     for ( i = 0; i < PCI_DEVTABLE_LEN; i++) {
  199.         if (PciDevTable[i].VendorId == vendorID && PciDevTable[i].DeviceId == deviceID) {
  200.             return PciDevTable[i].DeviceName;
  201.         }
  202.     }
  203.     return NULL;
  204. }
  205.  
  206. void outputVendorData(int vendorID)
  207. {
  208.     char *vendorName = getVendorName(vendorID);
  209.     fprintf(out, "Vendor ID: %04d, %s\n", vendorID, vendorName ? vendorName : "unknown vendor");
  210.    printf( "Vendor ID: %04d, %s\n", vendorID, vendorName ? vendorName : "Unknown vendor");
  211. }
  212.  
  213. void outputDeviceData(int vendorID, int deviceID)
  214. {
  215.     char *deviceName = getDeviceName(vendorID, deviceID);
  216.     fprintf(out, "Device ID: %04d, %s\n", deviceID, deviceName ? deviceName : "unknown device");
  217.     printf( "Device ID: %04d, %s\n", deviceID, deviceName ? deviceName : "Unknown device");
  218. }
  219.  
  220.  
  221. void outputGeneralData(int bus, int device, int function, int regData){
  222. //Выводим номер шины, устр и функции, Id and VendorId
  223.     fprintf(out, "%x:%x:%x\n", bus, device, function);
  224.     printf( "%x:%x:%x\n", bus, device, function);
  225.     int deviceID = regData >> DEVICEID_SHIFT;
  226.     int vendorID = regData & 0xFFFF;
  227.     outputVendorData(vendorID);
  228.     outputDeviceData(vendorID, deviceID);
  229. }
  230.  
  231.  
  232. //Чтение нужного регистра(reg) функции function девайса  device шина bus
  233. long readRegister(int bus, int device, int function, int reg) {
  234.    // C помощью сдвигов формирум адрес нужного регистра
  235.    long  configRegAddress = (1 << 31) | (bus << BUS_SHIFT) | (device << DEVICE_SHIFT) |(function << FUNCTION_SHIFT) | (reg << REGISTER_SHIFT);
  236.     // загружаем получ. адрес в регистр управления
  237.     outl(configRegAddress, CONTROL_PORT);
  238.     // Читаем значение из реггистра данных
  239.     return inl(DATA_PORT);
  240.  
  241.     return 0;
  242. }
  243.  
  244. //=================IsBridge====================
  245. bool IfBridge(int bus,int device, int function){
  246.  //Читаем 3 регистр из простр. конфигураций
  247.  long htypeRegData = readRegister(bus, device, function, 3);
  248. //Если -0 бит HEader Type  - 1  это мост, возвращаем этот бит
  249.     return ((htypeRegData >> 16) & 0xFF) & 1;
  250. }
  251.  
  252.  
  253. // Функция выводит информацию о заданной функции, заданного уст и моста
  254. void PrintInfo(int bus, int device, int function) {
  255.    long idRegData = readRegister(bus, device, function, ID_REGISTER);
  256.  
  257. // Если записано это значение, значит нет устройства
  258.    if (idRegData != 0xFFFFFFFF) {
  259.         outputGeneralData(bus, device, function, idRegData);
  260.  
  261. // Если это мост, выводим необх. информация, в ином случае выводим инфу о баз регистрах
  262.    if (IfBridge(bus, device, function)) {
  263.             fprintf(out, "\nIs bridge\n\n");
  264.         printf("\nIs bridge\n\n");
  265.         outputClassCode(readRegister(bus, device, function, 12));
  266.         } else {
  267.             fprintf(out, "\nNot a bridge\n\n");
  268.             printf("\nNot a bridge\n\n");            
  269.         outputBARsData( bus,  device, function);
  270.         outputRomBaseAdrData(readRegister(bus, device, function, 1));
  271.                    
  272.         }
  273.         fputs("---------------------------------------------------\n", out);
  274.        puts("---------------------------------------------------\n");
  275.     }
  276. }
  277.  
  278.  
  279. int main() {
  280.  
  281.  
  282.  
  283. // Изменение уровня привилегий программы  
  284.     if (iopl(3)) {  
  285.        printf("I/O Privilege level change error: %s\nTry running under ROOT user\n", strerror(errno));
  286.  
  287.        return 2;
  288.     }
  289.  
  290.    
  291.    int buses;
  292.    int device;
  293.    int function;
  294.    // Файл вывода
  295.    out = fopen("output.txt", "w");
  296.  
  297. // Циклы проходящие по всех шинам, устр-вам и их функциям
  298.    for ( buses = 0; buses < MAX_BUS; buses++){
  299.         for (device = 0; device < MAX_DEVICE; device++){
  300.             for ( function = 0; function < MAX_FUNCTIONS; function++){
  301.                 PrintInfo(buses,device,function);
  302.             }
  303.         }
  304.     }
  305.  
  306.  
  307.     fclose(out);
  308.     return 0;
  309. }
Add Comment
Please, Sign In to add comment