diff --git a/headers/os/drivers/PCI.h b/headers/os/drivers/PCI.h index 53bb1040a6..da33102b62 100644 --- a/headers/os/drivers/PCI.h +++ b/headers/os/drivers/PCI.h @@ -90,6 +90,25 @@ typedef struct pci_info { struct { ushort subsystem_id; /* subsystem (add-in card) id */ ushort subsystem_vendor_id; /* subsystem (add-in card) vendor id */ + +#ifdef __HAIKU_PCI_BUS_MANAGER_TESTING + // for testing only, not final (do not use!): + uchar primary_bus; + uchar secondary_bus; + uchar subordinate_bus; + uchar secondary_latency; + ushort reserved; + ulong memory_base; + ulong memory_limit; + ulong memory_base_upper32; + ulong memory_limit_upper32; + ulong io_base; + ulong io_limit; + ulong io_base_upper32; + ulong io_limit_upper32; + ushort secondary_status; + uchar bridge_control; +#endif /* __HAIKU_PCI_BUS_MANAGER_TESTING */ } h2; } u; } pci_info; diff --git a/src/add-ons/kernel/bus_managers/pci/pci.cpp b/src/add-ons/kernel/bus_managers/pci/pci.cpp index 63eb2f1ebc..fa3a6bf102 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci.cpp @@ -7,6 +7,7 @@ #include +#define __HAIKU_PCI_BUS_MANAGER_TESTING 1 #include #include "util/kernel_cpp.h" @@ -258,7 +259,7 @@ void PCI::ReadPciHeaderInfo(PCIDev *dev) { switch (dev->info.header_type & PCI_header_type_mask) { - case 0: + case PCI_header_type_generic: { // disable PCI device address decoding (io and memory) while BARs are modified uint16 pcicmd = pci_read_config(dev->bus, dev->dev, dev->func, PCI_command, 2); @@ -291,7 +292,7 @@ PCI::ReadPciHeaderInfo(PCIDev *dev) break; } - case 1: + case PCI_header_type_PCI_to_PCI_bridge: { // disable PCI device address decoding (io and memory) while BARs are modified uint16 pcicmd = pci_read_config(dev->bus, dev->dev, dev->func, PCI_command, 2); @@ -330,12 +331,37 @@ PCI::ReadPciHeaderInfo(PCIDev *dev) dev->info.u.h1.io_limit_upper16 = pci_read_config(dev->bus, dev->dev, dev->func, PCI_io_limit_upper16, 2); dev->info.u.h1.interrupt_line = pci_read_config(dev->bus, dev->dev, dev->func, PCI_interrupt_line, 1); dev->info.u.h1.interrupt_pin = pci_read_config(dev->bus, dev->dev, dev->func, PCI_interrupt_pin, 1); - dev->info.u.h1.bridge_control = pci_read_config(dev->bus, dev->dev, dev->func, PCI_bridge_control, 2); + dev->info.u.h1.bridge_control = pci_read_config(dev->bus, dev->dev, dev->func, PCI_bridge_control, 2); + dev->info.u.h1.subsystem_id = pci_read_config(dev->bus, dev->dev, dev->func, PCI_sub_device_id_1, 2); + dev->info.u.h1.subsystem_vendor_id = pci_read_config(dev->bus, dev->dev, dev->func, PCI_sub_vendor_id_1, 2); + break; + } + + case PCI_header_type_cardbus: + { + // for testing only, not final: + dev->info.u.h2.subsystem_id = pci_read_config(dev->bus, dev->dev, dev->func, PCI_sub_device_id_2, 2); + dev->info.u.h2.subsystem_vendor_id = pci_read_config(dev->bus, dev->dev, dev->func, PCI_sub_vendor_id_2, 2); + dev->info.u.h2.primary_bus = pci_read_config(dev->bus, dev->dev, dev->func, PCI_primary_bus_2, 1); + dev->info.u.h2.secondary_bus = pci_read_config(dev->bus, dev->dev, dev->func, PCI_secondary_bus_2, 1); + dev->info.u.h2.subordinate_bus = pci_read_config(dev->bus, dev->dev, dev->func, PCI_subordinate_bus_2, 1); + dev->info.u.h2.secondary_latency = pci_read_config(dev->bus, dev->dev, dev->func, PCI_secondary_latency_2, 1); + dev->info.u.h2.reserved = 0; + dev->info.u.h2.memory_base = pci_read_config(dev->bus, dev->dev, dev->func, PCI_memory_base0_2, 4); + dev->info.u.h2.memory_limit = pci_read_config(dev->bus, dev->dev, dev->func, PCI_memory_limit0_2, 4); + dev->info.u.h2.memory_base_upper32 = pci_read_config(dev->bus, dev->dev, dev->func, PCI_memory_base1_2, 4); + dev->info.u.h2.memory_limit_upper32 = pci_read_config(dev->bus, dev->dev, dev->func, PCI_memory_limit1_2, 4); + dev->info.u.h2.io_base = pci_read_config(dev->bus, dev->dev, dev->func, PCI_io_base0_2, 4); + dev->info.u.h2.io_limit = pci_read_config(dev->bus, dev->dev, dev->func, PCI_io_limit0_2, 4); + dev->info.u.h2.io_base_upper32 = pci_read_config(dev->bus, dev->dev, dev->func, PCI_io_base1_2, 4); + dev->info.u.h2.io_limit_upper32 = pci_read_config(dev->bus, dev->dev, dev->func, PCI_io_limit1_2, 4); + dev->info.u.h2.secondary_status = pci_read_config(dev->bus, dev->dev, dev->func, PCI_secondary_status_2, 2); + dev->info.u.h2.bridge_control = pci_read_config(dev->bus, dev->dev, dev->func, PCI_bridge_control_2, 1); break; } default: - TRACE(("PCI: Header type unknown (%d)\n", dev->info.header_type)); + TRACE(("PCI: Header type unknown (0x%02x)\n", dev->info.header_type)); break; } } diff --git a/src/add-ons/kernel/bus_managers/pci/pci_info.cpp b/src/add-ons/kernel/bus_managers/pci/pci_info.cpp index 7b6961b3bb..f40345fdbc 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_info.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci_info.cpp @@ -5,6 +5,7 @@ #include +#define __HAIKU_PCI_BUS_MANAGER_TESTING 1 #include #include #include "pci_info.h" @@ -19,29 +20,30 @@ #endif -void print_bridge_info(const pci_info *info, bool verbose); -void print_generic_info(const pci_info *info, bool verbose); -void print_capabilities(const pci_info *info); -void print_info_basic(const pci_info *info, bool verbose); void get_vendor_info(uint16 vendorID, const char **venShort, const char **venFull); void get_device_info(uint16 vendorID, uint16 deviceID, const char **devShort, const char **devFull); const char *get_class_info(uint8 class_base, uint8 class_sub, uint8 class_api); const char *get_capability_name(uint8 cap_id); -void -print_bridge_info(const pci_info *info, bool verbose) +static void +print_pci2pci_bridge_info(const pci_info *info, bool verbose) { + TRACE(("PCI: subsystem_id %04x, subsystem_vendor_id %04x\n", + info->u.h1.subsystem_id, info->u.h1.subsystem_vendor_id)); TRACE(("PCI: primary_bus %02x, secondary_bus %02x, subordinate_bus %02x, secondary_latency %02x\n", info->u.h1.primary_bus, info->u.h1.secondary_bus, info->u.h1.subordinate_bus, info->u.h1.secondary_latency)); - TRACE(("PCI: io_base %04x%02x, io_limit %04x%02x\n", - info->u.h1.io_base_upper16, info->u.h1.io_base, info->u.h1.io_limit_upper16, info->u.h1.io_limit)); + TRACE(("PCI: io_base_upper_16 %04x, io_base %02x\n", + info->u.h1.io_base_upper16, info->u.h1.io_base)); + TRACE(("PCI: io_limit_upper_16 %04x, io_limit %02x\n", + info->u.h1.io_limit_upper16, info->u.h1.io_limit)); TRACE(("PCI: memory_base %04x, memory_limit %04x\n", info->u.h1.memory_base, info->u.h1.memory_limit)); - TRACE(("PCI: prefetchable memory base %08lx%04x, limit %08lx%04x\n", - info->u.h1.prefetchable_memory_base_upper32, info->u.h1.prefetchable_memory_base, + TRACE(("PCI: prefetchable_memory_base_upper32 %08lx, prefetchable_memory_base %04x\n", + info->u.h1.prefetchable_memory_base_upper32, info->u.h1.prefetchable_memory_base)); + TRACE(("PCI: prefetchable_memory_limit_upper32 %08lx, prefetchable_memory_limit %04x\n", info->u.h1.prefetchable_memory_limit_upper32, info->u.h1.prefetchable_memory_limit)); - TRACE(("PCI: bridge_control %04x, secondary_status %04x\n", + TRACE(("PCI: bridge_control %02x, secondary_status %04x\n", info->u.h1.bridge_control, info->u.h1.secondary_status)); TRACE(("PCI: interrupt_line %02x, interrupt_pin %02x\n", info->u.h1.interrupt_line, info->u.h1.interrupt_pin)); @@ -54,7 +56,27 @@ print_bridge_info(const pci_info *info, bool verbose) } -void +static void +print_pci2cardbus_bridge_info(const pci_info *info, bool verbose) +{ + TRACE(("PCI: subsystem_id %04x, subsystem_vendor_id %04x\n", + info->u.h2.subsystem_id, info->u.h2.subsystem_vendor_id)); + TRACE(("PCI: primary_bus %02x, secondary_bus %02x, subordinate_bus %02x, secondary_latency %02x\n", + info->u.h2.primary_bus, info->u.h2.secondary_bus, info->u.h2.subordinate_bus, info->u.h2.secondary_latency)); + TRACE(("PCI: bridge_control %02x, secondary_status %04x\n", + info->u.h2.bridge_control, info->u.h2.secondary_status)); + TRACE(("PCI: memory_base_upper32 %08lx, memory_base %08lx\n", + info->u.h2.memory_base_upper32, info->u.h2.memory_base)); + TRACE(("PCI: memory_limit_upper32 %08lx, memory_limit %08lx\n", + info->u.h2.memory_limit_upper32, info->u.h2.memory_limit)); + TRACE(("PCI: io_base_upper32 %08lx, io_base %08lx\n", + info->u.h2.io_base_upper32, info->u.h2.io_base)); + TRACE(("PCI: io_limit_upper32 %08lx, io_limit %08lx\n", + info->u.h2.io_limit_upper32, info->u.h2.io_limit)); +} + + +static void print_generic_info(const pci_info *info, bool verbose) { TRACE(("PCI: ROM base host %08lx, pci %08lx, size %08lx\n", @@ -70,7 +92,7 @@ print_generic_info(const pci_info *info, bool verbose) } -void +static void print_capabilities(const pci_info *info) { uint16 status; @@ -85,8 +107,20 @@ print_capabilities(const pci_info *info) TRACE(("(not supported)\n")); return; } - - cap_ptr = pci_read_config(info->bus, info->device, info->function, PCI_capabilities_ptr, 1); + + switch (info->header_type & PCI_header_type_mask) { + case PCI_header_type_generic: + case PCI_header_type_PCI_to_PCI_bridge: + cap_ptr = pci_read_config(info->bus, info->device, info->function, PCI_capabilities_ptr, 1); + break; + case PCI_header_type_cardbus: + cap_ptr = pci_read_config(info->bus, info->device, info->function, PCI_capabilities_ptr_2, 1); + break; + default: + TRACE(("(unknown header type)\n")); + return; + } + cap_ptr &= ~3; if (!cap_ptr) { TRACE(("(empty list)\n")); @@ -114,7 +148,7 @@ print_capabilities(const pci_info *info) } -void +static void print_info_basic(const pci_info *info, bool verbose) { TRACE(("PCI: bus %2d, device %2d, function %2d: vendor %04x, device %04x, revision %02x\n", @@ -151,11 +185,14 @@ print_info_basic(const pci_info *info, bool verbose) info->line_size, info->latency, info->header_type, info->bist)); switch (info->header_type & PCI_header_type_mask) { - case 0: + case PCI_header_type_generic: print_generic_info(info, verbose); break; - case 1: - print_bridge_info(info, verbose); + case PCI_header_type_PCI_to_PCI_bridge: + print_pci2pci_bridge_info(info, verbose); + break; + case PCI_header_type_cardbus: + print_pci2cardbus_bridge_info(info, verbose); break; default: TRACE(("PCI: unknown header type\n"));