hrev45785 adds 1 changeset to branch 'master' old head: 0ebfc3e0327409c7feca98fa473c5bfd766cb56e new head: b027a0a2f750e957f109e9e872662aca67b4336f overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=b027a0a+%5E0ebfc3e ---------------------------------------------------------------------------- b027a0a: pci: change offset type to uint16 in config space API. * The config space is larger than 255, we need to use an uint16 to access offsets superior or equal to 256. The current API only proposes an uint8 for this. This change switches the offset parameter to the uint16 type. Axel hinted that the used values are the same with such a change (the doc says sign extended to 2 or 4 bytes). I checked with GCC2 and it's indeed the case when inspecting the memory. With GCC4, instructions are the same on function call. * prints info about extended capabilities. * struct pci_module_info and struct pci_device_module_info are extended with pci_find_extended_capability(). [ Jérôme Duval <jerome.duval@xxxxxxxxx> ] ---------------------------------------------------------------------------- Revision: hrev45785 Commit: b027a0a2f750e957f109e9e872662aca67b4336f URL: http://cgit.haiku-os.org/haiku/commit/?id=b027a0a Author: Jérôme Duval <jerome.duval@xxxxxxxxx> Date: Mon Jun 24 17:12:41 2013 UTC ---------------------------------------------------------------------------- 8 files changed, 151 insertions(+), 22 deletions(-) headers/os/drivers/PCI.h | 28 +++-- headers/os/drivers/bus/PCI.h | 6 +- src/add-ons/kernel/bus_managers/pci/pci.cpp | 4 +- src/add-ons/kernel/bus_managers/pci/pci.h | 4 +- .../kernel/bus_managers/pci/pci_device.cpp | 15 ++- src/add-ons/kernel/bus_managers/pci/pci_info.cpp | 109 +++++++++++++++++++ .../kernel/bus_managers/pci/pci_module.cpp | 3 +- .../kernel/bus_managers/pci/pci_private.h | 4 +- ---------------------------------------------------------------------------- diff --git a/headers/os/drivers/PCI.h b/headers/os/drivers/PCI.h index bff025f..1210349 100644 --- a/headers/os/drivers/PCI.h +++ b/headers/os/drivers/PCI.h @@ -131,18 +131,18 @@ struct pci_module_info { pci_info *info /* caller-supplied buffer for info */ ); uint32 (*read_pci_config) ( - uchar bus, /* bus number */ - uchar device, /* device # on bus */ - uchar function, /* function # in device */ - uchar offset, /* offset in configuration space */ - uchar size /* # bytes to read (1, 2 or 4) */ + uint8 bus, /* bus number */ + uint8 device, /* device # on bus */ + uint8 function, /* function # in device */ + uint16 offset, /* offset in configuration space */ + uint8 size /* # bytes to read (1, 2 or 4) */ ); void (*write_pci_config) ( - uchar bus, /* bus number */ - uchar device, /* device # on bus */ - uchar function, /* function # in device */ - uchar offset, /* offset in configuration space */ - uchar size, /* # bytes to write (1, 2 or 4) */ + uint8 bus, /* bus number */ + uint8 device, /* device # on bus */ + uint8 function, /* function # in device */ + uint16 offset, /* offset in configuration space */ + uint8 size, /* # bytes to write (1, 2 or 4) */ uint32 value /* value to write */ ); @@ -174,6 +174,14 @@ struct pci_module_info { uchar device, uchar function, uchar newInterruptLineValue); + + status_t (*find_pci_extended_capability) ( + uint8 bus, + uint8 device, + uint8 function, + uint16 cap_id, + uint16 *offset + ); }; #define B_PCI_MODULE_NAME "bus_managers/pci/v1" diff --git a/headers/os/drivers/bus/PCI.h b/headers/os/drivers/bus/PCI.h index fa362c7..f0816d3 100644 --- a/headers/os/drivers/bus/PCI.h +++ b/headers/os/drivers/bus/PCI.h @@ -27,13 +27,15 @@ typedef struct pci_device_module_info { void *(*ram_address)(pci_device *device, const void *physicalAddress); - uint32 (*read_pci_config)(pci_device *device, uint8 offset, + uint32 (*read_pci_config)(pci_device *device, uint16 offset, uint8 size); - void (*write_pci_config)(pci_device *device, uint8 offset, + void (*write_pci_config)(pci_device *device, uint16 offset, uint8 size, uint32 value); status_t (*find_pci_capability)(pci_device *device, uint8 capID, uint8 *offset); void (*get_pci_info)(pci_device *device, struct pci_info *info); + status_t (*find_pci_extended_capability)(pci_device *device, uint16 capID, + uint16 *offset); } pci_device_module_info; diff --git a/src/add-ons/kernel/bus_managers/pci/pci.cpp b/src/add-ons/kernel/bus_managers/pci/pci.cpp index 1b8a1c0..f13d492 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci.cpp @@ -43,7 +43,7 @@ pci_get_nth_pci_info(long index, pci_info *outInfo) uint32 -pci_read_config(uint8 virtualBus, uint8 device, uint8 function, uint8 offset, +pci_read_config(uint8 virtualBus, uint8 device, uint8 function, uint16 offset, uint8 size) { uint8 bus; @@ -62,7 +62,7 @@ pci_read_config(uint8 virtualBus, uint8 device, uint8 function, uint8 offset, void -pci_write_config(uint8 virtualBus, uint8 device, uint8 function, uint8 offset, +pci_write_config(uint8 virtualBus, uint8 device, uint8 function, uint16 offset, uint8 size, uint32 value) { uint8 bus; diff --git a/src/add-ons/kernel/bus_managers/pci/pci.h b/src/add-ons/kernel/bus_managers/pci/pci.h index 5ec5da5..2b5f57e 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.h +++ b/src/add-ons/kernel/bus_managers/pci/pci.h @@ -186,9 +186,9 @@ void pci_uninit(void); long pci_get_nth_pci_info(long index, pci_info *outInfo); uint32 pci_read_config(uint8 virtualBus, uint8 device, uint8 function, - uint8 offset, uint8 size); + uint16 offset, uint8 size); void pci_write_config(uint8 virtualBus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 value); + uint16 offset, uint8 size, uint32 value); void __pci_resolve_virtual_bus(uint8 virtualBus, uint8 *domain, uint8 *bus); diff --git a/src/add-ons/kernel/bus_managers/pci/pci_device.cpp b/src/add-ons/kernel/bus_managers/pci/pci_device.cpp index 32a885d..3d6f8e1 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_device.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci_device.cpp @@ -66,14 +66,14 @@ pci_device_write_io_32(pci_device* device, addr_t mappedIOAddress, uint32 value) static uint32 -pci_device_read_pci_config(pci_device* device, uint8 offset, uint8 size) +pci_device_read_pci_config(pci_device* device, uint16 offset, uint8 size) { return gPCI->ReadConfig(device->device, offset, size); } static void -pci_device_write_pci_config(pci_device* device, uint8 offset, uint8 size, +pci_device_write_pci_config(pci_device* device, uint16 offset, uint8 size, uint32 value) { gPCI->WriteConfig(device->device, offset, size, value); @@ -94,6 +94,14 @@ pci_device_find_capability(pci_device* device, uint8 capID, uint8* offset) } +static status_t +pci_device_find_extended_capability(pci_device* device, uint16 capID, + uint16* offset) +{ + return gPCI->FindExtendedCapability(device->device, capID, offset); +} + + static void pci_device_get_pci_info(pci_device* device, struct pci_info* info) { @@ -187,5 +195,6 @@ pci_device_module_info gPCIDeviceModule = { pci_device_read_pci_config, pci_device_write_pci_config, pci_device_find_capability, - pci_device_get_pci_info + pci_device_get_pci_info, + pci_device_find_extended_capability }; 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 ccc7ecf..3ff68d4 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_info.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci_info.cpp @@ -26,6 +26,7 @@ #endif const char *get_capability_name(uint8 cap_id); +const char *get_extended_capability_name(uint16 cap_id); static void @@ -177,6 +178,45 @@ print_capabilities(const pci_info *info) static void +print_extended_capabilities(const pci_info *info) +{ + if (pci_find_capability(info->bus, info->device, info->function, + PCI_cap_id_pcie, NULL) != B_OK) + return; + + uint16 capPointer = PCI_extended_capability; + uint32 capability = pci_read_config(info->bus, info->device, + info->function, capPointer, 4); + TRACE(("PCI: Extended capabilities: ")); + if (capability == 0 || capability == 0xffffffff) { + TRACE(("(empty list)\n")); + return; + } + + for (int i = 0; i < 48; i++) { + if (i) { + TRACE((", ")); + } + const char *name = get_extended_capability_name( + PCI_extcap_id(capability)); + if (name) { + TRACE(("%s", name)); + } else { + TRACE(("0x%04" B_PRIx32, PCI_extcap_id(capability))); + } + + capPointer = PCI_extcap_next_ptr(capability) & ~3; + if (capPointer < PCI_extended_capability) + break; + capability = pci_read_config(info->bus, info->device, info->function, + capPointer, 4); + } + + TRACE(("\n")); +} + + +static void print_info_basic(const pci_info *info, bool verbose) { uint8 domain; @@ -236,6 +276,7 @@ print_info_basic(const pci_info *info, bool verbose) } print_capabilities(info); + print_extended_capabilities(info); } @@ -298,3 +339,71 @@ get_capability_name(uint8 cap_id) } } + +const char * +get_extended_capability_name(uint16 cap_id) +{ + switch (cap_id) { + case PCI_extcap_id_aer: + return "Advanced Error Reporting"; + case PCI_extcap_id_vc: + return "Virtual Channel"; + case PCI_extcap_id_serial: + return "Serial Number"; + case PCI_extcap_id_power_budget: + return "Power Budgeting"; + case PCI_extcap_id_rcl_decl: + return "Root Complex Link Declaration"; + case PCI_extcap_id_rcil_ctl: + return "Root Complex Internal Link Control"; + case PCI_extcap_id_rcec_assoc: + return "Root Complex Event Collector Association"; + case PCI_extcap_id_mfvc: + return "MultiFunction Virtual Channel"; + case PCI_extcap_id_vc2: + return "Virtual Channel 2"; + case PCI_extcap_id_rcrb_header: + return "RCRB Header"; + case PCI_extcap_id_vendor: + return "Vendor Unique"; + case PCI_extcap_id_acs: + return "Access Control Services"; + case PCI_extcap_id_ari: + return "Alternative Routing Id Interpretation"; + case PCI_extcap_id_ats: + return "Address Translation Services"; + case PCI_extcap_id_srio_virtual: + return "Single Root I/O Virtualization"; + case PCI_extcap_id_mrio_virtual: + return "Multiple Root I/O Virtual"; + case PCI_extcap_id_multicast: + return "Multicast"; + case PCI_extcap_id_page_request: + return "Page Request"; + case PCI_extcap_id_amd: + return "AMD Reserved"; + case PCI_extcap_id_resizable_bar: + return "Resizable Bar"; + case PCI_extcap_id_dyn_power_alloc: + return "Dynamic Power Allocation"; + case PCI_extcap_id_tph_requester: + return "TPH Requester"; + case PCI_extcap_id_latency_tolerance: + return "Latency Tolerance Reporting"; + case PCI_extcap_id_2ndpcie: + return "Secondary PCIe"; + case PCI_extcap_id_pmux: + return "Protocol Multiplexing"; + case PCI_extcap_id_pasid: + return "Process Address Space Id"; + case PCI_extcap_id_ln_requester: + return "LN Requester"; + case PCI_extcap_id_dpc: + return "Downstream Porto Containment"; + case PCI_extcap_id_l1pm: + return "L1 Power Management Substates"; + default: + return NULL; + } +} + diff --git a/src/add-ons/kernel/bus_managers/pci/pci_module.cpp b/src/add-ons/kernel/bus_managers/pci/pci_module.cpp index fc71f6c..41227b1 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_module.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci_module.cpp @@ -67,7 +67,8 @@ static struct pci_module_info sOldPCIModule = { &pci_find_capability, &pci_reserve_device, &pci_unreserve_device, - &pci_update_interrupt_line + &pci_update_interrupt_line, + &pci_find_extended_capability }; module_dependency module_dependencies[] = { diff --git a/src/add-ons/kernel/bus_managers/pci/pci_private.h b/src/add-ons/kernel/bus_managers/pci/pci_private.h index 8804848..306b3d8 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_private.h +++ b/src/add-ons/kernel/bus_managers/pci/pci_private.h @@ -29,11 +29,11 @@ typedef struct pci_root_module_info { // read PCI config space uint32 (*read_pci_config)(uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size); + uint16 offset, uint8 size); // write PCI config space void (*write_pci_config)(uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 value); + uint16 offset, uint8 size, uint32 value); } pci_root_module_info; extern pci_root_module_info gPCIRootModule;