added experimental support for CardBus<->PCI bridges
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16049 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -90,6 +90,25 @@ typedef struct pci_info {
|
|||||||
struct {
|
struct {
|
||||||
ushort subsystem_id; /* subsystem (add-in card) id */
|
ushort subsystem_id; /* subsystem (add-in card) id */
|
||||||
ushort subsystem_vendor_id; /* subsystem (add-in card) vendor 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;
|
} h2;
|
||||||
} u;
|
} u;
|
||||||
} pci_info;
|
} pci_info;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
|
#define __HAIKU_PCI_BUS_MANAGER_TESTING 1
|
||||||
#include <PCI.h>
|
#include <PCI.h>
|
||||||
|
|
||||||
#include "util/kernel_cpp.h"
|
#include "util/kernel_cpp.h"
|
||||||
@@ -258,7 +259,7 @@ void
|
|||||||
PCI::ReadPciHeaderInfo(PCIDev *dev)
|
PCI::ReadPciHeaderInfo(PCIDev *dev)
|
||||||
{
|
{
|
||||||
switch (dev->info.header_type & PCI_header_type_mask) {
|
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
|
// 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);
|
uint16 pcicmd = pci_read_config(dev->bus, dev->dev, dev->func, PCI_command, 2);
|
||||||
@@ -291,7 +292,7 @@ PCI::ReadPciHeaderInfo(PCIDev *dev)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 1:
|
case PCI_header_type_PCI_to_PCI_bridge:
|
||||||
{
|
{
|
||||||
// disable PCI device address decoding (io and memory) while BARs are modified
|
// 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);
|
uint16 pcicmd = pci_read_config(dev->bus, dev->dev, dev->func, PCI_command, 2);
|
||||||
@@ -331,11 +332,36 @@ PCI::ReadPciHeaderInfo(PCIDev *dev)
|
|||||||
dev->info.u.h1.interrupt_line = pci_read_config(dev->bus, dev->dev, dev->func, PCI_interrupt_line, 1);
|
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.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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
|
#define __HAIKU_PCI_BUS_MANAGER_TESTING 1
|
||||||
#include <PCI.h>
|
#include <PCI.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "pci_info.h"
|
#include "pci_info.h"
|
||||||
@@ -19,29 +20,30 @@
|
|||||||
#endif
|
#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_vendor_info(uint16 vendorID, const char **venShort, const char **venFull);
|
||||||
void get_device_info(uint16 vendorID, uint16 deviceID, const char **devShort, const char **devFull);
|
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_class_info(uint8 class_base, uint8 class_sub, uint8 class_api);
|
||||||
const char *get_capability_name(uint8 cap_id);
|
const char *get_capability_name(uint8 cap_id);
|
||||||
|
|
||||||
|
|
||||||
void
|
static void
|
||||||
print_bridge_info(const pci_info *info, bool verbose)
|
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",
|
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));
|
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",
|
TRACE(("PCI: io_base_upper_16 %04x, io_base %02x\n",
|
||||||
info->u.h1.io_base_upper16, info->u.h1.io_base, info->u.h1.io_limit_upper16, info->u.h1.io_limit));
|
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",
|
TRACE(("PCI: memory_base %04x, memory_limit %04x\n",
|
||||||
info->u.h1.memory_base, info->u.h1.memory_limit));
|
info->u.h1.memory_base, info->u.h1.memory_limit));
|
||||||
TRACE(("PCI: prefetchable memory base %08lx%04x, limit %08lx%04x\n",
|
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,
|
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));
|
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));
|
info->u.h1.bridge_control, info->u.h1.secondary_status));
|
||||||
TRACE(("PCI: interrupt_line %02x, interrupt_pin %02x\n",
|
TRACE(("PCI: interrupt_line %02x, interrupt_pin %02x\n",
|
||||||
info->u.h1.interrupt_line, info->u.h1.interrupt_pin));
|
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)
|
print_generic_info(const pci_info *info, bool verbose)
|
||||||
{
|
{
|
||||||
TRACE(("PCI: ROM base host %08lx, pci %08lx, size %08lx\n",
|
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)
|
print_capabilities(const pci_info *info)
|
||||||
{
|
{
|
||||||
uint16 status;
|
uint16 status;
|
||||||
@@ -86,7 +108,19 @@ print_capabilities(const pci_info *info)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
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;
|
cap_ptr &= ~3;
|
||||||
if (!cap_ptr) {
|
if (!cap_ptr) {
|
||||||
TRACE(("(empty list)\n"));
|
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)
|
print_info_basic(const pci_info *info, bool verbose)
|
||||||
{
|
{
|
||||||
TRACE(("PCI: bus %2d, device %2d, function %2d: vendor %04x, device %04x, revision %02x\n",
|
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));
|
info->line_size, info->latency, info->header_type, info->bist));
|
||||||
|
|
||||||
switch (info->header_type & PCI_header_type_mask) {
|
switch (info->header_type & PCI_header_type_mask) {
|
||||||
case 0:
|
case PCI_header_type_generic:
|
||||||
print_generic_info(info, verbose);
|
print_generic_info(info, verbose);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case PCI_header_type_PCI_to_PCI_bridge:
|
||||||
print_bridge_info(info, verbose);
|
print_pci2pci_bridge_info(info, verbose);
|
||||||
|
break;
|
||||||
|
case PCI_header_type_cardbus:
|
||||||
|
print_pci2cardbus_bridge_info(info, verbose);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
TRACE(("PCI: unknown header type\n"));
|
TRACE(("PCI: unknown header type\n"));
|
||||||
|
|||||||
Reference in New Issue
Block a user