Scan PCI devices via MCFG table
This commit is contained in:
parent
ba0befa21b
commit
673ce8f097
@ -94,20 +94,9 @@ struct Acpi
|
||||
uint[2] _reserved;
|
||||
SGMADesc[0] sgma_descs;
|
||||
|
||||
void initialize()
|
||||
size_t n_sgma_descs()
|
||||
{
|
||||
Klog.writefln("MCFG length = %u", header.length);
|
||||
size_t n_sgma_descs = (header.length - MCFG.sgma_descs.offsetof) / MCFG.SGMADesc.sizeof;
|
||||
Klog.writefln("# SGMA descriptors = %u", (header.length - MCFG.sgma_descs.offsetof) / MCFG.SGMADesc.sizeof);
|
||||
for (size_t i = 0; i < n_sgma_descs; i++)
|
||||
{
|
||||
Klog.writefln("SGMA %u: SG %u; Bus %u-%u; addr %p",
|
||||
i,
|
||||
sgma_descs[i].pci_segment_group_number,
|
||||
sgma_descs[i].start_pci_bus_number,
|
||||
sgma_descs[i].end_pci_bus_number,
|
||||
sgma_descs[i].base_address);
|
||||
}
|
||||
return (header.length - MCFG.sgma_descs.offsetof) / MCFG.SGMADesc.sizeof;
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,7 +147,6 @@ struct Acpi
|
||||
else if (signature == MCFG_SIGNATURE)
|
||||
{
|
||||
mcfg = cast(MCFG *)address;
|
||||
mcfg.initialize();
|
||||
}
|
||||
}
|
||||
if (madt == null)
|
||||
|
@ -6,6 +6,7 @@ import hulk.hurl;
|
||||
import hulk.hurl.a1;
|
||||
import hulk.range;
|
||||
import hulk.usb.xhci;
|
||||
import hulk.acpi;
|
||||
|
||||
struct Pci
|
||||
{
|
||||
@ -15,6 +16,10 @@ struct Pci
|
||||
/* IO address for PCI configuration data. */
|
||||
enum IO_ADDR_CONFIG_DATA = 0xCFCu;
|
||||
|
||||
enum MAX_DEVICES_PER_BUS = 32;
|
||||
|
||||
enum MAX_FUNCTIONS_PER_DEVICE = 8;
|
||||
|
||||
struct Address
|
||||
{
|
||||
/** Bus number (0-255). */
|
||||
@ -207,7 +212,7 @@ struct Pci
|
||||
device.initialize(address, vendor_id, device_id);
|
||||
if (device.multifunction)
|
||||
{
|
||||
for (address.function_nr = 1u; address.function_nr < 8u; address.function_nr++)
|
||||
for (address.function_nr = 1u; address.function_nr < MAX_FUNCTIONS_PER_DEVICE; address.function_nr++)
|
||||
{
|
||||
scan(address);
|
||||
}
|
||||
@ -215,16 +220,74 @@ struct Pci
|
||||
}
|
||||
}
|
||||
|
||||
struct Header
|
||||
{
|
||||
ushort vendor_id;
|
||||
ushort device_id;
|
||||
ushort command;
|
||||
ushort status;
|
||||
ubyte revision_id;
|
||||
ubyte interface_id;
|
||||
ubyte subclass_id;
|
||||
ubyte class_id;
|
||||
ubyte cache_line_size;
|
||||
ubyte latency_timer;
|
||||
ubyte header_type;
|
||||
ubyte bist;
|
||||
}
|
||||
|
||||
private static void scan(ubyte bus_nr, ubyte device_nr, ubyte function_nr, ulong config_address)
|
||||
{
|
||||
Header * header = cast(Header *)config_address;
|
||||
if (header.vendor_id != 0xFFFFu)
|
||||
{
|
||||
Klog.writefln("Found PCI device %04x:%04x (%02x:%02x:%02x) at %02u:%02u.%u (%p)",
|
||||
header.vendor_id, header.device_id,
|
||||
header.class_id, header.subclass_id, header.interface_id,
|
||||
bus_nr, device_nr, function_nr, config_address);
|
||||
if (function_nr == 0 && (header.header_type & 0x80u) != 0u)
|
||||
{
|
||||
for (function_nr = 1u; function_nr < MAX_FUNCTIONS_PER_DEVICE; function_nr++)
|
||||
{
|
||||
config_address += PAGE_SIZE;
|
||||
scan(bus_nr, device_nr, function_nr, config_address);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void initialize()
|
||||
{
|
||||
Klog.writefln("Scanning PCI devices...");
|
||||
for (uint bus_nr = 0u; bus_nr < 256u; bus_nr++)
|
||||
{
|
||||
for (ubyte device_nr = 0u; device_nr < 32u; device_nr++)
|
||||
for (ubyte device_nr = 0u; device_nr < MAX_DEVICES_PER_BUS; device_nr++)
|
||||
{
|
||||
scan(Address(cast(ubyte)bus_nr, device_nr, 0u));
|
||||
}
|
||||
}
|
||||
Klog.writefln("PCI scan complete.");
|
||||
|
||||
Klog.writefln("MCFG PCI scan...");
|
||||
size_t n_sgma_descs = Acpi.mcfg.n_sgma_descs;
|
||||
for (size_t i = 0u; i < n_sgma_descs; i++)
|
||||
{
|
||||
Acpi.MCFG.SGMADesc * sgma_desc = &Acpi.mcfg.sgma_descs[i];
|
||||
ulong base_address = sgma_desc.base_address;
|
||||
uint start_pci_bus = sgma_desc.start_pci_bus_number;
|
||||
uint end_pci_bus = sgma_desc.end_pci_bus_number;
|
||||
ulong n_buses = (end_pci_bus - start_pci_bus) + 1u;
|
||||
ulong map_length = PAGE_SIZE * MAX_FUNCTIONS_PER_DEVICE * MAX_DEVICES_PER_BUS * n_buses;
|
||||
Hurl.identity_map_range(base_address, map_length, PT_DISABLE_CACHE | PT_NO_EXECUTE);
|
||||
for (uint bus_nr = start_pci_bus; bus_nr <= end_pci_bus; bus_nr++)
|
||||
{
|
||||
for (ubyte device_nr = 0u; device_nr < MAX_DEVICES_PER_BUS; device_nr++)
|
||||
{
|
||||
ulong device_address = base_address + ((bus_nr - start_pci_bus) * (MAX_DEVICES_PER_BUS * MAX_FUNCTIONS_PER_DEVICE) + device_nr * MAX_FUNCTIONS_PER_DEVICE) * PAGE_SIZE;
|
||||
scan(cast(ubyte)bus_nr, device_nr, 0u, device_address);
|
||||
}
|
||||
}
|
||||
}
|
||||
Klog.writefln("PCI scan 2 complete.");
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user