I try walk in ports.
typedef unsigned int ui;
#include "pci.h"
#include "string.h"
#include <sys/io.h>
#include <stdio.h>
#include <errno.h>
char* getBaseClassName(ui baseClassCode){//decipher Class Code field (see txt document lab3.txt) :)
char* str;
switch(baseClassCode){
case 0:
str = "Devices, constructed before classification.";
break;
case 1:
str = "Storage controllers.";
break;
case 2:
str = "Network controllers";
break;
case 3:
str = "Display controllers.";
break;
case 4:
str = "Multimedia devices.";
break;
case 5:
str = "Memory controllers.";
break;
case 6:
str = "Bridges.";
break;
case 7:
str = "Communication controllers.";
break;
case 8:
str = "System peripherals.";
break;
case 9:
str = "IO device controllers.";
break;
case 10:
str = "Dock station.";
break;
case 11:
str = "Processors.";
break;
case 12:
str = "Serial bus controllers.";
break;
case 13:
str = "Wireless interface controllers.";
break;
}
return str;
}
char* getIntPinType(ui reg){//decipher Interrupt pin
char* str;
switch (reg) {
case 0:
str = "-";
break;
case 1:
str = "INTA#";
break;
case 2:
str = "INTB#";
break;
case 3:
str = "INTC#";
break;
case 4:
str = "INTD#";
break;
default:
str = "Invalid Pin number";
break;
}
}
int main()
{
ui address = 0x80000000, vendorId, deviceId, result, headerType, interruptPin, addressMemory, classCodeReg;
if (iopl(3)) {
printf("I/O Privilege level change error: %s\nTry running under ROOT user\n", strerror(errno));
return 2;
}
else
{
printf("Access received!\n");
}
for(ui i = 0; i < 256; i++)//cycle for bus number
{
address &= 0xFF00FFFF;
address |= i << 16;
for(ui j = 0; j < 32; j++)//cycle for device number
{
address &= 0xFFFF07FF;https://www.youtube.com/watch?v=NxXX1pClpkY
address |= j << 11;
for(ui k = 0; k < 8; k++)//cycle for function number
{
address &= 0xFFFFF8FF;
address |= k << 8;
outl(address, 0xCF8);
result = inl(0xCFC);
if(result != 0xFFFFFFFF){//check if device is connected
printf("%d:%d:%d\n", i, j, k);
vendorId = result & 0x0000FFFF;
deviceId = (result & 0xFFFF0000) >> 16;
for(ui m = 0; m < PCI_VENTABLE_LEN; m++)//searching for vendorId in PciVenTable[], where PCI_VENTABLE_LEN is size of this array
if(vendorId == PciVenTable[m].VendorId)
printf("Vendor: %x -> %s\n", PciVenTable[m].VendorId, PciVenTable[m].VendorName);
for(ui n = 0; n < PCI_DEVTABLE_LEN; n++)//searching for deviceId in PciDevTable[], where PCI_DEVTABLE_LEN is size of this array
if((deviceId == PciDevTable[n].DeviceId) && (vendorId == PciDevTable[n].VendorId))
printf("Device: %x -> %s\n", PciDevTable[n].DeviceId, PciDevTable[n].DeviceName);
outl((address & 0xFFFFFF03) | 0x0000000C, 0xCF8);
headerType = (inl(0xCFC) & 0x0800000) >> 23;
if(headerType == 0){//check if device is bridge
printf("\nNot Bridge\n\n");
outl((address & 0xFFFFFF03) | 0x0000003C, 0xCF8);
interruptPin = (inl(0xCFC) >> 8) & 0xFF;
printf("Interrupt Pin: %x -> %s\n", interruptPin, getIntPinType(interruptPin));
ui regNum = 0x10, delta = 0x04, regType, counter = 1;//start with 0x10 address adding 0x04 to look for each register
printf("BARs:\n\n");
while(regNum != 0x28){//cycle for analyzing BAR registers (0 - Memory reg, 1 - I/O space reg)
outl(address & 0xFFFFFF03|regNum, 0xCF8);
regType = (inl(0xCFC) & 0x1);
outl(address & 0xFFFFFF03|regNum, 0xCF8);
addressMemory = inl(0xCFC);
printf("Reg%d: ", counter);
if(addressMemory == 0){
printf("Unused register\n");
}
else if(regType == 0){//check if memory
printf("Memory address register\n");
}
else if(regType == 1){//check if IO
printf("I/O space register: Base address - %x\n", addressMemory);
}
regNum += delta;
counter++;
}
outl((address & 0xFFFFFF03) | 0x08, 0xCF8);
classCodeReg = inl(0xCFC) >> 8;
ui baseClassCode = classCodeReg >> 16;
printf("Base class code: %x -> %s\n", baseClassCode, getBaseClassName(baseClassCode));//output number of classcode and deciphering this field
}
printf("---------------------------------\n");
}
}
}
}
return 0;
}
User contributions licensed under CC BY-SA 3.0