From 7a4edf38f0938ad05a20dd0e4824435a42bc340a Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Thu, 8 Jun 2023 20:28:32 -0400 Subject: [PATCH] Scan for multi-function PCI devices --- src/hulk/pci.d | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/hulk/pci.d b/src/hulk/pci.d index 754bf28..f80a336 100644 --- a/src/hulk/pci.d +++ b/src/hulk/pci.d @@ -26,9 +26,9 @@ struct Pci } } - private static uint read_config_register(uint bus_id, uint device_idx, uint register_id) + private static uint read_config_register(uint bus_id, uint device_idx, uint function_idx, uint register_id) { - uint addr = 0x8000_0000u | (bus_id << 16u) | (device_idx << 11u) | (register_id << 2u); + uint addr = 0x8000_0000u | (bus_id << 16u) | (device_idx << 11u) | (function_idx << 8u) | (register_id << 2u); out32(IO_ADDR_CONFIG_ADDRESS, addr); return in32(IO_ADDR_CONFIG_DATA); } @@ -59,22 +59,34 @@ struct Pci } } - private static void scan(uint bus_id, uint device_idx) + private static void scan(uint bus_id, uint device_idx, uint function_idx) { - ulong reg0 = read_config_register(bus_id, device_idx, 0u); + ulong reg0 = read_config_register(bus_id, device_idx, function_idx, 0u); if (reg0 != 0xFFFFFFFFu) { - uint reg2 = read_config_register(bus_id, device_idx, 2u); + uint reg2 = read_config_register(bus_id, device_idx, function_idx, 2u); ushort vendor_id = reg0 & 0xFFFFu; ushort device_id = (reg0 >> 16u) & 0xFFFFu; ubyte class_id = (reg2 >> 24u) & 0xFFu; ubyte subclass_id = (reg2 >> 16u) & 0xFFu; ubyte if_id = (reg2 >> 8u) & 0xFFu; - Klog.writefln("Found PCI device %04x:%04x (%02x:%02x:%02x) at %02u:%02u", + Klog.writefln("Found PCI device %04x:%04x (%02x:%02x:%02x) at %02u:%02u.%u", vendor_id, device_id, class_id, subclass_id, if_id, - bus_id, device_idx); + bus_id, device_idx, function_idx); init_device(class_id, subclass_id, if_id); + if (function_idx == 0u) + { + uint reg3 = read_config_register(bus_id, device_idx, function_idx, 3u); + if ((reg3 & (1u << 23u)) != 0u) + { + /* Multi-function device found. */ + for (function_idx = 1u; function_idx < 8u; function_idx++) + { + scan(bus_id, device_idx, function_idx); + } + } + } } } @@ -85,7 +97,7 @@ struct Pci { for (uint device_idx = 0u; device_idx < 32u; device_idx++) { - scan(bus_id, device_idx); + scan(bus_id, device_idx, 0u); } } Klog.writefln("PCI scan complete.");