Files
sdos/src/pci.c
T

92 lines
2.7 KiB
C

#include "../include/pci.h"
#include "../include/system.h"
#include "../include/port.h"
#include "../include/scrn.h"
uint32_t Read(uint16_t busNumber, uint16_t deviceNumber, uint16_t functionNumber, uint32_t registerOffset)
{
puts("Read ");
puts(int_to_string(functionNumber, 10));
puts("\n");
uint32_t id =
0x1 << 31
| ((busNumber & 0xFF) << 16)
| ((deviceNumber & 0x1F) << 11)
| ((functionNumber & 0x07) << 8)
| (registerOffset & 0xFC);
Write32Bit(0xCF8, id);
uint32_t result = Read32Bit(0xCFC);
return result >> (8 * (registerOffset %4));
}
void Write(uint16_t busNumber, uint16_t deviceNumber, uint16_t functionNumber, uint32_t registerOffset, uint32_t value)
{
uint32_t id =
0x1 << 31
| ((busNumber & 0xFF) << 16)
| ((deviceNumber & 0x1F) << 11)
| ((functionNumber & 0x07) << 8)
| (registerOffset & 0xFC);
Write32Bit(0xCF8, id);
Write32Bit(0xCFC, value);
}
bool DeviceHasFunctions(uint16_t bus, uint16_t device)
{
//Checks the 7th bit to determine if the device has a function.
return Read(bus, device, 0, 0x0E) & (1 << 7);
}
void EnumPCISubsystem()
{
for(int bus = 0; bus < 8; bus++)
{
for(int device = 0; device < 32; device++)
{
int functionCount = DeviceHasFunctions(bus, device) ? 8 : 1;//8 or 1
for(int function = 0; function < functionCount; function++)
{
//puts(", Function ");
//puts(int_to_string(function, 16));
struct DeviceDescriptor dev = {0};
dev = GetDeviceDescriptor(bus, device, function);
if(dev.VendorId == 0x0000 || dev.VendorId == 0xFFFF)
break;//Break loop, no more funcitons.
//puts("PCI BUS ");
//puts(int_to_string(bus, 16));
//puts("Device ");
//puts(int_to_string(device, 16));
//puts(" = Vendor ");
//puts(int_to_string(dev.VendorId, 16));
//puts(", Device ");
//puts(int_to_string(dev.DeviceId, 16));
//puts(" Class ");
//puts(int_to_string(dev.ClassId, 16));
//puts("\n");
}
}
}
}
struct DeviceDescriptor GetDeviceDescriptor(uint16_t busNumber, uint16_t deviceNumber, uint16_t functionNumber)
{
struct DeviceDescriptor result;
result.Bus = busNumber;
result.Device = deviceNumber;
result.Function = functionNumber;
result.VendorId = Read(busNumber, deviceNumber, functionNumber, 0x00);
result.DeviceId = Read(busNumber, deviceNumber, functionNumber, 0x02);
result.ClassId = Read(busNumber, deviceNumber, functionNumber, 0x0B);
result.SubClassId = Read(busNumber, deviceNumber, functionNumber, 0x0A);
result.InterfaceId = Read(busNumber, deviceNumber, functionNumber, 0x09);
result.Revision = Read(busNumber, deviceNumber, functionNumber, 0x08);
result.Interrupt = Read(busNumber, deviceNumber, functionNumber, 0x3C);
return result;
}