58 lines
1.5 KiB
C
58 lines
1.5 KiB
C
#include <lcrash/pci/pci.h>
|
|
|
|
#include <lcrash/mm/virt.h>
|
|
#include <lcrash/acpi/acpi.h>
|
|
#include <lcrash/debug/debug.h>
|
|
#include <lcrash/driver/sysbus.h>
|
|
|
|
bool PciIsPresent = false;
|
|
bool PciSupportsECM = false;
|
|
|
|
void* PciBusses[256] = {};
|
|
|
|
void PciScanDevice(u32 Bus, u32 Device) {
|
|
struct PciConfigurationSpaceHeader* DeviceHeader = (struct PciConfigurationSpaceHeader*)(PciBusses[Bus] + Device * 0x800);
|
|
|
|
// Is a device connected here?
|
|
if (DeviceHeader->VendorID != 0xFFFF) {
|
|
while (1) {}
|
|
}
|
|
}
|
|
|
|
void PciScanBus(u32 Bus) {
|
|
// Scan bus devices
|
|
for (int i = 0; i < 32; i++) PciScanDevice(Bus, i);
|
|
}
|
|
|
|
void PciInitialize() {
|
|
// Try to figure out if we have PCIe
|
|
if (!AcpiPresent()) Panic("Failed to initialize PCI");
|
|
|
|
struct AcpiMCFG* BridgeTable = AcpiGetTable("MCFG");
|
|
|
|
// Guess not
|
|
if (BridgeTable == NULL) Panic("Failed to find PCI bridge table");
|
|
|
|
// Take our pcie bridges
|
|
s32 Length = (BridgeTable->Header.Length - 44) / 16;
|
|
for (int i = 0; i < Length; i++) {
|
|
// Identity map our busses because linux doesn't do it for us
|
|
VmemMapMemory(
|
|
BridgeTable->Bridges[i].Address, BridgeTable->Bridges[i].Address,
|
|
(BridgeTable->Bridges[i].EndBus - BridgeTable->Bridges[i].StartBus) * 0x100000
|
|
);
|
|
|
|
for (int Bus = BridgeTable->Bridges[i].StartBus; Bus < BridgeTable->Bridges[i].EndBus; Bus++) {
|
|
PciBusses[Bus] = BridgeTable->Bridges[i].Address + (Bus - BridgeTable->Bridges[i].StartBus) * 0x100000;
|
|
}
|
|
}
|
|
|
|
// Scan the root bus
|
|
PciScanBus(0);
|
|
|
|
return;
|
|
}
|
|
|
|
bool PciPresent() { return PciIsPresent; }
|
|
bool PciePresent() { return PciSupportsECM; }
|