Remove legacy PCI bus scanning

This commit is contained in:
Josh Holtrop 2023-09-17 16:13:37 -04:00
parent cfd42550fc
commit cda45b205d
2 changed files with 28 additions and 70 deletions

View File

@ -161,6 +161,6 @@ struct Acpi
private static void map_table(ulong address, ulong length) private static void map_table(ulong address, ulong length)
{ {
Hurl.identity_map_range(address, length, PT_DISABLE_CACHE | PT_NO_EXECUTE); Hurl.identity_map_range(address, length, PT_WRITABLE | PT_DISABLE_CACHE | PT_NO_EXECUTE);
} }
} }

View File

@ -32,34 +32,23 @@ struct Pci
ubyte function_nr; ubyte function_nr;
} }
struct Device static struct Device
{ {
Configuration * config;
Address address; Address address;
ushort vendor_id;
ushort device_id;
ubyte class_id;
ubyte subclass_id;
ubyte if_id;
bool multifunction; bool multifunction;
ubyte header_type;
Range[6] memory_ranges; Range[6] memory_ranges;
void initialize(Address address, ushort vendor_id, ushort device_id) void initialize(Address address, Configuration * config)
{ {
this.config = config;
this.address = address; this.address = address;
this.vendor_id = vendor_id;
this.device_id = device_id;
uint reg2 = read_config_register(address, 2u);
class_id = (reg2 >> 24u) & 0xFFu;
subclass_id = (reg2 >> 16u) & 0xFFu;
if_id = (reg2 >> 8u) & 0xFFu;
Klog.writefln("Found PCI device %04x:%04x (%02x:%02x:%02x) at %02u:%02u.%u", Klog.writefln("Found PCI device %04x:%04x (%02x:%02x:%02x) at %02u:%02u.%u",
vendor_id, device_id, config.vendor_id, config.device_id,
class_id, subclass_id, if_id, config.class_id, config.subclass_id, config.interface_id,
address.bus_nr, address.device_nr, address.function_nr); address.bus_nr, address.device_nr, address.function_nr);
uint reg3 = read_config_register(address, 3u); multifunction = (address.function_nr == 0u) && ((config.header_type & 0x80u) != 0u);
header_type = (reg3 >> 16u) & 0x7Fu; ubyte header_type = config.header_type & 0x7Fu;
multifunction = (address.function_nr == 0u) && ((reg3 & (1u << 23u)) != 0u);
if (header_type == 0u) if (header_type == 0u)
{ {
@ -74,10 +63,10 @@ struct Pci
size_t range_index; size_t range_index;
uint[2] r; uint[2] r;
uint[2] s; uint[2] s;
for (uint reg_no = 4u; reg_no <= 9u; reg_no++) for (uint bar_idx = 0u; bar_idx < config.header0.base_addresses.length; bar_idx++)
{ {
/* Read the BAR. */ /* Read the BAR. */
r[0] = read_config_register(address, reg_no); r[0] = config.header0.base_addresses[bar_idx];
/* Skip zeroed BARs. */ /* Skip zeroed BARs. */
if (r[0] == 0u) if (r[0] == 0u)
{ {
@ -95,11 +84,11 @@ struct Pci
/* 32-bit region. */ /* 32-bit region. */
r[1] = 0u; r[1] = 0u;
} }
else if ((bar_type == 2u) && (reg_no < 9u)) else if ((bar_type == 2u) && (bar_idx < 5u))
{ {
/* 64-bit region. */ /* 64-bit region. */
is_64bit = true; is_64bit = true;
r[1] = read_config_register(address, reg_no + 1); r[1] = config.header0.base_addresses[bar_idx + 1];
} }
else else
{ {
@ -107,14 +96,14 @@ struct Pci
} }
/* Determine the region length. */ /* Determine the region length. */
write_config_register(address, reg_no, 0xFFFF_FFFFu); config.header0.base_addresses[bar_idx] = 0xFFFF_FFFFu;
s[0] = read_config_register(address, reg_no); s[0] = config.header0.base_addresses[bar_idx];
write_config_register(address, reg_no, r[0]); config.header0.base_addresses[bar_idx] = r[0];
if (is_64bit) if (is_64bit)
{ {
write_config_register(address, reg_no + 1, 0xFFFF_FFFFu); config.header0.base_addresses[bar_idx + 1] = 0xFFFF_FFFFu;
s[1] = read_config_register(address, reg_no + 1); s[1] = config.header0.base_addresses[bar_idx + 1];
write_config_register(address, reg_no + 1, r[1]); config.header0.base_addresses[bar_idx + 1] = r[1];
} }
else else
{ {
@ -129,20 +118,20 @@ struct Pci
range_index++; range_index++;
if (is_64bit) if (is_64bit)
{ {
reg_no++; bar_idx++;
} }
} }
} }
private void spawn_device_instance() private void spawn_device_instance()
{ {
switch (class_id) switch (config.class_id)
{ {
case SerialBusController.ID: case SerialBusController.ID:
switch (subclass_id) switch (config.subclass_id)
{ {
case SerialBusController.USBController.ID: case SerialBusController.USBController.ID:
switch (if_id) switch (config.interface_id)
{ {
case SerialBusController.USBController.XHCIController.ID: case SerialBusController.USBController.XHCIController.ID:
XHCI.build(&this); XHCI.build(&this);
@ -201,25 +190,6 @@ struct Pci
out32(IO_ADDR_CONFIG_DATA, value); out32(IO_ADDR_CONFIG_DATA, value);
} }
private static void scan(Address address)
{
ulong reg0 = read_config_register(address, 0u);
if (reg0 != 0xFFFFFFFFu)
{
ushort vendor_id = reg0 & 0xFFFFu;
ushort device_id = (reg0 >> 16u) & 0xFFFFu;
Device * device = A1.allocate!Device();
device.initialize(address, vendor_id, device_id);
if (device.multifunction)
{
for (address.function_nr = 1u; address.function_nr < MAX_FUNCTIONS_PER_DEVICE; address.function_nr++)
{
scan(address);
}
}
}
}
static struct Configuration static struct Configuration
{ {
static struct HeaderType0 static struct HeaderType0
@ -362,11 +332,9 @@ struct Pci
Configuration * config = cast(Configuration *)config_address; Configuration * config = cast(Configuration *)config_address;
if (config.vendor_id != 0xFFFFu) if (config.vendor_id != 0xFFFFu)
{ {
Klog.writefln("Found PCI device %04x:%04x (%02x:%02x:%02x) at %02u:%02u.%u (%p)", Device * device = A1.allocate!Device();
config.vendor_id, config.device_id, device.initialize(Address(bus_nr, device_nr, function_nr), config);
config.class_id, config.subclass_id, config.interface_id, if (device.multifunction)
bus_nr, device_nr, function_nr, config_address);
if (function_nr == 0 && (config.header_type & 0x80u) != 0u)
{ {
for (function_nr = 1u; function_nr < MAX_FUNCTIONS_PER_DEVICE; function_nr++) for (function_nr = 1u; function_nr < MAX_FUNCTIONS_PER_DEVICE; function_nr++)
{ {
@ -380,16 +348,6 @@ struct Pci
public static void initialize() public static void initialize()
{ {
Klog.writefln("Scanning PCI devices..."); Klog.writefln("Scanning PCI devices...");
for (uint bus_nr = 0u; bus_nr < 256u; bus_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; size_t n_sgma_descs = Acpi.mcfg.n_sgma_descs;
for (size_t i = 0u; i < n_sgma_descs; i++) for (size_t i = 0u; i < n_sgma_descs; i++)
{ {
@ -399,7 +357,7 @@ struct Pci
uint end_pci_bus = sgma_desc.end_pci_bus_number; uint end_pci_bus = sgma_desc.end_pci_bus_number;
ulong n_buses = (end_pci_bus - start_pci_bus) + 1u; 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; 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); Hurl.identity_map_range(base_address, map_length, PT_WRITABLE | PT_DISABLE_CACHE | PT_NO_EXECUTE);
for (uint bus_nr = start_pci_bus; bus_nr <= end_pci_bus; bus_nr++) 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++) for (ubyte device_nr = 0u; device_nr < MAX_DEVICES_PER_BUS; device_nr++)
@ -409,6 +367,6 @@ struct Pci
} }
} }
} }
Klog.writefln("PCI scan 2 complete."); Klog.writefln("PCI scan complete.");
} }
} }