From cfd42550fc57c0ea900f8b302eb38b8c88905d5d Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Sun, 17 Sep 2023 15:22:58 -0400 Subject: [PATCH] Add struct definitions for all PCI header types --- src/hulk/pci.d | 157 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 139 insertions(+), 18 deletions(-) diff --git a/src/hulk/pci.d b/src/hulk/pci.d index aab2667..b9be213 100644 --- a/src/hulk/pci.d +++ b/src/hulk/pci.d @@ -220,32 +220,153 @@ struct Pci } } - struct Header + static struct Configuration { - 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; + static struct HeaderType0 + { + 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; + + uint[6] base_addresses; + uint cardbus_cis_pointer; + ushort subsystem_vendor_id; + ushort subsystem_id; + uint expansion_rom_base_address; + ubyte capabilities_pointer; + ubyte[7] _reserved; + ubyte interrupt_line; + ubyte interrupt_pin; + ubyte min_grant; + ubyte max_latency; + } + + /** + * PCI configuration format for header type 1 (PCI-to-PCI bridge). + */ + static struct HeaderType1 + { + 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; + + uint[2] base_addresses; + ubyte primary_bus_nr; + ubyte secondary_bus_nr; + ubyte subordinate_bus_nr; + ubyte secondary_latency_timer; + ubyte io_base; + ubyte io_limit; + ushort secondary_status; + ushort memory_base; + ushort memory_limit; + ushort prefetchable_memory_base; + ushort prefetchable_memory_limit; + uint prefetchable_base_high; + uint prefetchable_limit_high; + ushort io_base_high; + ushort io_limit_high; + ubyte capability_pointer; + ubyte[3] _reserved; + uint expansion_rom_base_address; + ubyte interrupt_line; + ubyte interrupt_pin; + ushort bridge_control; + } + + /** + * PCI configuration format for header type 2 (PCI-to-CardBus bridge). + */ + static struct HeaderType2 + { + 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; + + uint cardbus_base_address; + ubyte capability_list_offset; + ubyte _reserved; + ushort secondary_status; + ubyte pci_bus_nr; + ubyte cardbus_bus_nr; + ubyte subordinate_bus_nr; + ubyte cardbus_latency_timer; + uint base_address_0; + uint memory_limit_0; + uint base_address_1; + uint memory_limit_1; + uint io_base_address_0; + uint io_limit_0; + uint io_base_address_1; + uint io_limit_1; + ubyte interrupt_line; + ubyte interrupt_pin; + ushort bridge_control; + ushort subsystem_device_id; + ushort subsystem_vendor_id; + uint legacy_base_address; + } + + union + { + struct + { + 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; + } + HeaderType0 header0; + HeaderType1 header1; + HeaderType2 header2; + } } 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) + 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)", - header.vendor_id, header.device_id, - header.class_id, header.subclass_id, header.interface_id, + 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 && (header.header_type & 0x80u) != 0u) + if (function_nr == 0 && (config.header_type & 0x80u) != 0u) { for (function_nr = 1u; function_nr < MAX_FUNCTIONS_PER_DEVICE; function_nr++) {