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)
{
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;
}
struct Device
static struct Device
{
Configuration * config;
Address address;
ushort vendor_id;
ushort device_id;
ubyte class_id;
ubyte subclass_id;
ubyte if_id;
bool multifunction;
ubyte header_type;
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.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",
vendor_id, device_id,
class_id, subclass_id, if_id,
config.vendor_id, config.device_id,
config.class_id, config.subclass_id, config.interface_id,
address.bus_nr, address.device_nr, address.function_nr);
uint reg3 = read_config_register(address, 3u);
header_type = (reg3 >> 16u) & 0x7Fu;
multifunction = (address.function_nr == 0u) && ((reg3 & (1u << 23u)) != 0u);
multifunction = (address.function_nr == 0u) && ((config.header_type & 0x80u) != 0u);
ubyte header_type = config.header_type & 0x7Fu;
if (header_type == 0u)
{
@ -74,10 +63,10 @@ struct Pci
size_t range_index;
uint[2] r;
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. */
r[0] = read_config_register(address, reg_no);
r[0] = config.header0.base_addresses[bar_idx];
/* Skip zeroed BARs. */
if (r[0] == 0u)
{
@ -95,11 +84,11 @@ struct Pci
/* 32-bit region. */
r[1] = 0u;
}
else if ((bar_type == 2u) && (reg_no < 9u))
else if ((bar_type == 2u) && (bar_idx < 5u))
{
/* 64-bit region. */
is_64bit = true;
r[1] = read_config_register(address, reg_no + 1);
r[1] = config.header0.base_addresses[bar_idx + 1];
}
else
{
@ -107,14 +96,14 @@ struct Pci
}
/* Determine the region length. */
write_config_register(address, reg_no, 0xFFFF_FFFFu);
s[0] = read_config_register(address, reg_no);
write_config_register(address, reg_no, r[0]);
config.header0.base_addresses[bar_idx] = 0xFFFF_FFFFu;
s[0] = config.header0.base_addresses[bar_idx];
config.header0.base_addresses[bar_idx] = r[0];
if (is_64bit)
{
write_config_register(address, reg_no + 1, 0xFFFF_FFFFu);
s[1] = read_config_register(address, reg_no + 1);
write_config_register(address, reg_no + 1, r[1]);
config.header0.base_addresses[bar_idx + 1] = 0xFFFF_FFFFu;
s[1] = config.header0.base_addresses[bar_idx + 1];
config.header0.base_addresses[bar_idx + 1] = r[1];
}
else
{
@ -129,20 +118,20 @@ struct Pci
range_index++;
if (is_64bit)
{
reg_no++;
bar_idx++;
}
}
}
private void spawn_device_instance()
{
switch (class_id)
switch (config.class_id)
{
case SerialBusController.ID:
switch (subclass_id)
switch (config.subclass_id)
{
case SerialBusController.USBController.ID:
switch (if_id)
switch (config.interface_id)
{
case SerialBusController.USBController.XHCIController.ID:
XHCI.build(&this);
@ -201,25 +190,6 @@ struct Pci
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 HeaderType0
@ -362,11 +332,9 @@ struct Pci
Configuration * config = cast(Configuration *)config_address;
if (config.vendor_id != 0xFFFFu)
{
Klog.writefln("Found PCI device %04x:%04x (%02x:%02x:%02x) at %02u:%02u.%u (%p)",
config.vendor_id, config.device_id,
config.class_id, config.subclass_id, config.interface_id,
bus_nr, device_nr, function_nr, config_address);
if (function_nr == 0 && (config.header_type & 0x80u) != 0u)
Device * device = A1.allocate!Device();
device.initialize(Address(bus_nr, device_nr, function_nr), config);
if (device.multifunction)
{
for (function_nr = 1u; function_nr < MAX_FUNCTIONS_PER_DEVICE; function_nr++)
{
@ -380,16 +348,6 @@ struct Pci
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 < 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++)
{
@ -399,7 +357,7 @@ struct Pci
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);
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 (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.");
}
}