diff --git a/src/hulk/acpi.d b/src/hulk/acpi.d index 14f675f..d1e07ef 100644 --- a/src/hulk/acpi.d +++ b/src/hulk/acpi.d @@ -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); } } diff --git a/src/hulk/pci.d b/src/hulk/pci.d index b9be213..f2e93a0 100644 --- a/src/hulk/pci.d +++ b/src/hulk/pci.d @@ -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."); } }