Add struct definitions for all PCI header types

This commit is contained in:
Josh Holtrop 2023-09-17 15:22:58 -04:00
parent 673ce8f097
commit cfd42550fc

View File

@ -220,32 +220,153 @@ struct Pci
} }
} }
struct Header static struct Configuration
{ {
ushort vendor_id; static struct HeaderType0
ushort device_id; {
ushort command; ushort vendor_id;
ushort status; ushort device_id;
ubyte revision_id; ushort command;
ubyte interface_id; ushort status;
ubyte subclass_id; ubyte revision_id;
ubyte class_id; ubyte interface_id;
ubyte cache_line_size; ubyte subclass_id;
ubyte latency_timer; ubyte class_id;
ubyte header_type; ubyte cache_line_size;
ubyte bist; 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) private static void scan(ubyte bus_nr, ubyte device_nr, ubyte function_nr, ulong config_address)
{ {
Header * header = cast(Header *)config_address; Configuration * config = cast(Configuration *)config_address;
if (header.vendor_id != 0xFFFFu) if (config.vendor_id != 0xFFFFu)
{ {
Klog.writefln("Found PCI device %04x:%04x (%02x:%02x:%02x) at %02u:%02u.%u (%p)", Klog.writefln("Found PCI device %04x:%04x (%02x:%02x:%02x) at %02u:%02u.%u (%p)",
header.vendor_id, header.device_id, config.vendor_id, config.device_id,
header.class_id, header.subclass_id, header.interface_id, config.class_id, config.subclass_id, config.interface_id,
bus_nr, device_nr, function_nr, config_address); 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++) for (function_nr = 1u; function_nr < MAX_FUNCTIONS_PER_DEVICE; function_nr++)
{ {