From 705263f5b30e9f6df57140be66bb1613c6e4ad1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 20 May 2008 17:53:54 +0000 Subject: [PATCH] * Some preparations for the new driver architecture: added FindCapability(), and {Read|Write}Config() that get a PCIDev structure, added a FindDevice() method. * Made sPCI a global gPCI, since the new PCI root/device modules will be using it directly. * Moved the functionality of pci_find_capability() into a new PCI::FindCapability() method. * Removed the redundant "Pci" from PCI::{Read|Write}PciConfig(), and GetNthPciInfo(). * Added PCI::_NumFunctions() that returns the number of functions instead of doing it manually every time. * Tried to honour the 80 character limit, as well as other coding style things a bit more. * Added '_' prefix for private method names. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25575 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/bus_managers/pci/pci.cpp | 1049 ++++++++++------- src/add-ons/kernel/bus_managers/pci/pci.h | 162 +-- .../kernel/bus_managers/pci/pci_fixup.cpp | 71 +- 3 files changed, 757 insertions(+), 525 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/pci/pci.cpp b/src/add-ons/kernel/bus_managers/pci/pci.cpp index dd87b15e4e..0ad527053e 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci.cpp @@ -1,7 +1,6 @@ /* - * Copyright 2006-2007, Marcus Overhagen. All rights reserved. - * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. - * Copyright 2003, Marcus Overhagen. All rights reserved. + * Copyright 2003-2008, Marcus Overhagen. All rights reserved. + * Copyright 2005-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * * Distributed under the terms of the MIT License. */ @@ -21,7 +20,9 @@ #define FLOW(x...) //#define FLOW(x...) dprintf(x) -static PCI *sPCI; + +PCI *gPCI; + // #pragma mark bus manager exports @@ -29,107 +30,74 @@ static PCI *sPCI; status_t pci_controller_add(pci_controller *controller, void *cookie) { - return sPCI->AddController(controller, cookie); + return gPCI->AddController(controller, cookie); } long pci_get_nth_pci_info(long index, pci_info *outInfo) { - return sPCI->GetNthPciInfo(index, outInfo); + return gPCI->GetNthInfo(index, outInfo); } uint32 -pci_read_config(uint8 virtualBus, uint8 device, uint8 function, uint8 offset, uint8 size) +pci_read_config(uint8 virtualBus, uint8 device, uint8 function, uint8 offset, + uint8 size) { uint8 bus; int domain; uint32 value; - - if (sPCI->ResolveVirtualBus(virtualBus, &domain, &bus) != B_OK) + + if (gPCI->ResolveVirtualBus(virtualBus, &domain, &bus) != B_OK) return 0xffffffff; - - if (sPCI->ReadPciConfig(domain, bus, device, function, offset, size, &value) != B_OK) + + if (gPCI->ReadConfig(domain, bus, device, function, offset, size, + &value) != B_OK) return 0xffffffff; - + return value; } void -pci_write_config(uint8 virtualBus, uint8 device, uint8 function, uint8 offset, uint8 size, uint32 value) +pci_write_config(uint8 virtualBus, uint8 device, uint8 function, uint8 offset, + uint8 size, uint32 value) { uint8 bus; int domain; - - if (sPCI->ResolveVirtualBus(virtualBus, &domain, &bus) != B_OK) + if (gPCI->ResolveVirtualBus(virtualBus, &domain, &bus) != B_OK) return; - - sPCI->WritePciConfig(domain, bus, device, function, offset, size, value); + + gPCI->WriteConfig(domain, bus, device, function, offset, size, value); } -status_t -pci_find_capability(uchar bus, uchar device, uchar function, uchar cap_id, uchar *offset) +status_t +pci_find_capability(uchar virtualBus, uchar device, uchar function, + uchar capID, uchar *offset) { - uint16 status; - uint8 header_type; - uint8 cap_ptr; - int i; - - if (!offset) { - TRACE_CAP("PCI: find_pci_capability ERROR %u:%u:%u capability %#02x offset NULL pointer\n", bus, device, function, cap_id); - return B_BAD_VALUE; - } - - status = pci_read_config(bus, device, function, PCI_status, 2); - if (!(status & PCI_status_capabilities)) { - TRACE_CAP("PCI: find_pci_capability ERROR %u:%u:%u capability %#02x not supported\n", bus, device, function, cap_id); + uint8 bus; + int domain; + if (gPCI->ResolveVirtualBus(virtualBus, &domain, &bus) != B_OK) return B_ERROR; - } - header_type = pci_read_config(bus, device, function, PCI_header_type, 1); - switch (header_type & PCI_header_type_mask) { - case PCI_header_type_generic: - case PCI_header_type_PCI_to_PCI_bridge: - cap_ptr = pci_read_config(bus, device, function, PCI_capabilities_ptr, 1); - break; - case PCI_header_type_cardbus: - cap_ptr = pci_read_config(bus, device, function, PCI_capabilities_ptr_2, 1); - break; - default: - TRACE_CAP("PCI: find_pci_capability ERROR %u:%u:%u capability %#02x unknown header type\n", bus, device, function, cap_id); - return B_ERROR; - } + return gPCI->FindCapability(domain, bus, device, function, capID, offset); +} - cap_ptr &= ~3; - if (!cap_ptr) { - TRACE_CAP("PCI: find_pci_capability ERROR %u:%u:%u capability %#02x empty list\n", bus, device, function, cap_id); - return B_NAME_NOT_FOUND; - } - for (i = 0; i < 48; i++) { - uint8 this_cap_id = pci_read_config(bus, device, function, cap_ptr, 1); - if (this_cap_id == cap_id) { - *offset = cap_ptr; - return B_OK; - } - - cap_ptr = pci_read_config(bus, device, function, cap_ptr + 1, 1); - cap_ptr &= ~3; - - if (!cap_ptr) - return B_NAME_NOT_FOUND; - } - - TRACE_CAP("PCI: find_pci_capability ERROR %u:%u:%u capability %#02x circular list\n", bus, device, function, cap_id); - return B_ERROR; +// used by pci_info.cpp print_info_basic() +void +__pci_resolve_virtual_bus(uint8 virtualBus, int *domain, uint8 *bus) +{ + if (gPCI->ResolveVirtualBus(virtualBus, domain, bus) < B_OK) + panic("ResolveVirtualBus failed"); } // #pragma mark kernel debugger commands + static int display_io(int argc, char **argv) { @@ -251,16 +219,18 @@ write_io(int argc, char **argv) static int pcistatus(int argc, char **argv) { - sPCI->ClearDeviceStatus(NULL, true); + gPCI->ClearDeviceStatus(NULL, true); return 0; } + // #pragma mark bus manager init/uninit + status_t pci_init(void) { - sPCI = new PCI; + gPCI = new PCI; if (pci_io_init() != B_OK) { TRACE(("PCI: pci_io_init failed\n")); @@ -286,8 +256,8 @@ pci_init(void) return B_ERROR; } - sPCI->InitDomainData(); - sPCI->InitBus(); + gPCI->InitDomainData(); + gPCI->InitBus(); add_debugger_command("pcistatus", &pcistatus, "dump and clear pci device status registers"); @@ -312,18 +282,20 @@ pci_uninit(void) remove_debugger_command("inb", &display_io); remove_debugger_command("in8", &display_io); - delete sPCI; + delete gPCI; } // #pragma mark PCI class + PCI::PCI() - : fRootBus(0) - , fDomainCount(0) - , fBusEnumeration(false) - , fVirtualBusMap() - , fNextVirtualBus(0) + : + fRootBus(0), + fDomainCount(0), + fBusEnumeration(false), + fVirtualBusMap(), + fNextVirtualBus(0) { #if defined(__POWERPC__) || defined(__M68K__) fBusEnumeration = true; @@ -334,7 +306,7 @@ PCI::PCI() void PCI::InitBus() { - PCIBus **ppnext = &fRootBus; + PCIBus **nextBus = &fRootBus; for (int i = 0; i < fDomainCount; i++) { PCIBus *bus = new PCIBus; bus->next = NULL; @@ -342,27 +314,27 @@ PCI::InitBus() bus->child = NULL; bus->domain = i; bus->bus = 0; - *ppnext = bus; - ppnext = &bus->next; + *nextBus = bus; + nextBus = &bus->next; } - + if (fBusEnumeration) { for (int i = 0; i < fDomainCount; i++) { - EnumerateBus(i, 0); + _EnumerateBus(i, 0); } } if (1) { for (int i = 0; i < fDomainCount; i++) { - FixupDevices(i, 0); + _FixupDevices(i, 0); } } - + if (fRootBus) { - DiscoverBus(fRootBus); - ConfigureBridges(fRootBus); + _DiscoverBus(fRootBus); + _ConfigureBridges(fRootBus); ClearDeviceStatus(fRootBus, false); - RefreshDeviceInfo(fRootBus); + _RefreshDeviceInfo(fRootBus); } } @@ -373,7 +345,7 @@ PCI::~PCI() status_t -PCI::CreateVirtualBus(int domain, uint8 bus, uint8 *virtualBus) +PCI::_CreateVirtualBus(int domain, uint8 bus, uint8 *virtualBus) { #if defined(__INTEL__) @@ -403,7 +375,7 @@ PCI::CreateVirtualBus(int domain, uint8 bus, uint8 *virtualBus) *virtualBus = fNextVirtualBus++; FLOW("PCI::CreateVirtualBus: domain %d, bus %d => virtualBus %d\n", domain, bus, *virtualBus); - + return fVirtualBusMap.Insert(*virtualBus, value); #endif @@ -434,27 +406,18 @@ PCI::ResolveVirtualBus(uint8 virtualBus, int *domain, uint8 *bus) } -// used by pci_info.cpp print_info_basic() -void -__pci_resolve_virtual_bus(uint8 virtualBus, int *domain, uint8 *bus) -{ - if (sPCI->ResolveVirtualBus(virtualBus, domain, bus) < B_OK) - panic("ResolveVirtualBus failed"); -} - - status_t PCI::AddController(pci_controller *controller, void *controller_cookie) { if (fDomainCount == MAX_PCI_DOMAINS) return B_ERROR; - + fDomainData[fDomainCount].controller = controller; fDomainData[fDomainCount].controller_cookie = controller_cookie; // initialized later to avoid call back into controller at this point fDomainData[fDomainCount].max_bus_devices = -1; - + fDomainCount++; return B_OK; } @@ -465,7 +428,7 @@ PCI::InitDomainData() for (int i = 0; i < fDomainCount; i++) { int32 count; status_t status; - + status = (*fDomainData[i].controller->get_max_bus_devices)(fDomainData[i].controller_cookie, &count); fDomainData[i].max_bus_devices = (status == B_OK) ? count : 0; } @@ -473,7 +436,7 @@ PCI::InitDomainData() domain_data * -PCI::GetDomainData(int domain) +PCI::_GetDomainData(int domain) { if (domain < 0 || domain >= fDomainCount) return NULL; @@ -482,209 +445,237 @@ PCI::GetDomainData(int domain) } -status_t -PCI::GetNthPciInfo(long index, pci_info *outInfo) +inline int +PCI::_NumFunctions(int domain, uint8 bus, uint8 device) { - long curindex = 0; - if (!fRootBus) - return B_ERROR; - return GetNthPciInfo(fRootBus, &curindex, index, outInfo); + uint8 type = ReadConfig(domain, bus, device, + 0, PCI_header_type, 1); + return (type & PCI_multifunction) != 0 ? 8 : 1; } status_t -PCI::GetNthPciInfo(PCIBus *bus, long *curindex, long wantindex, pci_info *outInfo) +PCI::GetNthInfo(long index, pci_info *outInfo) +{ + long currentIndex = 0; + if (!fRootBus) + return B_ERROR; + + return _GetNthInfo(fRootBus, ¤tIndex, index, outInfo); +} + + +status_t +PCI::_GetNthInfo(PCIBus *bus, long *currentIndex, long wantIndex, + pci_info *outInfo) { // maps tree structure to linear indexed view PCIDev *dev = bus->child; while (dev) { - if (*curindex == wantindex) { + if (*currentIndex == wantIndex) { *outInfo = dev->info; return B_OK; } - *curindex += 1; - if (dev->child && B_OK == GetNthPciInfo(dev->child, curindex, wantindex, outInfo)) + *currentIndex += 1; + if (dev->child && B_OK == _GetNthInfo(dev->child, currentIndex, + wantIndex, outInfo)) return B_OK; dev = dev->next; } - + if (bus->next) - return GetNthPciInfo(bus->next, curindex, wantindex, outInfo); - + return _GetNthInfo(bus->next, currentIndex, wantIndex, outInfo); + return B_ERROR; } + void -PCI::EnumerateBus(int domain, uint8 bus, uint8 *subordinate_bus) +PCI::_EnumerateBus(int domain, uint8 bus, uint8 *subordinateBus) { TRACE(("PCI: EnumerateBus: domain %u, bus %u\n", domain, bus)); - - int max_bus_devices = GetDomainData(domain)->max_bus_devices; + + int maxBusDevices = _GetDomainData(domain)->max_bus_devices; // step 1: disable all bridges on this bus - for (int dev = 0; dev < max_bus_devices; dev++) { - uint16 vendor_id = ReadPciConfig(domain, bus, dev, 0, PCI_vendor_id, 2); + for (int dev = 0; dev < maxBusDevices; dev++) { + uint16 vendor_id = ReadConfig(domain, bus, dev, 0, PCI_vendor_id, 2); if (vendor_id == 0xffff) continue; - - uint8 type = ReadPciConfig(domain, bus, dev, 0, PCI_header_type, 1); - int nfunc = (type & PCI_multifunction) ? 8 : 1; - for (int func = 0; func < nfunc; func++) { - uint16 device_id = ReadPciConfig(domain, bus, dev, func, PCI_device_id, 2); + + int numFunctions = _NumFunctions(domain, bus, dev); + for (int function = 0; function < numFunctions; function++) { + uint16 device_id = ReadConfig(domain, bus, dev, function, + PCI_device_id, 2); if (device_id == 0xffff) continue; - uint8 base_class = ReadPciConfig(domain, bus, dev, func, PCI_class_base, 1); - uint8 sub_class = ReadPciConfig(domain, bus, dev, func, PCI_class_sub, 1); - if (base_class != PCI_bridge || sub_class != PCI_pci) + uint8 baseClass = ReadConfig(domain, bus, dev, function, + PCI_class_base, 1); + uint8 subClass = ReadConfig(domain, bus, dev, function, + PCI_class_sub, 1); + if (baseClass != PCI_bridge || subClass != PCI_pci) continue; - - TRACE(("PCI: found PCI-PCI bridge: domain %u, bus %u, dev %u, func %u\n", domain, bus, dev, func)); + + TRACE(("PCI: found PCI-PCI bridge: domain %u, bus %u, dev %u, func %u\n", domain, bus, dev, function)); TRACE(("PCI: original settings: pcicmd %04lx, primary-bus %lu, secondary-bus %lu, subordinate-bus %lu\n", - ReadPciConfig(domain, bus, dev, func, PCI_command, 2), - ReadPciConfig(domain, bus, dev, func, PCI_primary_bus, 1), - ReadPciConfig(domain, bus, dev, func, PCI_secondary_bus, 1), - ReadPciConfig(domain, bus, dev, func, PCI_subordinate_bus, 1))); - + ReadConfig(domain, bus, dev, function, PCI_command, 2), + ReadConfig(domain, bus, dev, function, PCI_primary_bus, 1), + ReadConfig(domain, bus, dev, function, PCI_secondary_bus, 1), + ReadConfig(domain, bus, dev, function, PCI_subordinate_bus, 1))); + // disable decoding uint16 pcicmd; - pcicmd = ReadPciConfig(domain, bus, dev, func, PCI_command, 2); - pcicmd &= ~(PCI_command_io | PCI_command_memory | PCI_command_master); - WritePciConfig(domain, bus, dev, func, PCI_command, 2, pcicmd); + pcicmd = ReadConfig(domain, bus, dev, function, PCI_command, 2); + pcicmd &= ~(PCI_command_io | PCI_command_memory + | PCI_command_master); + WriteConfig(domain, bus, dev, function, PCI_command, 2, pcicmd); // disable busses - WritePciConfig(domain, bus, dev, func, PCI_primary_bus, 1, 0); - WritePciConfig(domain, bus, dev, func, PCI_secondary_bus, 1, 0); - WritePciConfig(domain, bus, dev, func, PCI_subordinate_bus, 1, 0); + WriteConfig(domain, bus, dev, function, PCI_primary_bus, 1, 0); + WriteConfig(domain, bus, dev, function, PCI_secondary_bus, 1, 0); + WriteConfig(domain, bus, dev, function, PCI_subordinate_bus, 1, 0); TRACE(("PCI: disabled settings: pcicmd %04lx, primary-bus %lu, secondary-bus %lu, subordinate-bus %lu\n", - ReadPciConfig(domain, bus, dev, func, PCI_command, 2), - ReadPciConfig(domain, bus, dev, func, PCI_primary_bus, 1), - ReadPciConfig(domain, bus, dev, func, PCI_secondary_bus, 1), - ReadPciConfig(domain, bus, dev, func, PCI_subordinate_bus, 1))); + ReadConfig(domain, bus, dev, function, PCI_command, 2), + ReadConfig(domain, bus, dev, function, PCI_primary_bus, 1), + ReadConfig(domain, bus, dev, function, PCI_secondary_bus, 1), + ReadConfig(domain, bus, dev, function, PCI_subordinate_bus, 1))); } } - - uint8 last_used_bus_number = bus; - + + uint8 lastUsedBusNumber = bus; + // step 2: assign busses to all bridges, and enable them again - for (int dev = 0; dev < max_bus_devices; dev++) { - uint16 vendor_id = ReadPciConfig(domain, bus, dev, 0, PCI_vendor_id, 2); + for (int dev = 0; dev < maxBusDevices; dev++) { + uint16 vendor_id = ReadConfig(domain, bus, dev, 0, PCI_vendor_id, 2); if (vendor_id == 0xffff) continue; - - uint8 type = ReadPciConfig(domain, bus, dev, 0, PCI_header_type, 1); - int nfunc = (type & PCI_multifunction) ? 8 : 1; - for (int func = 0; func < nfunc; func++) { - uint16 device_id = ReadPciConfig(domain, bus, dev, func, PCI_device_id, 2); - if (device_id == 0xffff) + + int numFunctions = _NumFunctions(domain, bus, dev); + for (int function = 0; function < numFunctions; function++) { + uint16 deviceID = ReadConfig(domain, bus, dev, function, + PCI_device_id, 2); + if (deviceID == 0xffff) continue; - uint8 base_class = ReadPciConfig(domain, bus, dev, func, PCI_class_base, 1); - uint8 sub_class = ReadPciConfig(domain, bus, dev, func, PCI_class_sub, 1); - if (base_class != PCI_bridge || sub_class != PCI_pci) + uint8 baseClass = ReadConfig(domain, bus, dev, function, + PCI_class_base, 1); + uint8 subClass = ReadConfig(domain, bus, dev, function, + PCI_class_sub, 1); + if (baseClass != PCI_bridge || subClass != PCI_pci) continue; - - TRACE(("PCI: configuring PCI-PCI bridge: domain %u, bus %u, dev %u, func %u\n", - domain, bus, dev, func)); - + + TRACE(("PCI: configuring PCI-PCI bridge: domain %u, bus %u, dev %u, func %u\n", + domain, bus, dev, function)); + // open Scheunentor for enumerating the bus behind the bridge - WritePciConfig(domain, bus, dev, func, PCI_primary_bus, 1, bus); - WritePciConfig(domain, bus, dev, func, PCI_secondary_bus, 1, last_used_bus_number + 1); - WritePciConfig(domain, bus, dev, func, PCI_subordinate_bus, 1, 255); - + WriteConfig(domain, bus, dev, function, PCI_primary_bus, 1, bus); + WriteConfig(domain, bus, dev, function, PCI_secondary_bus, 1, + lastUsedBusNumber + 1); + WriteConfig(domain, bus, dev, function, PCI_subordinate_bus, 1, 255); + // enable decoding (too early here?) uint16 pcicmd; - pcicmd = ReadPciConfig(domain, bus, dev, func, PCI_command, 2); + pcicmd = ReadConfig(domain, bus, dev, function, PCI_command, 2); pcicmd |= PCI_command_io | PCI_command_memory | PCI_command_master; - WritePciConfig(domain, bus, dev, func, PCI_command, 2, pcicmd); + WriteConfig(domain, bus, dev, function, PCI_command, 2, pcicmd); TRACE(("PCI: probing settings: pcicmd %04lx, primary-bus %lu, secondary-bus %lu, subordinate-bus %lu\n", - ReadPciConfig(domain, bus, dev, func, PCI_command, 2), - ReadPciConfig(domain, bus, dev, func, PCI_primary_bus, 1), - ReadPciConfig(domain, bus, dev, func, PCI_secondary_bus, 1), - ReadPciConfig(domain, bus, dev, func, PCI_subordinate_bus, 1))); - + ReadConfig(domain, bus, dev, function, PCI_command, 2), + ReadConfig(domain, bus, dev, function, PCI_primary_bus, 1), + ReadConfig(domain, bus, dev, function, PCI_secondary_bus, 1), + ReadConfig(domain, bus, dev, function, PCI_subordinate_bus, 1))); + // enumerate bus - EnumerateBus(domain, last_used_bus_number + 1, &last_used_bus_number); + _EnumerateBus(domain, lastUsedBusNumber + 1, &lastUsedBusNumber); // close Scheunentor - WritePciConfig(domain, bus, dev, func, PCI_subordinate_bus, 1, last_used_bus_number); - + WriteConfig(domain, bus, dev, function, PCI_subordinate_bus, 1, lastUsedBusNumber); + TRACE(("PCI: configured settings: pcicmd %04lx, primary-bus %lu, secondary-bus %lu, subordinate-bus %lu\n", - ReadPciConfig(domain, bus, dev, func, PCI_command, 2), - ReadPciConfig(domain, bus, dev, func, PCI_primary_bus, 1), - ReadPciConfig(domain, bus, dev, func, PCI_secondary_bus, 1), - ReadPciConfig(domain, bus, dev, func, PCI_subordinate_bus, 1))); + ReadConfig(domain, bus, dev, function, PCI_command, 2), + ReadConfig(domain, bus, dev, function, PCI_primary_bus, 1), + ReadConfig(domain, bus, dev, function, PCI_secondary_bus, 1), + ReadConfig(domain, bus, dev, function, PCI_subordinate_bus, 1))); } } - if (subordinate_bus) - *subordinate_bus = last_used_bus_number; + if (subordinateBus) + *subordinateBus = lastUsedBusNumber; - TRACE(("PCI: EnumerateBus done: domain %u, bus %u, last used bus number %u\n", domain, bus, last_used_bus_number)); + TRACE(("PCI: EnumerateBus done: domain %u, bus %u, last used bus number %u\n", domain, bus, lastUsedBusNumber)); } void -PCI::FixupDevices(int domain, uint8 bus) +PCI::_FixupDevices(int domain, uint8 bus) { FLOW("PCI: FixupDevices domain %u, bus %u\n", domain, bus); - int maxBusDevices = GetDomainData(domain)->max_bus_devices; + int maxBusDevices = _GetDomainData(domain)->max_bus_devices; for (int dev = 0; dev < maxBusDevices; dev++) { - uint16 vendorId = ReadPciConfig(domain, bus, dev, 0, PCI_vendor_id, 2); + uint16 vendorId = ReadConfig(domain, bus, dev, 0, PCI_vendor_id, 2); if (vendorId == 0xffff) continue; - - uint8 type = ReadPciConfig(domain, bus, dev, 0, PCI_header_type, 1); - int nfunc = (type & PCI_multifunction) ? 8 : 1; - for (int func = 0; func < nfunc; func++) { - uint16 deviceId = ReadPciConfig(domain, bus, dev, func, PCI_device_id, 2); + + int numFunctions = _NumFunctions(domain, bus, dev); + for (int function = 0; function < numFunctions; function++) { + uint16 deviceId = ReadConfig(domain, bus, dev, function, + PCI_device_id, 2); if (deviceId == 0xffff) continue; - pci_fixup_device(this, domain, bus, dev, func); + pci_fixup_device(this, domain, bus, dev, function); - uint8 base_class = ReadPciConfig(domain, bus, dev, func, PCI_class_base, 1); - if (base_class != PCI_bridge) + uint8 baseClass = ReadConfig(domain, bus, dev, function, + PCI_class_base, 1); + if (baseClass != PCI_bridge) continue; - uint8 sub_class = ReadPciConfig(domain, bus, dev, func, PCI_class_sub, 1); - if (sub_class != PCI_pci) + uint8 subClass = ReadConfig(domain, bus, dev, function, + PCI_class_sub, 1); + if (subClass != PCI_pci) continue; - int busBehindBridge = ReadPciConfig(domain, bus, dev, func, PCI_secondary_bus, 1); - - FixupDevices(domain, busBehindBridge); + int busBehindBridge = ReadConfig(domain, bus, dev, function, + PCI_secondary_bus, 1); + + _FixupDevices(domain, busBehindBridge); } } } void -PCI::ConfigureBridges(PCIBus *bus) +PCI::_ConfigureBridges(PCIBus *bus) { for (PCIDev *dev = bus->child; dev; dev = dev->next) { - if (dev->info.class_base == PCI_bridge && dev->info.class_sub == PCI_pci) { - uint16 bridgeControlOld = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_bridge_control, 2); + if (dev->info.class_base == PCI_bridge + && dev->info.class_sub == PCI_pci) { + uint16 bridgeControlOld = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_bridge_control, 2); uint16 bridgeControlNew = bridgeControlOld; - // Enable: Parity Error Response, SERR, Master Abort Mode, Discard Timer SERR + // Enable: Parity Error Response, SERR, Master Abort Mode, Discard + // Timer SERR // Clear: Discard Timer Status - bridgeControlNew |= (1 << 0) | (1 << 1) | (1 << 5) | (1 << 10) | (1 << 11); + bridgeControlNew |= (1 << 0) | (1 << 1) | (1 << 5) | (1 << 10) + | (1 << 11); // Set discard timer to 2^15 PCI clocks bridgeControlNew &= ~((1 << 8) | (1 << 9)); - WritePciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_bridge_control, 2, bridgeControlNew); - bridgeControlNew = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_bridge_control, 2); + WriteConfig(dev->domain, dev->bus, dev->device, dev->function, + PCI_bridge_control, 2, bridgeControlNew); + bridgeControlNew = ReadConfig(dev->domain, dev->bus, dev->device, + dev->function, PCI_bridge_control, 2); dprintf("PCI: dom %u, bus %u, dev %2u, func %u, changed PCI bridge control from 0x%04x to 0x%04x\n", - dev->domain, dev->bus, dev->dev, dev->func, bridgeControlOld, bridgeControlNew); + dev->domain, dev->bus, dev->device, dev->function, bridgeControlOld, bridgeControlNew); } if (dev->child) - ConfigureBridges(dev->child); + _ConfigureBridges(dev->child); } - + if (bus->next) - ConfigureBridges(bus->next); + _ConfigureBridges(bus->next); } @@ -698,13 +689,14 @@ PCI::ClearDeviceStatus(PCIBus *bus, bool dumpStatus) } for (PCIDev *dev = bus->child; dev; dev = dev->next) { - // Clear and dump PCI device status - uint16 status = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_status, 2); - WritePciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_status, 2, status); + uint16 status = ReadConfig(dev->domain, dev->bus, dev->device, + dev->function, PCI_status, 2); + WriteConfig(dev->domain, dev->bus, dev->device, dev->function, PCI_status, + 2, status); if (dumpStatus) { kprintf("domain %u, bus %u, dev %2u, func %u, PCI device status 0x%04x\n", - dev->domain, dev->bus, dev->dev, dev->func, status); + dev->domain, dev->bus, dev->device, dev->function, status); if (status & (1 << 15)) kprintf(" Detected Parity Error\n"); if (status & (1 << 14)) @@ -719,14 +711,16 @@ PCI::ClearDeviceStatus(PCIBus *bus, bool dumpStatus) kprintf(" Master Data Parity Error\n"); } - if (dev->info.class_base == PCI_bridge && dev->info.class_sub == PCI_pci) { - + if (dev->info.class_base == PCI_bridge + && dev->info.class_sub == PCI_pci) { // Clear and dump PCI bridge secondary status - uint16 secondaryStatus = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_secondary_status, 2); - WritePciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_secondary_status, 2, secondaryStatus); - if (dumpStatus) { - kprintf("domain %u, bus %u, dev %2u, func %u, PCI bridge secondary status 0x%04x\n", - dev->domain, dev->bus, dev->dev, dev->func, secondaryStatus); + uint16 secondaryStatus = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_secondary_status, 2); + WriteConfig(dev->domain, dev->bus, dev->device, dev->function, + PCI_secondary_status, 2, secondaryStatus); + if (dumpStatus) { + kprintf("domain %u, bus %u, dev %2u, func %u, PCI bridge secondary status 0x%04x\n", + dev->domain, dev->bus, dev->device, dev->function, secondaryStatus); if (secondaryStatus & (1 << 15)) kprintf(" Detected Parity Error\n"); if (secondaryStatus & (1 << 14)) @@ -742,11 +736,13 @@ PCI::ClearDeviceStatus(PCIBus *bus, bool dumpStatus) } // Clear and dump the discard-timer error bit located in bridge-control register - uint16 bridgeControl = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_bridge_control, 2); - WritePciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_bridge_control, 2, bridgeControl); + uint16 bridgeControl = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_bridge_control, 2); + WriteConfig(dev->domain, dev->bus, dev->device, dev->function, + PCI_bridge_control, 2, bridgeControl); if (dumpStatus) { - kprintf("domain %u, bus %u, dev %2u, func %u, PCI bridge control 0x%04x\n", - dev->domain, dev->bus, dev->dev, dev->func, bridgeControl); + kprintf("domain %u, bus %u, dev %2u, func %u, PCI bridge control 0x%04x\n", + dev->domain, dev->bus, dev->device, dev->function, bridgeControl); if (bridgeControl & (1 << 10)) { kprintf(" bridge-control: Discard Timer Error\n"); } @@ -756,108 +752,118 @@ PCI::ClearDeviceStatus(PCIBus *bus, bool dumpStatus) if (dev->child) ClearDeviceStatus(dev->child, dumpStatus); } - + if (bus->next) ClearDeviceStatus(bus->next, dumpStatus); } void -PCI::DiscoverBus(PCIBus *bus) +PCI::_DiscoverBus(PCIBus *bus) { FLOW("PCI: DiscoverBus, domain %u, bus %u\n", bus->domain, bus->bus); - - int max_bus_devices = GetDomainData(bus->domain)->max_bus_devices; - for (int dev = 0; dev < max_bus_devices; dev++) { - uint16 vendor_id = ReadPciConfig(bus->domain, bus->bus, dev, 0, PCI_vendor_id, 2); - if (vendor_id == 0xffff) + int maxBusDevices = _GetDomainData(bus->domain)->max_bus_devices; + + for (int dev = 0; dev < maxBusDevices; dev++) { + uint16 vendorID = ReadConfig(bus->domain, bus->bus, dev, 0, + PCI_vendor_id, 2); + if (vendorID == 0xffff) continue; - - uint8 type = ReadPciConfig(bus->domain, bus->bus, dev, 0, PCI_header_type, 1); - int nfunc = (type & PCI_multifunction) ? 8 : 1; - for (int func = 0; func < nfunc; func++) - DiscoverDevice(bus, dev, func); + + int numFunctions = _NumFunctions(bus->domain, bus->bus, dev); + for (int function = 0; function < numFunctions; function++) + _DiscoverDevice(bus, dev, function); } - + if (bus->next) - DiscoverBus(bus->next); + _DiscoverBus(bus->next); } void -PCI::DiscoverDevice(PCIBus *bus, uint8 dev, uint8 func) +PCI::_DiscoverDevice(PCIBus *bus, uint8 dev, uint8 function) { - FLOW("PCI: DiscoverDevice, domain %u, bus %u, dev %u, func %u\n", bus->domain, bus->bus, dev, func); + FLOW("PCI: DiscoverDevice, domain %u, bus %u, dev %u, func %u\n", bus->domain, bus->bus, dev, function); - uint16 device_id = ReadPciConfig(bus->domain, bus->bus, dev, func, PCI_device_id, 2); - if (device_id == 0xffff) + uint16 deviceID = ReadConfig(bus->domain, bus->bus, dev, function, + PCI_device_id, 2); + if (deviceID == 0xffff) return; - PCIDev *newdev = CreateDevice(bus, dev, func); + PCIDev *newDev = _CreateDevice(bus, dev, function); - uint8 base_class = ReadPciConfig(bus->domain, bus->bus, dev, func, PCI_class_base, 1); - uint8 sub_class = ReadPciConfig(bus->domain, bus->bus, dev, func, PCI_class_sub, 1); - if (base_class == PCI_bridge && sub_class == PCI_pci) { - uint8 secondary_bus = ReadPciConfig(bus->domain, bus->bus, dev, func, PCI_secondary_bus, 1); - PCIBus *newbus = CreateBus(newdev, bus->domain, secondary_bus); - DiscoverBus(newbus); + uint8 baseClass = ReadConfig(bus->domain, bus->bus, dev, function, + PCI_class_base, 1); + uint8 subClass = ReadConfig(bus->domain, bus->bus, dev, function, + PCI_class_sub, 1); + if (baseClass == PCI_bridge && subClass == PCI_pci) { + uint8 secondaryBus = ReadConfig(bus->domain, bus->bus, dev, function, + PCI_secondary_bus, 1); + PCIBus *newBus = _CreateBus(newDev, bus->domain, secondaryBus); + _DiscoverBus(newBus); } } PCIBus * -PCI::CreateBus(PCIDev *parent, int domain, uint8 bus) +PCI::_CreateBus(PCIDev *parent, int domain, uint8 bus) { - PCIBus *newbus = new PCIBus; - newbus->next = NULL; - newbus->parent = parent; - newbus->child = NULL; - newbus->domain = domain; - newbus->bus = bus; - + PCIBus *newBus = new(std::nothrow) PCIBus; + if (newBus == NULL) + return NULL; + + newBus->next = NULL; + newBus->parent = parent; + newBus->child = NULL; + newBus->domain = domain; + newBus->bus = bus; + // append - parent->child = newbus; - - return newbus; + parent->child = newBus; + + return newBus; } - -PCIDev * -PCI::CreateDevice(PCIBus *parent, uint8 dev, uint8 func) -{ - FLOW("PCI: CreateDevice, domain %u, bus %u, dev %u, func %u:\n", parent->domain, parent->bus, dev, func); - - PCIDev *newdev = new PCIDev; - newdev->next = NULL; - newdev->parent = parent; - newdev->child = NULL; - newdev->domain = parent->domain; - newdev->bus = parent->bus; - newdev->dev = dev; - newdev->func = func; - ReadPciBasicInfo(newdev); +PCIDev * +PCI::_CreateDevice(PCIBus *parent, uint8 device, uint8 function) +{ + FLOW("PCI: CreateDevice, domain %u, bus %u, dev %u, func %u:\n", parent->domain, parent->bus, dev, function); + + PCIDev *newDev = new(std::nothrow) PCIDev; + if (newDev == NULL) + return NULL; + + newDev->next = NULL; + newDev->parent = parent; + newDev->child = NULL; + newDev->domain = parent->domain; + newDev->bus = parent->bus; + newDev->device = device; + newDev->function = function; + + _ReadBasicInfo(newDev); FLOW("PCI: CreateDevice, vendor 0x%04x, device 0x%04x, class_base 0x%02x, class_sub 0x%02x\n", newdev->info.vendor_id, newdev->info.device_id, newdev->info.class_base, newdev->info.class_sub); // append - if (parent->child == 0) { - parent->child = newdev; + if (parent->child == NULL) { + parent->child = newDev; } else { PCIDev *sub = parent->child; while (sub->next) sub = sub->next; - sub->next = newdev; + sub->next = newDev; } - - return newdev; + + return newDev; } uint32 -PCI::BarSize(uint32 bits, uint32 mask) +PCI::_BarSize(uint32 bits, uint32 mask) { bits &= mask; if (!bits) @@ -870,167 +876,249 @@ PCI::BarSize(uint32 bits, uint32 mask) void -PCI::GetBarInfo(PCIDev *dev, uint8 offset, uint32 *address, uint32 *size, uint8 *flags) +PCI::_GetBarInfo(PCIDev *dev, uint8 offset, uint32 *_address, uint32 *_size, + uint8 *_flags) { - uint32 oldvalue = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, offset, 4); - WritePciConfig(dev->domain, dev->bus, dev->dev, dev->func, offset, 4, 0xffffffff); - uint32 newvalue = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, offset, 4); - WritePciConfig(dev->domain, dev->bus, dev->dev, dev->func, offset, 4, oldvalue); - - *address = oldvalue & PCI_address_memory_32_mask; - if (size) - *size = BarSize(newvalue, PCI_address_memory_32_mask); - if (flags) - *flags = newvalue & 0xf; + uint32 oldValue = ReadConfig(dev->domain, dev->bus, dev->device, dev->function, + offset, 4); + WriteConfig(dev->domain, dev->bus, dev->device, dev->function, offset, 4, + 0xffffffff); + uint32 newValue = ReadConfig(dev->domain, dev->bus, dev->device, dev->function, + offset, 4); + WriteConfig(dev->domain, dev->bus, dev->device, dev->function, offset, 4, + oldValue); + + *_address = oldValue & PCI_address_memory_32_mask; + if (_size != NULL) + *_size = _BarSize(newValue, PCI_address_memory_32_mask); + if (_flags != NULL) + *_flags = newValue & 0xf; } void -PCI::GetRomBarInfo(PCIDev *dev, uint8 offset, uint32 *address, uint32 *size, uint8 *flags) +PCI::_GetRomBarInfo(PCIDev *dev, uint8 offset, uint32 *_address, uint32 *_size, + uint8 *_flags) { - uint32 oldvalue = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, offset, 4); - WritePciConfig(dev->domain, dev->bus, dev->dev, dev->func, offset, 4, 0xfffffffe); // LSB must be 0 - uint32 newvalue = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, offset, 4); - WritePciConfig(dev->domain, dev->bus, dev->dev, dev->func, offset, 4, oldvalue); - - *address = oldvalue & PCI_rom_address_mask; - if (size) - *size = BarSize(newvalue, PCI_rom_address_mask); - if (flags) - *flags = newvalue & 0xf; + uint32 oldValue = ReadConfig(dev->domain, dev->bus, dev->device, dev->function, + offset, 4); + WriteConfig(dev->domain, dev->bus, dev->device, dev->function, offset, 4, + 0xfffffffe); // LSB must be 0 + uint32 newValue = ReadConfig(dev->domain, dev->bus, dev->device, dev->function, + offset, 4); + WriteConfig(dev->domain, dev->bus, dev->device, dev->function, offset, 4, + oldValue); + + *_address = oldValue & PCI_rom_address_mask; + if (_size != NULL) + *_size = _BarSize(newValue, PCI_rom_address_mask); + if (_flags != NULL) + *_flags = newValue & 0xf; } void -PCI::ReadPciBasicInfo(PCIDev *dev) +PCI::_ReadBasicInfo(PCIDev *dev) { uint8 virtualBus; - - if (CreateVirtualBus(dev->domain, dev->bus, &virtualBus) != B_OK) { + + if (_CreateVirtualBus(dev->domain, dev->bus, &virtualBus) != B_OK) { dprintf("PCI: CreateVirtualBus failed, domain %u, bus %u\n", dev->domain, dev->bus); return; } - - dev->info.vendor_id = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_vendor_id, 2); - dev->info.device_id = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_device_id, 2); + + dev->info.vendor_id = ReadConfig(dev->domain, dev->bus, dev->device, + dev->function, PCI_vendor_id, 2); + dev->info.device_id = ReadConfig(dev->domain, dev->bus, dev->device, + dev->function, PCI_device_id, 2); dev->info.bus = virtualBus; - dev->info.device = dev->dev; - dev->info.function = dev->func; - dev->info.revision = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_revision, 1); - dev->info.class_api = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_class_api, 1); - dev->info.class_sub = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_class_sub, 1); - dev->info.class_base = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_class_base, 1); - dev->info.line_size = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_line_size, 1); - dev->info.latency = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_latency, 1); - // BeOS does not mask off the multifunction bit, developer must use (header_type & PCI_header_type_mask) - dev->info.header_type = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_header_type, 1); - dev->info.bist = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_bist, 1); + dev->info.device = dev->device; + dev->info.function = dev->function; + dev->info.revision = ReadConfig(dev->domain, dev->bus, dev->device, + dev->function, PCI_revision, 1); + dev->info.class_api = ReadConfig(dev->domain, dev->bus, dev->device, + dev->function, PCI_class_api, 1); + dev->info.class_sub = ReadConfig(dev->domain, dev->bus, dev->device, + dev->function, PCI_class_sub, 1); + dev->info.class_base = ReadConfig(dev->domain, dev->bus, dev->device, + dev->function, PCI_class_base, 1); + dev->info.line_size = ReadConfig(dev->domain, dev->bus, dev->device, + dev->function, PCI_line_size, 1); + dev->info.latency = ReadConfig(dev->domain, dev->bus, dev->device, + dev->function, PCI_latency, 1); + // BeOS does not mask off the multifunction bit, developer must use + // (header_type & PCI_header_type_mask) + dev->info.header_type = ReadConfig(dev->domain, dev->bus, dev->device, + dev->function, PCI_header_type, 1); + dev->info.bist = ReadConfig(dev->domain, dev->bus, dev->device, + dev->function, PCI_bist, 1); dev->info.reserved = 0; } void -PCI::ReadPciHeaderInfo(PCIDev *dev) +PCI::_ReadHeaderInfo(PCIDev *dev) { switch (dev->info.header_type & PCI_header_type_mask) { case PCI_header_type_generic: { - // disable PCI device address decoding (io and memory) while BARs are modified - uint16 pcicmd = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_command, 2); - WritePciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_command, 2, pcicmd & ~(PCI_command_io | PCI_command_memory)); + // disable PCI device address decoding (io and memory) while BARs + // are modified + uint16 pcicmd = ReadConfig(dev->domain, dev->bus, dev->device, + dev->function, PCI_command, 2); + WriteConfig(dev->domain, dev->bus, dev->device, dev->function, + PCI_command, 2, + pcicmd & ~(PCI_command_io | PCI_command_memory)); - // get BAR size infos - GetRomBarInfo(dev, PCI_rom_base, &dev->info.u.h0.rom_base_pci, &dev->info.u.h0.rom_size); + // get BAR size infos + _GetRomBarInfo(dev, PCI_rom_base, &dev->info.u.h0.rom_base_pci, + &dev->info.u.h0.rom_size); for (int i = 0; i < 6; i++) { - GetBarInfo(dev, PCI_base_registers + 4*i, + _GetBarInfo(dev, PCI_base_registers + 4*i, &dev->info.u.h0.base_registers_pci[i], &dev->info.u.h0.base_register_sizes[i], &dev->info.u.h0.base_register_flags[i]); } - - // restore PCI device address decoding - WritePciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_command, 2, pcicmd); - dev->info.u.h0.rom_base = (ulong)pci_ram_address((void *)dev->info.u.h0.rom_base_pci); + // restore PCI device address decoding + WriteConfig(dev->domain, dev->bus, dev->device, dev->function, + PCI_command, 2, pcicmd); + + dev->info.u.h0.rom_base = (ulong)pci_ram_address( + (void *)dev->info.u.h0.rom_base_pci); for (int i = 0; i < 6; i++) { - dev->info.u.h0.base_registers[i] = (ulong)pci_ram_address((void *)dev->info.u.h0.base_registers_pci[i]); + dev->info.u.h0.base_registers[i] = (ulong)pci_ram_address( + (void *)dev->info.u.h0.base_registers_pci[i]); } - - dev->info.u.h0.cardbus_cis = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_cardbus_cis, 4); - dev->info.u.h0.subsystem_id = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_subsystem_id, 2); - dev->info.u.h0.subsystem_vendor_id = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_subsystem_vendor_id, 2); - dev->info.u.h0.interrupt_line = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_interrupt_line, 1); - dev->info.u.h0.interrupt_pin = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_interrupt_pin, 1); - dev->info.u.h0.min_grant = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_min_grant, 1); - dev->info.u.h0.max_latency = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_max_latency, 1); + + dev->info.u.h0.cardbus_cis = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_cardbus_cis, 4); + dev->info.u.h0.subsystem_id = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_subsystem_id, 2); + dev->info.u.h0.subsystem_vendor_id = ReadConfig(dev->domain, + dev->bus, dev->device, dev->function, PCI_subsystem_vendor_id, 2); + dev->info.u.h0.interrupt_line = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_interrupt_line, 1); + dev->info.u.h0.interrupt_pin = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_interrupt_pin, 1); + dev->info.u.h0.min_grant = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_min_grant, 1); + dev->info.u.h0.max_latency = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_max_latency, 1); break; } case PCI_header_type_PCI_to_PCI_bridge: { // disable PCI device address decoding (io and memory) while BARs are modified - uint16 pcicmd = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_command, 2); - WritePciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_command, 2, pcicmd & ~(PCI_command_io | PCI_command_memory)); + uint16 pcicmd = ReadConfig(dev->domain, dev->bus, dev->device, + dev->function, PCI_command, 2); + WriteConfig(dev->domain, dev->bus, dev->device, dev->function, + PCI_command, 2, + pcicmd & ~(PCI_command_io | PCI_command_memory)); - GetRomBarInfo(dev, PCI_bridge_rom_base, &dev->info.u.h1.rom_base_pci); + _GetRomBarInfo(dev, PCI_bridge_rom_base, + &dev->info.u.h1.rom_base_pci); for (int i = 0; i < 2; i++) { - GetBarInfo(dev, PCI_base_registers + 4*i, + _GetBarInfo(dev, PCI_base_registers + 4*i, &dev->info.u.h1.base_registers_pci[i], &dev->info.u.h1.base_register_sizes[i], &dev->info.u.h1.base_register_flags[i]); } // restore PCI device address decoding - WritePciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_command, 2, pcicmd); + WriteConfig(dev->domain, dev->bus, dev->device, dev->function, + PCI_command, 2, pcicmd); - dev->info.u.h1.rom_base = (ulong)pci_ram_address((void *)dev->info.u.h1.rom_base_pci); + dev->info.u.h1.rom_base = (ulong)pci_ram_address( + (void *)dev->info.u.h1.rom_base_pci); for (int i = 0; i < 2; i++) { - dev->info.u.h1.base_registers[i] = (ulong)pci_ram_address((void *)dev->info.u.h1.base_registers_pci[i]); + dev->info.u.h1.base_registers[i] = (ulong)pci_ram_address( + (void *)dev->info.u.h1.base_registers_pci[i]); } - dev->info.u.h1.primary_bus = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_primary_bus, 1); - dev->info.u.h1.secondary_bus = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_secondary_bus, 1); - dev->info.u.h1.subordinate_bus = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_subordinate_bus, 1); - dev->info.u.h1.secondary_latency = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_secondary_latency, 1); - dev->info.u.h1.io_base = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_io_base, 1); - dev->info.u.h1.io_limit = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_io_limit, 1); - dev->info.u.h1.secondary_status = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_secondary_status, 2); - dev->info.u.h1.memory_base = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_memory_base, 2); - dev->info.u.h1.memory_limit = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_memory_limit, 2); - dev->info.u.h1.prefetchable_memory_base = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_prefetchable_memory_base, 2); - dev->info.u.h1.prefetchable_memory_limit = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_prefetchable_memory_limit, 2); - dev->info.u.h1.prefetchable_memory_base_upper32 = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_prefetchable_memory_base_upper32, 4); - dev->info.u.h1.prefetchable_memory_limit_upper32 = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_prefetchable_memory_limit_upper32, 4); - dev->info.u.h1.io_base_upper16 = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_io_base_upper16, 2); - dev->info.u.h1.io_limit_upper16 = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_io_limit_upper16, 2); - dev->info.u.h1.interrupt_line = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_interrupt_line, 1); - dev->info.u.h1.interrupt_pin = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_interrupt_pin, 1); - dev->info.u.h1.bridge_control = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_bridge_control, 2); - dev->info.u.h1.subsystem_id = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_sub_device_id_1, 2); - dev->info.u.h1.subsystem_vendor_id = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_sub_vendor_id_1, 2); + dev->info.u.h1.primary_bus = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_primary_bus, 1); + dev->info.u.h1.secondary_bus = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_secondary_bus, 1); + dev->info.u.h1.subordinate_bus = ReadConfig(dev->domain, + dev->bus, dev->device, dev->function, PCI_subordinate_bus, 1); + dev->info.u.h1.secondary_latency = ReadConfig(dev->domain, + dev->bus, dev->device, dev->function, PCI_secondary_latency, 1); + dev->info.u.h1.io_base = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_io_base, 1); + dev->info.u.h1.io_limit = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_io_limit, 1); + dev->info.u.h1.secondary_status = ReadConfig(dev->domain, + dev->bus, dev->device, dev->function, PCI_secondary_status, 2); + dev->info.u.h1.memory_base = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_memory_base, 2); + dev->info.u.h1.memory_limit = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_memory_limit, 2); + dev->info.u.h1.prefetchable_memory_base = ReadConfig(dev->domain, + dev->bus, dev->device, dev->function, PCI_prefetchable_memory_base, 2); + dev->info.u.h1.prefetchable_memory_limit = ReadConfig( + dev->domain, dev->bus, dev->device, dev->function, + PCI_prefetchable_memory_limit, 2); + dev->info.u.h1.prefetchable_memory_base_upper32 = ReadConfig( + dev->domain, dev->bus, dev->device, dev->function, + PCI_prefetchable_memory_base_upper32, 4); + dev->info.u.h1.prefetchable_memory_limit_upper32 = ReadConfig( + dev->domain, dev->bus, dev->device, dev->function, + PCI_prefetchable_memory_limit_upper32, 4); + dev->info.u.h1.io_base_upper16 = ReadConfig(dev->domain, + dev->bus, dev->device, dev->function, PCI_io_base_upper16, 2); + dev->info.u.h1.io_limit_upper16 = ReadConfig(dev->domain, + dev->bus, dev->device, dev->function, PCI_io_limit_upper16, 2); + dev->info.u.h1.interrupt_line = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_interrupt_line, 1); + dev->info.u.h1.interrupt_pin = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_interrupt_pin, 1); + dev->info.u.h1.bridge_control = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_bridge_control, 2); + dev->info.u.h1.subsystem_id = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_sub_device_id_1, 2); + dev->info.u.h1.subsystem_vendor_id = ReadConfig(dev->domain, + dev->bus, dev->device, dev->function, PCI_sub_vendor_id_1, 2); break; } - + case PCI_header_type_cardbus: { // for testing only, not final: - dev->info.u.h2.subsystem_id = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_sub_device_id_2, 2); - dev->info.u.h2.subsystem_vendor_id = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_sub_vendor_id_2, 2); - dev->info.u.h2.primary_bus = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_primary_bus_2, 1); - dev->info.u.h2.secondary_bus = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_secondary_bus_2, 1); - dev->info.u.h2.subordinate_bus = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_subordinate_bus_2, 1); - dev->info.u.h2.secondary_latency = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_secondary_latency_2, 1); + dev->info.u.h2.subsystem_id = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_sub_device_id_2, 2); + dev->info.u.h2.subsystem_vendor_id = ReadConfig(dev->domain, + dev->bus, dev->device, dev->function, PCI_sub_vendor_id_2, 2); + dev->info.u.h2.primary_bus = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_primary_bus_2, 1); + dev->info.u.h2.secondary_bus = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_secondary_bus_2, 1); + dev->info.u.h2.subordinate_bus = ReadConfig(dev->domain, + dev->bus, dev->device, dev->function, PCI_subordinate_bus_2, 1); + dev->info.u.h2.secondary_latency = ReadConfig(dev->domain, + dev->bus, dev->device, dev->function, PCI_secondary_latency_2, 1); dev->info.u.h2.reserved = 0; - dev->info.u.h2.memory_base = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_memory_base0_2, 4); - dev->info.u.h2.memory_limit = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_memory_limit0_2, 4); - dev->info.u.h2.memory_base_upper32 = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_memory_base1_2, 4); - dev->info.u.h2.memory_limit_upper32 = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_memory_limit1_2, 4); - dev->info.u.h2.io_base = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_io_base0_2, 4); - dev->info.u.h2.io_limit = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_io_limit0_2, 4); - dev->info.u.h2.io_base_upper32 = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_io_base1_2, 4); - dev->info.u.h2.io_limit_upper32 = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_io_limit1_2, 4); - dev->info.u.h2.secondary_status = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_secondary_status_2, 2); - dev->info.u.h2.bridge_control = ReadPciConfig(dev->domain, dev->bus, dev->dev, dev->func, PCI_bridge_control_2, 2); + dev->info.u.h2.memory_base = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_memory_base0_2, 4); + dev->info.u.h2.memory_limit = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_memory_limit0_2, 4); + dev->info.u.h2.memory_base_upper32 = ReadConfig(dev->domain, + dev->bus, dev->device, dev->function, PCI_memory_base1_2, 4); + dev->info.u.h2.memory_limit_upper32 = ReadConfig(dev->domain, + dev->bus, dev->device, dev->function, PCI_memory_limit1_2, 4); + dev->info.u.h2.io_base = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_io_base0_2, 4); + dev->info.u.h2.io_limit = ReadConfig(dev->domain, dev->bus, + dev->device, dev->function, PCI_io_limit0_2, 4); + dev->info.u.h2.io_base_upper32 = ReadConfig(dev->domain, + dev->bus, dev->device, dev->function, PCI_io_base1_2, 4); + dev->info.u.h2.io_limit_upper32 = ReadConfig(dev->domain, + dev->bus, dev->device, dev->function, PCI_io_limit1_2, 4); + dev->info.u.h2.secondary_status = ReadConfig(dev->domain, + dev->bus, dev->device, dev->function, PCI_secondary_status_2, 2); + dev->info.u.h2.bridge_control = ReadConfig(dev->domain, + dev->bus, dev->device, dev->function, PCI_bridge_control_2, 2); break; } @@ -1042,83 +1130,198 @@ PCI::ReadPciHeaderInfo(PCIDev *dev) void -PCI::RefreshDeviceInfo(PCIBus *bus) +PCI::_RefreshDeviceInfo(PCIBus *bus) { for (PCIDev *dev = bus->child; dev; dev = dev->next) { - ReadPciBasicInfo(dev); - ReadPciHeaderInfo(dev); + _ReadBasicInfo(dev); + _ReadHeaderInfo(dev); if (dev->child) - RefreshDeviceInfo(dev->child); + _RefreshDeviceInfo(dev->child); } - + if (bus->next) - RefreshDeviceInfo(bus->next); + _RefreshDeviceInfo(bus->next); } status_t -PCI::ReadPciConfig(int domain, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 *value) +PCI::ReadConfig(int domain, uint8 bus, uint8 device, uint8 function, + uint8 offset, uint8 size, uint32 *value) { - domain_data *info; - info = GetDomainData(domain); + domain_data *info = _GetDomainData(domain); if (!info) return B_ERROR; - - if (device > (info->max_bus_devices - 1) - || function > 7 + + if (device > (info->max_bus_devices - 1) + || function > 7 || (size != 1 && size != 2 && size != 4) - || (size == 2 && (offset & 3) == 3) + || (size == 2 && (offset & 3) == 3) || (size == 4 && (offset & 3) != 0)) { dprintf("PCI: can't read config for domain %d, bus %u, device %u, function %u, offset %u, size %u\n", domain, bus, device, function, offset, size); return B_ERROR; } - status_t status; - status = (*info->controller->read_pci_config)(info->controller_cookie, - bus, device, function, - offset, size, value); - return status; + return (*info->controller->read_pci_config)(info->controller_cookie, bus, + device, function, offset, size, value); } uint32 -PCI::ReadPciConfig(int domain, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size) +PCI::ReadConfig(int domain, uint8 bus, uint8 device, uint8 function, + uint8 offset, uint8 size) { uint32 value; - - if (ReadPciConfig(domain, bus, device, function, offset, size, &value) != B_OK) + if (ReadConfig(domain, bus, device, function, offset, size, &value) + != B_OK) return 0xffffffff; - + + return value; +} + + +uint32 +PCI::ReadConfig(PCIDev *device, uint8 offset, uint8 size) +{ + uint32 value; + if (ReadConfig(device->domain, device->bus, device->device, + device->function, offset, size, &value) != B_OK) + return 0xffffffff; + return value; } status_t -PCI::WritePciConfig(int domain, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 value) +PCI::WriteConfig(int domain, uint8 bus, uint8 device, uint8 function, + uint8 offset, uint8 size, uint32 value) { - domain_data *info; - info = GetDomainData(domain); + domain_data *info = _GetDomainData(domain); if (!info) return B_ERROR; - - if (device > (info->max_bus_devices - 1) - || function > 7 + + if (device > (info->max_bus_devices - 1) + || function > 7 || (size != 1 && size != 2 && size != 4) - || (size == 2 && (offset & 3) == 3) + || (size == 2 && (offset & 3) == 3) || (size == 4 && (offset & 3) != 0)) { dprintf("PCI: can't write config for domain %d, bus %u, device %u, function %u, offset %u, size %u\n", domain, bus, device, function, offset, size); return B_ERROR; } - status_t status; - status = (*info->controller->write_pci_config)(info->controller_cookie, - bus, device, function, - offset, size, value); - return status; + return (*info->controller->write_pci_config)(info->controller_cookie, bus, + device, function, offset, size, value); } + +status_t +PCI::WriteConfig(PCIDev *device, uint8 offset, uint8 size, uint32 value) +{ + return WriteConfig(device->domain, device->bus, device->device, + device->function, offset, size, value); +} + + +status_t +PCI::FindCapability(int domain, uint8 bus, uint8 device, uint8 function, + uint8 capID, uint8 *offset) +{ + if (offset == NULL) { + TRACE_CAP("PCI: FindCapability() ERROR %u:%u:%u capability %#02x offset NULL pointer\n", bus, device, function, capID); + return B_BAD_VALUE; + } + + uint16 status = ReadConfig(domain, bus, device, function, PCI_status, 2); + if (!(status & PCI_status_capabilities)) { + TRACE_CAP("PCI: find_pci_capability ERROR %u:%u:%u capability %#02x not supported\n", bus, device, function, capID); + return B_ERROR; + } + + uint8 headerType = ReadConfig(domain, bus, device, function, + PCI_header_type, 1); + uint8 capPointer; + + switch (headerType & PCI_header_type_mask) { + case PCI_header_type_generic: + case PCI_header_type_PCI_to_PCI_bridge: + capPointer = ReadConfig(domain, bus, device, function, + PCI_capabilities_ptr, 1); + break; + case PCI_header_type_cardbus: + capPointer = ReadConfig(domain, bus, device, function, + PCI_capabilities_ptr_2, 1); + break; + default: + TRACE_CAP("PCI: find_pci_capability ERROR %u:%u:%u capability %#02x unknown header type\n", bus, device, function, capID); + return B_ERROR; + } + + capPointer &= ~3; + if (capPointer == 0) { + TRACE_CAP("PCI: find_pci_capability ERROR %u:%u:%u capability %#02x empty list\n", bus, device, function, capID); + return B_NAME_NOT_FOUND; + } + + for (int i = 0; i < 48; i++) { + if (ReadConfig(domain, bus, device, function, capPointer, 1) == capID) { + *offset = capPointer; + return B_OK; + } + + capPointer = ReadConfig(domain, bus, device, function, capPointer + 1, + 1); + capPointer &= ~3; + + if (capPointer == 0) + return B_NAME_NOT_FOUND; + } + + TRACE_CAP("PCI: find_pci_capability ERROR %u:%u:%u capability %#02x circular list\n", bus, device, function, capID); + return B_ERROR; +} + + +status_t +PCI::FindCapability(PCIDev *device, uint8 capID, uint8 *offset) +{ + return FindCapability(device->domain, device->bus, device->device, + device->function, capID, offset); +} + + +PCIDev * +PCI::FindDevice(int domain, uint8 bus, uint8 device, uint8 function) +{ + return _FindDevice(fRootBus, domain, bus, device, function); +} + + +PCIDev * +PCI::_FindDevice(PCIBus *current, int domain, uint8 bus, uint8 device, + uint8 function) +{ + if (current->domain == domain && current->bus == bus) { + // search device on this bus + + for (PCIDev *child = current->child; child != NULL; + child = child->next) { + if (child->device == device && child->function == function) + return child; + + if (child->child != NULL) { + // search child busses + PCIDev *found = _FindDevice(child->child, domain, bus, device, + function); + if (found != NULL) + return found; + } + } + } + + // search other busses + if (current->next != NULL) + return _FindDevice(current->next, domain, bus, device, function); + + return NULL; +} diff --git a/src/add-ons/kernel/bus_managers/pci/pci.h b/src/add-ons/kernel/bus_managers/pci/pci.h index 3d50e4731c..ddaacb0bd4 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.h +++ b/src/add-ons/kernel/bus_managers/pci/pci.h @@ -1,7 +1,6 @@ /* - * Copyright 2006, Marcus Overhagen. All rights reserved. - * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. - * Copyright 2003, Marcus Overhagen. All rights reserved. + * Copyright 2003-2008, Marcus Overhagen. All rights reserved. + * Copyright 2005-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * * Distributed under the terms of the MIT License. */ @@ -19,7 +18,7 @@ #define TRACE_PCI #ifndef TRACE_PCI -# define TRACE(x) +# define TRACE(x) #else # define TRACE(x) dprintf x #endif @@ -30,104 +29,131 @@ struct PCIDev; struct PCIBus { - PCIBus *next; - PCIDev *parent; - PCIDev *child; - int domain; - uint8 bus; + PCIBus * next; + PCIDev * parent; + PCIDev * child; + int domain; + uint8 bus; }; struct PCIDev { - PCIDev *next; - PCIBus *parent; - PCIBus *child; - int domain; - uint8 bus; - uint8 dev; - uint8 func; - pci_info info; + PCIDev * next; + PCIBus * parent; + PCIBus * child; + int domain; + uint8 bus; + uint8 device; + uint8 function; + pci_info info; }; -struct domain_data -{ +struct domain_data { // These two are set in PCI::AddController: pci_controller * controller; void * controller_cookie; - + // All the rest is set in PCI::InitDomainData int max_bus_devices; }; class PCI { - public: +public: PCI(); ~PCI(); - - void InitDomainData(); - void InitBus(); - status_t AddController(pci_controller *controller, void *controller_cookie); + void InitDomainData(); + void InitBus(); - status_t GetNthPciInfo(long index, pci_info *outInfo); + status_t AddController(pci_controller *controller, + void *controller_cookie); - status_t ReadPciConfig(int domain, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 *value); + status_t GetNthInfo(long index, pci_info *outInfo); - uint32 ReadPciConfig(int domain, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size); + status_t ReadConfig(int domain, uint8 bus, uint8 device, + uint8 function, uint8 offset, uint8 size, + uint32 *value); + uint32 ReadConfig(int domain, uint8 bus, uint8 device, + uint8 function, uint8 offset, uint8 size); + uint32 ReadConfig(PCIDev *device, uint8 offset, + uint8 size); - status_t WritePciConfig(int domain, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 value); + status_t WriteConfig(int domain, uint8 bus, uint8 device, + uint8 function, uint8 offset, uint8 size, + uint32 value); + status_t WriteConfig(PCIDev *device, uint8 offset, + uint8 size, uint32 value); - status_t ResolveVirtualBus(uint8 virtualBus, int *domain, uint8 *bus); - - void ClearDeviceStatus(PCIBus *bus, bool dumpStatus); + status_t FindCapability(int domain, uint8 bus, uint8 device, + uint8 function, uint8 capID, uint8 *offset); + status_t FindCapability(PCIDev *device, uint8 capID, + uint8 *offset); - private: + status_t ResolveVirtualBus(uint8 virtualBus, int *domain, + uint8 *bus); - void EnumerateBus(int domain, uint8 bus, uint8 *subordinate_bus = NULL); + PCIDev * FindDevice(int domain, uint8 bus, uint8 device, + uint8 function); - void FixupDevices(int domain, uint8 bus); + void ClearDeviceStatus(PCIBus *bus, bool dumpStatus); - void DiscoverBus(PCIBus *bus); - void DiscoverDevice(PCIBus *bus, uint8 dev, uint8 func); +private: + void _EnumerateBus(int domain, uint8 bus, + uint8 *subordinateBus = NULL); - PCIDev *CreateDevice(PCIBus *parent, uint8 dev, uint8 func); - PCIBus *CreateBus(PCIDev *parent, int domain, uint8 bus); + void _FixupDevices(int domain, uint8 bus); - status_t GetNthPciInfo(PCIBus *bus, long *curindex, long wantindex, pci_info *outInfo); - void ReadPciBasicInfo(PCIDev *dev); - void ReadPciHeaderInfo(PCIDev *dev); + void _DiscoverBus(PCIBus *bus); + void _DiscoverDevice(PCIBus *bus, uint8 dev, + uint8 function); - void ConfigureBridges(PCIBus *bus); - void RefreshDeviceInfo(PCIBus *bus); + PCIDev * _CreateDevice(PCIBus *parent, uint8 dev, + uint8 function); + PCIBus * _CreateBus(PCIDev *parent, int domain, uint8 bus); - uint32 BarSize(uint32 bits, uint32 mask); - void GetBarInfo(PCIDev *dev, uint8 offset, uint32 *address, uint32 *size = 0, uint8 *flags = 0); - void GetRomBarInfo(PCIDev *dev, uint8 offset, uint32 *address, uint32 *size = 0, uint8 *flags = 0); - - - domain_data * GetDomainData(int domain); - - status_t CreateVirtualBus(int domain, uint8 bus, uint8 *virtualBus); + status_t _GetNthInfo(PCIBus *bus, long *currentIndex, + long wantIndex, pci_info *outInfo); + void _ReadBasicInfo(PCIDev *dev); + void _ReadHeaderInfo(PCIDev *dev); - private: - PCIBus * fRootBus; + void _ConfigureBridges(PCIBus *bus); + void _RefreshDeviceInfo(PCIBus *bus); - enum { MAX_PCI_DOMAINS = 8 }; - - domain_data fDomainData[MAX_PCI_DOMAINS]; - int fDomainCount; - bool fBusEnumeration; + uint32 _BarSize(uint32 bits, uint32 mask); + void _GetBarInfo(PCIDev *dev, uint8 offset, + uint32 *address, uint32 *size = 0, + uint8 *flags = 0); + void _GetRomBarInfo(PCIDev *dev, uint8 offset, + uint32 *address, uint32 *size = 0, + uint8 *flags = 0); - typedef VectorMap VirtualBusMap; + domain_data * _GetDomainData(int domain); - VirtualBusMap fVirtualBusMap; - int fNextVirtualBus; + status_t _CreateVirtualBus(int domain, uint8 bus, + uint8 *virtualBus); + + int _NumFunctions(int domain, uint8 bus, uint8 device); + PCIDev * _FindDevice(PCIBus *current, int domain, uint8 bus, + uint8 device, uint8 function); + +private: + PCIBus * fRootBus; + + enum { MAX_PCI_DOMAINS = 8 }; + + domain_data fDomainData[MAX_PCI_DOMAINS]; + int fDomainCount; + bool fBusEnumeration; + + typedef VectorMap VirtualBusMap; + + VirtualBusMap fVirtualBusMap; + int fNextVirtualBus; }; +extern PCI *gPCI; + #endif // __cplusplus @@ -140,8 +166,10 @@ 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); -void pci_write_config(uint8 virtualBus, uint8 device, uint8 function, uint8 offset, uint8 size, uint32 value); +uint32 pci_read_config(uint8 virtualBus, uint8 device, uint8 function, + uint8 offset, uint8 size); +void pci_write_config(uint8 virtualBus, uint8 device, uint8 function, + uint8 offset, uint8 size, uint32 value); void __pci_resolve_virtual_bus(uint8 virtualBus, int *domain, uint8 *bus); diff --git a/src/add-ons/kernel/bus_managers/pci/pci_fixup.cpp b/src/add-ons/kernel/bus_managers/pci/pci_fixup.cpp index 3365fc8ada..0cc8035571 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_fixup.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci_fixup.cpp @@ -12,12 +12,13 @@ /* The Jmicron AHCI controller has a mode that combines IDE and AHCI functionality * into a single PCI device at function 0. This happens when the controller is set * in the BIOS to "basic" or "IDE" mode (but not in "RAID" or "AHCI" mode). - * To avoid needing two drivers to handle a single PCI device, we switch to the - * multifunction (split device) AHCI mode. This will set PCI device at function 0 + * To avoid needing two drivers to handle a single PCI device, we switch to the + * multifunction (split device) AHCI mode. This will set PCI device at function 0 * to AHCI, and PCI device at function 1 to IDE controller. */ static void -jmicron_fixup_ahci(PCI *pci, int domain, uint8 bus, uint8 device, uint8 function, uint16 deviceId) +jmicron_fixup_ahci(PCI *pci, int domain, uint8 bus, uint8 device, + uint8 function, uint16 deviceId) { switch (deviceId) { case 0x2361: // 1 SATA, 1 PATA @@ -34,26 +35,26 @@ jmicron_fixup_ahci(PCI *pci, int domain, uint8 bus, uint8 device, uint8 function domain, bus, device, function, deviceId); if (function == 0) { - dprintf("jmicron_fixup_ahci: 0x40: 0x%08lx\n", pci->ReadPciConfig(domain, bus, device, function, 0x40, 4)); - dprintf("jmicron_fixup_ahci: 0xdc: 0x%08lx\n", pci->ReadPciConfig(domain, bus, device, function, 0xdc, 4)); - uint32 val = pci->ReadPciConfig(domain, bus, device, function, 0xdc, 4); + dprintf("jmicron_fixup_ahci: 0x40: 0x%08lx\n", pci->ReadConfig(domain, bus, device, function, 0x40, 4)); + dprintf("jmicron_fixup_ahci: 0xdc: 0x%08lx\n", pci->ReadConfig(domain, bus, device, function, 0xdc, 4)); + uint32 val = pci->ReadConfig(domain, bus, device, function, 0xdc, 4); if (!(val & (1 << 30))) { - uint8 irq = pci->ReadPciConfig(domain, bus, device, function, 0x3c, 1); + uint8 irq = pci->ReadConfig(domain, bus, device, function, 0x3c, 1); dprintf("jmicron_fixup_ahci: enabling split device mode\n"); val &= ~(1 << 24); val |= (1 << 25) | (1 << 30); - pci->WritePciConfig(domain, bus, device, function, 0xdc, 4, val); - val = pci->ReadPciConfig(domain, bus, device, function, 0x40, 4); + pci->WriteConfig(domain, bus, device, function, 0xdc, 4, val); + val = pci->ReadConfig(domain, bus, device, function, 0x40, 4); val &= ~(1 << 16); val |= (1 << 1) | (1 << 17) | (1 << 22); - pci->WritePciConfig(domain, bus, device, function, 0x40, 4, val); + pci->WriteConfig(domain, bus, device, function, 0x40, 4, val); if (function == 0) - pci->WritePciConfig(domain, bus, device, 1, 0x3c, 1, irq); - else + pci->WriteConfig(domain, bus, device, 1, 0x3c, 1, irq); + else dprintf("jmicron_fixup_ahci: can't assign IRQ\n"); } - dprintf("jmicron_fixup_ahci: 0x40: 0x%08lx\n", pci->ReadPciConfig(domain, bus, device, function, 0x40, 4)); - dprintf("jmicron_fixup_ahci: 0xdc: 0x%08lx\n", pci->ReadPciConfig(domain, bus, device, function, 0xdc, 4)); + dprintf("jmicron_fixup_ahci: 0x40: 0x%08lx\n", pci->ReadConfig(domain, bus, device, function, 0x40, 4)); + dprintf("jmicron_fixup_ahci: 0xdc: 0x%08lx\n", pci->ReadConfig(domain, bus, device, function, 0xdc, 4)); } } @@ -85,49 +86,49 @@ intel_fixup_ahci(PCI *pci, int domain, uint8 bus, uint8 device, uint8 function, dprintf("intel_fixup_ahci: domain %u, bus %u, device %u, function %u, deviceId 0x%04x\n", domain, bus, device, function, deviceId); - dprintf("intel_fixup_ahci: 0x24: 0x%08lx\n", pci->ReadPciConfig(domain, bus, device, function, 0x24, 4)); - dprintf("intel_fixup_ahci: 0x90: 0x%02lx\n", pci->ReadPciConfig(domain, bus, device, function, 0x90, 1)); + dprintf("intel_fixup_ahci: 0x24: 0x%08lx\n", pci->ReadConfig(domain, bus, device, function, 0x24, 4)); + dprintf("intel_fixup_ahci: 0x90: 0x%02lx\n", pci->ReadConfig(domain, bus, device, function, 0x90, 1)); - uint8 map = pci->ReadPciConfig(domain, bus, device, function, 0x90, 1); + uint8 map = pci->ReadConfig(domain, bus, device, function, 0x90, 1); if ((map >> 6) == 0) { - uint32 bar5 = pci->ReadPciConfig(domain, bus, device, function, 0x24, 4); - uint16 pcicmd = pci->ReadPciConfig(domain, bus, device, function, PCI_command, 2); + uint32 bar5 = pci->ReadConfig(domain, bus, device, function, 0x24, 4); + uint16 pcicmd = pci->ReadConfig(domain, bus, device, function, PCI_command, 2); dprintf("intel_fixup_ahci: switching from IDE to AHCI mode\n"); - pci->WritePciConfig(domain, bus, device, function, PCI_command, 2, + pci->WriteConfig(domain, bus, device, function, PCI_command, 2, pcicmd & ~(PCI_command_io | PCI_command_memory)); - pci->WritePciConfig(domain, bus, device, function, 0x24, 4, 0xffffffff); - dprintf("intel_fixup_ahci: ide-bar5 bits-1: 0x%08lx\n", pci->ReadPciConfig(domain, bus, device, function, 0x24, 4)); - pci->WritePciConfig(domain, bus, device, function, 0x24, 4, 0); - dprintf("intel_fixup_ahci: ide-bar5 bits-0: 0x%08lx\n", pci->ReadPciConfig(domain, bus, device, function, 0x24, 4)); + pci->WriteConfig(domain, bus, device, function, 0x24, 4, 0xffffffff); + dprintf("intel_fixup_ahci: ide-bar5 bits-1: 0x%08lx\n", pci->ReadConfig(domain, bus, device, function, 0x24, 4)); + pci->WriteConfig(domain, bus, device, function, 0x24, 4, 0); + dprintf("intel_fixup_ahci: ide-bar5 bits-0: 0x%08lx\n", pci->ReadConfig(domain, bus, device, function, 0x24, 4)); map &= ~0x03; map |= 0x40; - pci->WritePciConfig(domain, bus, device, function, 0x90, 1, map); + pci->WriteConfig(domain, bus, device, function, 0x90, 1, map); - pci->WritePciConfig(domain, bus, device, function, 0x24, 4, 0xffffffff); - dprintf("intel_fixup_ahci: ahci-bar5 bits-1: 0x%08lx\n", pci->ReadPciConfig(domain, bus, device, function, 0x24, 4)); - pci->WritePciConfig(domain, bus, device, function, 0x24, 4, 0); - dprintf("intel_fixup_ahci: ahci-bar5 bits-0: 0x%08lx\n", pci->ReadPciConfig(domain, bus, device, function, 0x24, 4)); + pci->WriteConfig(domain, bus, device, function, 0x24, 4, 0xffffffff); + dprintf("intel_fixup_ahci: ahci-bar5 bits-1: 0x%08lx\n", pci->ReadConfig(domain, bus, device, function, 0x24, 4)); + pci->WriteConfig(domain, bus, device, function, 0x24, 4, 0); + dprintf("intel_fixup_ahci: ahci-bar5 bits-0: 0x%08lx\n", pci->ReadConfig(domain, bus, device, function, 0x24, 4)); if (deviceId == 0x27c0 || deviceId == 0x27c4) // restore on ICH7 - pci->WritePciConfig(domain, bus, device, function, 0x24, 4, bar5); + pci->WriteConfig(domain, bus, device, function, 0x24, 4, bar5); - pci->WritePciConfig(domain, bus, device, function, PCI_command, 2, pcicmd); + pci->WriteConfig(domain, bus, device, function, PCI_command, 2, pcicmd); } - dprintf("intel_fixup_ahci: 0x24: 0x%08lx\n", pci->ReadPciConfig(domain, bus, device, function, 0x24, 4)); - dprintf("intel_fixup_ahci: 0x90: 0x%02lx\n", pci->ReadPciConfig(domain, bus, device, function, 0x90, 1)); + dprintf("intel_fixup_ahci: 0x24: 0x%08lx\n", pci->ReadConfig(domain, bus, device, function, 0x24, 4)); + dprintf("intel_fixup_ahci: 0x90: 0x%02lx\n", pci->ReadConfig(domain, bus, device, function, 0x90, 1)); } void pci_fixup_device(PCI *pci, int domain, uint8 bus, uint8 device, uint8 function) { - uint16 vendorId = pci->ReadPciConfig(domain, bus, device, function, PCI_vendor_id, 2); - uint16 deviceId = pci->ReadPciConfig(domain, bus, device, function, PCI_device_id, 2); + uint16 vendorId = pci->ReadConfig(domain, bus, device, function, PCI_vendor_id, 2); + uint16 deviceId = pci->ReadConfig(domain, bus, device, function, PCI_device_id, 2); // dprintf("pci_fixup_device: domain %u, bus %u, device %u, function %u\n", domain, bus, device, function);