Advertisement
Vladislav8653

Untitled

Nov 27th, 2023
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.34 KB | None | 0 0
  1. #include "stdio.h"
  2. #include "stdbool.h"
  3. #include "string.h"
  4. #include "stdlib.h"
  5. #include "sys/io.h"
  6. #include "pci.h"
  7.  
  8. #define BASE_ADDRESS_REGISTERS_NUM 6
  9.  
  10. #define DEVICE_ID_OFFSET 0x2
  11. #define INTERRUPT_PIN_OFFSET 0x8
  12.  
  13. #define ID_REGISTER_OFFSET 0x0
  14. #define BASE_ADDRESS_REGISTER_OFFSET 4
  15.  
  16. #define PCI_VENDORS_TABLE_LENGHT (sizeof(PciVenTable) / sizeof(PCI_VENTABLE))
  17. #define PCI_DEVICE_TABLE_LENGHT (sizeof(PciDevTable) / sizeof(PCI_DEVTABLE))
  18.  
  19. #define INTERRUPT_PIN_NOT_USED_MESSAGE "NOT USED"
  20. #define INTERRUPT_PIN_NOT_USED 0
  21. #define INTERRUPT_PIN_A_MESSAGE "INTA#"
  22. #define INTERRUPT_PIN_A 1
  23. #define INTERRUPT_PIN_B_MESSAGE "INTB#"
  24. #define INTERRUPT_PIN_B 2
  25. #define INTERRUPT_PIN_C_MESSAGE "INTC#"
  26. #define INTERRUPT_PIN_C 3
  27. #define INTERRUPT_PIN_D_MESSAGE "INTD#"
  28. #define INTERRUPT_PIN_D 4
  29. #define INVALID_INTERRUPT_PIN "INVALID PIN"
  30.  
  31. #define IRQ_MESSAGE "IRQ%d"
  32. #define INVALID_INTERRUPT_LINE_MESSAGE "INVALID INTERRUPT LINE"
  33.  
  34. int calculateAddress(int bus, int device, int function, int _register)
  35. {
  36. return (1 << 31) | (bus << 16) | (device << 11) | (function << 8) | (_register << 2);
  37. }
  38.  
  39. int readRegister(int bus, int device, int function, int _register)
  40. {
  41. int address = calculateAddress(bus, device, function, _register);
  42. outl(address, 0xCF8);//write//controlling
  43. return inl(0xCFC);//read//data
  44. }
  45.  
  46. bool isFunctionAvailable(long idRegisterData)
  47. {
  48. return idRegisterData != -1;
  49. }
  50.  
  51. int getDeviceId(int idRegisterData)
  52. {
  53. return idRegisterData >> 0x2 * 8;
  54. }
  55.  
  56. int getVendorId(int idRegisterData)
  57. {
  58. return idRegisterData & 0xFFFF;
  59. }
  60.  
  61. char* getVendorName(int vendorId) {
  62. for (int i = 0; i < PCI_VENDORS_TABLE_LENGHT; i++)
  63. {
  64. if (PciVenTable[i].VendorId == vendorId) {
  65. return PciVenTable[i].VendorName;
  66. }
  67. }
  68. return "UNKNOWN VENDOR";
  69. }
  70.  
  71. char* getDeviceName(int vendorId, int deviceId)
  72. {
  73. for (int i = 0; i < PCI_DEVICE_TABLE_LENGHT; i++)
  74. {
  75. if (PciDevTable[i].VendorId == vendorId && PciDevTable[i].DeviceId == deviceId)
  76. {
  77. return PciDevTable[i].DeviceName;
  78. }
  79. }
  80. return "UNKNOWN DEVICE";
  81. }
  82.  
  83. void printGeneralInfo(int bus, int device, int function, int idRegisterData)
  84. {
  85. int deviceId = getDeviceId(idRegisterData);
  86. int vendorId = getVendorId(idRegisterData);
  87. char* deviceName = getDeviceName(vendorId, deviceId);
  88. char* vendorName = getVendorName(vendorId);
  89. printf("%02x:%02x.%x %0x %0x %s %s ", bus, device, function, vendorId, deviceId, vendorName, deviceName);
  90. }
  91.  
  92.  
  93. bool checkOnBridge(int bus, int device, int function)
  94. {
  95. int headerTypeRegisterData = readRegister(bus, device, function, 0x3);
  96. return ((headerTypeRegisterData >> 16) & 0xFF) & 1;
  97. }
  98.  
  99. int getInterruptLineData(int bus, int device, int function)
  100. {
  101. return readRegister(bus, device, function, 15) & 0xFF;
  102. }
  103.  
  104. char* decodeInterruptLineData(int interruptLineData)
  105. {
  106. char* interruptLine = malloc (sizeof (char) * 255);
  107.  
  108. if (interruptLineData == 0xFF)
  109. {
  110. strcpy(interruptLine, "RESERVED");
  111. }
  112. else if (interruptLineData < 16)
  113. {
  114. sprintf(interruptLine, IRQ_MESSAGE, interruptLineData);
  115. }
  116. else {
  117. strcpy(interruptLine, INVALID_INTERRUPT_LINE_MESSAGE);
  118. }
  119.  
  120. return interruptLine;
  121. }
  122.  
  123. void printInterruptLineData(int bus, int device, int function)
  124. {
  125. int interruptLineData = getInterruptLineData(bus, device, function);
  126.  
  127. char* interruptLine = decodeInterruptLineData(interruptLineData);
  128.  
  129. printf("%s", interruptLine);
  130. }
  131.  
  132. char* decodeInterruptPinData(int interruptPinData)
  133. {
  134. char* interruptPin;
  135.  
  136. switch (interruptPinData)
  137. {
  138. case INTERRUPT_PIN_NOT_USED:
  139. interruptPin = INTERRUPT_PIN_NOT_USED_MESSAGE;
  140. break;
  141. case INTERRUPT_PIN_A:
  142. interruptPin = INTERRUPT_PIN_A_MESSAGE;
  143. break;
  144. case INTERRUPT_PIN_B:
  145. interruptPin = INTERRUPT_PIN_B_MESSAGE;
  146. break;
  147. case INTERRUPT_PIN_C:
  148. interruptPin = INTERRUPT_PIN_C_MESSAGE;
  149. break;
  150. case INTERRUPT_PIN_D:
  151. interruptPin = INTERRUPT_PIN_D_MESSAGE;
  152. break;
  153. default:
  154. interruptPin = INVALID_INTERRUPT_PIN;
  155. break;
  156. }
  157.  
  158. return interruptPin;
  159. }
  160.  
  161. int getInterruptPinData(int bus, int device, int function)
  162. {
  163. return (readRegister(bus, device, function, 15) >> INTERRUPT_PIN_OFFSET) & 0xFF;
  164. }
  165.  
  166. void printInterruptPinData(int bus, int device, int function)
  167. {
  168. int interruptPinData = getInterruptPinData(bus, device, function);
  169.  
  170. char* interruptPin = decodeInterruptPinData(interruptPinData);
  171.  
  172. printf("%s ", interruptPin);
  173. }
  174.  
  175. int readPCIConfigWord(int bus, int device, int function, int offset)
  176. {
  177. int address = 0x80000000 | (bus << 16) | (device << 11) | (function << 8) | (offset & 0xFC);
  178. outl(address, 0xCF8);
  179. return inw(0xCFC + (offset & 2));
  180. }
  181.  
  182. // Basic loop
  183. void checkFunction(int bus, int device, int function)
  184. {
  185. int idRegisterData = readRegister(bus, device, function, ID_REGISTER_OFFSET);
  186.  
  187. if (isFunctionAvailable(idRegisterData))
  188. {
  189. printGeneralInfo(bus, device, function, idRegisterData);
  190. if (!checkOnBridge(bus, device, function))
  191. {
  192. printf("\nInterrupt pin:\n");
  193. printInterruptPinData(bus, device, function);
  194. printf("\nInterrupt line:\n");
  195. printInterruptLineData(bus, device, function);
  196. }
  197. else
  198. {
  199. printf("\nBus numbers:\n");
  200. int primaryBusNumber = readPCIConfigWord(bus, device, function, 0x18);
  201. int secondaryBusNumber = readPCIConfigWord(bus, device, function, 0x19);
  202. int subordinateBusNumber = readPCIConfigWord(bus, device, function, 0x1A);
  203. printf("%d-%d-%d\n", primaryBusNumber, secondaryBusNumber, subordinateBusNumber);
  204. }
  205. printf("\n");
  206. }
  207. }
  208.  
  209. int main(void)
  210. {
  211. if (iopl(3))
  212. {
  213. printf("I/O privilege level change error: try running under root user! \n");
  214. return 1;
  215. }
  216. for (int bus = 0; bus < 256; bus++)
  217. {
  218. for (int device = 0; device < 32; device++)
  219. {
  220. for (int function = 0; function < 8; function++)
  221. {
  222. checkFunction(bus, device, function);
  223. }
  224. }
  225. }
  226. return 0;
  227. }
  228.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement