diff --git a/headers/os/drivers/bus/PCI.h b/headers/os/drivers/bus/PCI.h index 4946b05be0..46c4dd72ff 100644 --- a/headers/os/drivers/bus/PCI.h +++ b/headers/os/drivers/bus/PCI.h @@ -58,20 +58,11 @@ typedef struct pci_device_module_info { } pci_device_module_info; -enum { - kPciRangeInvalid = 0, - kPciRangeIoPort = 1, - kPciRangeMmio = 2, - kPciRangeMmio64Bit = 1 << 0, - kPciRangeMmioPrefetch = 1 << 1, - kPciRangeMmioEnd = 6, - kPciRangeEnd = 6, -}; - typedef struct pci_resource_range { uint32 type; - phys_addr_t host_addr; - phys_addr_t pci_addr; + uint8 address_type; + phys_addr_t host_address; + phys_addr_t pci_address; uint64 size; } pci_resource_range; diff --git a/src/add-ons/kernel/bus_managers/pci/pci.cpp b/src/add-ons/kernel/bus_managers/pci/pci.cpp index ff3073dbe6..7794369291 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci.cpp @@ -81,8 +81,8 @@ pci_ram_address(phys_addr_t childAdr) #else uint8 domain; pci_resource_range range; - if (gPCI->LookupRange(kPciRangeMmio, childAdr, domain, range) >= B_OK) - hostAdr = childAdr - range.pci_addr + range.host_addr; + if (gPCI->LookupRange(B_IO_MEMORY, childAdr, domain, range) >= B_OK) + hostAdr = childAdr - range.pci_address + range.host_address; #endif //dprintf("pci_ram_address(%#" B_PRIx64 ") -> %#" B_PRIx64 "\n", childAdr, hostAdr); return hostAdr; @@ -673,33 +673,27 @@ status_t PCI::LookupRange(uint32 type, phys_addr_t pciAddr, uint8 &domain, pci_resource_range &range, uint8 **mappedAdr) { - if (type >= kPciRangeEnd) - return B_BAD_VALUE; - for (uint8 curDomain = 0; curDomain < fDomainCount; curDomain++) { - pci_resource_range const *const &ranges = fDomainData[curDomain].ranges; + const auto &ranges = fDomainData[curDomain].ranges; - uint32 typeBeg, typeEnd; - if (type == kPciRangeMmio) { - typeBeg = kPciRangeMmio; - typeEnd = kPciRangeMmioEnd; - } else { - typeBeg = type; - typeEnd = type + 1; - } - for (uint32 curType = typeBeg; curType < typeEnd; curType++) { - const pci_resource_range curRange = ranges[curType]; - if (pciAddr >= curRange.pci_addr && pciAddr < curRange.pci_addr + curRange.size) { + for (int32 i = 0; i < ranges.Count(); i++) { + const pci_resource_range curRange = ranges[i]; + if (curRange.type != type) + continue; + + if (pciAddr >= curRange.pci_address + && pciAddr < (curRange.pci_address + curRange.size)) { domain = curDomain; range = curRange; #if !(defined(__i386__) || defined(__x86_64__)) - if (type == kPciRangeIoPort && mappedAdr != NULL) + if (type == B_IO_PORT && mappedAdr != NULL) *mappedAdr = fDomainData[curDomain].io_port_adr; #endif return B_OK; } } } + return B_ENTRY_NOT_FOUND; } @@ -716,23 +710,27 @@ PCI::InitDomainData(domain_data &data) status = ctrl->get_max_bus_devices(ctrlCookie, &count); data.max_bus_devices = (status == B_OK) ? count : 0; - memset(data.ranges, 0, sizeof(data.ranges)); pci_resource_range range; - for (uint32 j = 0; ctrl->get_range(ctrlCookie, j, &range) >= B_OK; j++) { - if (range.type < kPciRangeEnd && range.size > 0) - data.ranges[range.type] = range; - } + for (uint32 j = 0; ctrl->get_range(ctrlCookie, j, &range) >= B_OK; j++) + data.ranges.Add(range); #if !(defined(__i386__) || defined(__x86_64__)) - // TODO: free resources when domain is detached - pci_resource_range &ioPortRange = data.ranges[kPciRangeIoPort]; - if (ioPortRange.size > 0) { - data.io_port_area = map_physical_memory("PCI IO Ports", - ioPortRange.host_addr, ioPortRange.size, B_ANY_KERNEL_ADDRESS, - B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void **)&data.io_port_adr); + for (int32 i = 0; i < data.ranges.Count(); i++) { + pci_resource_range &ioPortRange = data.ranges[i]; + if (ioPortRange.type != B_IO_PORT) + continue; - if (data.io_port_area < B_OK) - data.io_port_adr = NULL; + if (ioPortRange.size > 0) { + data.io_port_area = map_physical_memory("PCI IO Ports", + ioPortRange.host_address, ioPortRange.size, B_ANY_KERNEL_ADDRESS, + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void **)&data.io_port_adr); + + if (data.io_port_area < B_OK) + data.io_port_adr = NULL; + + // TODO: Map other IO ports (if any.) + break; + } } #endif } diff --git a/src/add-ons/kernel/bus_managers/pci/pci.h b/src/add-ons/kernel/bus_managers/pci/pci.h index 89a31b24f2..56b413de71 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.h +++ b/src/add-ons/kernel/bus_managers/pci/pci.h @@ -47,6 +47,14 @@ struct PCIDev { struct domain_data { + ~domain_data() + { +#if !(defined(__i386__) || defined(__x86_64__)) + if (io_port_area >= 0) + delete_area(io_port_area); +#endif + } + // These two are set in PCI::AddController: pci_controller_module_info *controller; void * controller_cookie; @@ -55,11 +63,11 @@ struct domain_data { // All the rest is set in PCI::InitDomainData int max_bus_devices; - pci_resource_range ranges[kPciRangeEnd]; + Vector ranges; #if !(defined(__i386__) || defined(__x86_64__)) - area_id io_port_area; - uint8 * io_port_adr; + area_id io_port_area = -1; + uint8 * io_port_adr = NULL; #endif }; diff --git a/src/add-ons/kernel/busses/pci/designware/DWPCIController.cpp b/src/add-ons/kernel/busses/pci/designware/DWPCIController.cpp index 6df23447ed..b478ed84f2 100644 --- a/src/add-ons/kernel/busses/pci/designware/DWPCIController.cpp +++ b/src/add-ons/kernel/busses/pci/designware/DWPCIController.cpp @@ -201,28 +201,30 @@ DWPCIController::ReadResourceInfo() uint64_t parentAdr = B_BENDIAN_TO_HOST_INT64(*(uint64_t*)(it + 3)); uint64_t len = B_BENDIAN_TO_HOST_INT64(*(uint64_t*)(it + 5)); - uint32 outType = kPciRangeInvalid; + pci_resource_range range = {}; + range.host_address = parentAdr; + range.pci_address = childAdr; + range.size = len; + + if ((type & fdtPciRangePrefechable) != 0) + range.address_type |= PCI_address_prefetchable; + switch (type & fdtPciRangeTypeMask) { case fdtPciRangeIoPort: - outType = kPciRangeIoPort; + range.type = B_IO_PORT; + fResourceRanges.Add(range); break; case fdtPciRangeMmio32Bit: - outType = kPciRangeMmio; + range.type = B_IO_MEMORY; + range.address_type |= PCI_address_type_32; + fResourceRanges.Add(range); break; case fdtPciRangeMmio64Bit: - outType = kPciRangeMmio + kPciRangeMmio64Bit; + range.type = B_IO_MEMORY; + range.address_type |= PCI_address_type_64; + fResourceRanges.Add(range); break; } - if (outType >= kPciRangeMmio && outType < kPciRangeMmioEnd - && (fdtPciRangePrefechable & type) != 0) - outType += kPciRangeMmioPrefetch; - - if (outType != kPciRangeInvalid) { - fResourceRanges[outType].type = outType; - fResourceRanges[outType].host_addr = parentAdr; - fResourceRanges[outType].pci_addr = childAdr; - fResourceRanges[outType].size = len; - } switch (type & fdtPciRangeTypeMask) { case fdtPciRangeConfig: dprintf("CONFIG"); break; @@ -392,7 +394,7 @@ DWPCIController::WriteIrq(uint8 bus, uint8 device, uint8 function, status_t DWPCIController::GetRange(uint32 index, pci_resource_range* range) { - if (index >= kPciRangeEnd) + if (index >= (uint32)fResourceRanges.Count()) return B_BAD_INDEX; *range = fResourceRanges[index]; diff --git a/src/add-ons/kernel/busses/pci/designware/DWPCIController.h b/src/add-ons/kernel/busses/pci/designware/DWPCIController.h index 2a540a920d..0a1a07964b 100644 --- a/src/add-ons/kernel/busses/pci/designware/DWPCIController.h +++ b/src/add-ons/kernel/busses/pci/designware/DWPCIController.h @@ -12,6 +12,7 @@ #include #include +#include #define CHECK_RET(err) {status_t _err = (err); if (_err < B_OK) return _err;} @@ -231,7 +232,7 @@ private: addr_t fConfigBase {}; size_t fConfigSize {}; - pci_resource_range fResourceRanges[kPciRangeEnd] {}; + Vector fResourceRanges; InterruptMapMask fInterruptMapMask {}; uint32 fInterruptMapLen {}; ArrayDeleter fInterruptMap; diff --git a/src/add-ons/kernel/busses/pci/ecam/ECAMPCIController.cpp b/src/add-ons/kernel/busses/pci/ecam/ECAMPCIController.cpp index 4ad6bf494f..e959b67c20 100644 --- a/src/add-ons/kernel/busses/pci/ecam/ECAMPCIController.cpp +++ b/src/add-ons/kernel/busses/pci/ecam/ECAMPCIController.cpp @@ -245,7 +245,7 @@ ECAMPCIController::WriteIrq(uint8 bus, uint8 device, uint8 function, status_t ECAMPCIController::GetRange(uint32 index, pci_resource_range* range) { - if (index >= kPciRangeEnd) + if (index >= (uint32)fResourceRanges.Count()) return B_BAD_INDEX; *range = fResourceRanges[index]; diff --git a/src/add-ons/kernel/busses/pci/ecam/ECAMPCIController.h b/src/add-ons/kernel/busses/pci/ecam/ECAMPCIController.h index 861d2e8d21..257f4be257 100644 --- a/src/add-ons/kernel/busses/pci/ecam/ECAMPCIController.h +++ b/src/add-ons/kernel/busses/pci/ecam/ECAMPCIController.h @@ -13,6 +13,7 @@ #include #include +#include #define CHECK_RET(err) {status_t _err = (err); if (_err < B_OK) return _err;} @@ -128,7 +129,7 @@ protected: uint8 volatile* fRegs{}; uint64 fRegsLen{}; - pci_resource_range fResourceRanges[kPciRangeEnd] {}; + Vector fResourceRanges; }; diff --git a/src/add-ons/kernel/busses/pci/ecam/ECAMPCIControllerACPI.cpp b/src/add-ons/kernel/busses/pci/ecam/ECAMPCIControllerACPI.cpp index adab914f68..5d692fa4bb 100644 --- a/src/add-ons/kernel/busses/pci/ecam/ECAMPCIControllerACPI.cpp +++ b/src/add-ons/kernel/busses/pci/ecam/ECAMPCIControllerACPI.cpp @@ -106,8 +106,8 @@ DecodeAddress(const T& resource, pci_resource_range& range) addressMaximum = acpiRange.minimum + addressLength - 1; ASSERT((phys_addr_t)(acpiRange.minimum + addressLength - 1) == addressMaximum); - range.host_addr = acpiRange.minimum + acpiRange.translation_offset; - range.pci_addr = acpiRange.minimum; + range.host_address = acpiRange.minimum + acpiRange.translation_offset; + range.pci_address = acpiRange.minimum; range.size = addressLength; } @@ -115,44 +115,46 @@ DecodeAddress(const T& resource, pci_resource_range& range) acpi_status ECAMPCIControllerACPI::AcpiCrsScanCallbackInt(acpi_resource *res) { - uint32 outType; - - switch (res->data.address.resource_type) { - case 0: // ACPI_MEMORY_RANGE - outType = kPciRangeMmio; - if (res->type == ACPI_RESOURCE_TYPE_ADDRESS64) - outType += kPciRangeMmio64Bit; - if (res->data.address.info.mem.caching == 3 /*ACPI_PREFETCHABLE_MEMORY*/) - outType += kPciRangeMmioPrefetch; - break; - case 1: // ACPI_IO_RANGE - outType = kPciRangeIoPort; - break; - default: - return B_OK; - } - - pci_resource_range& range = fResourceRanges[outType]; - range.type = outType; + pci_resource_range range = {}; switch (res->type) { case ACPI_RESOURCE_TYPE_ADDRESS16: { - const auto &address = res->data.address16; + const auto& address = res->data.address16; DecodeAddress(address, range); break; } case ACPI_RESOURCE_TYPE_ADDRESS32: { - const auto &address = res->data.address32; + const auto& address = res->data.address32; DecodeAddress(address, range); + range.address_type |= PCI_address_type_32; break; } case ACPI_RESOURCE_TYPE_ADDRESS64: { - const auto &address = res->data.address64; + const auto& address = res->data.address64; DecodeAddress(address, range); + range.address_type |= PCI_address_type_64; break; } + + default: + return B_OK; } + switch (res->data.address.resource_type) { + case 0: // ACPI_MEMORY_RANGE + range.type = B_IO_MEMORY; + if (res->data.address.info.mem.caching == 3 /*ACPI_PREFETCHABLE_MEMORY*/) + range.address_type |= PCI_address_prefetchable; + break; + case 1: // ACPI_IO_RANGE + range.type = B_IO_PORT; + break; + + default: + return B_OK; + } + + fResourceRanges.Add(range); return B_OK; } diff --git a/src/add-ons/kernel/busses/pci/ecam/ECAMPCIControllerFDT.cpp b/src/add-ons/kernel/busses/pci/ecam/ECAMPCIControllerFDT.cpp index a77f011d77..6038b784a8 100644 --- a/src/add-ons/kernel/busses/pci/ecam/ECAMPCIControllerFDT.cpp +++ b/src/add-ons/kernel/busses/pci/ecam/ECAMPCIControllerFDT.cpp @@ -44,28 +44,30 @@ ECAMPCIControllerFDT::ReadResourceInfo() uint64_t parentAdr = B_BENDIAN_TO_HOST_INT64(*(uint64_t*)(it + 3)); uint64_t len = B_BENDIAN_TO_HOST_INT64(*(uint64_t*)(it + 5)); - uint32 outType = kPciRangeInvalid; + pci_resource_range range = {}; + range.host_address = parentAdr; + range.pci_address = childAdr; + range.size = len; + + if ((type & fdtPciRangePrefechable) != 0) + range.address_type |= PCI_address_prefetchable; + switch (type & fdtPciRangeTypeMask) { case fdtPciRangeIoPort: - outType = kPciRangeIoPort; + range.type = B_IO_PORT; + fResourceRanges.Add(range); break; case fdtPciRangeMmio32Bit: - outType = kPciRangeMmio; + range.type = B_IO_MEMORY; + range.address_type |= PCI_address_type_32; + fResourceRanges.Add(range); break; case fdtPciRangeMmio64Bit: - outType = kPciRangeMmio + kPciRangeMmio64Bit; + range.type = B_IO_MEMORY; + range.address_type |= PCI_address_type_64; + fResourceRanges.Add(range); break; } - if (outType >= kPciRangeMmio && outType < kPciRangeMmioEnd - && (fdtPciRangePrefechable & type) != 0) - outType += kPciRangeMmioPrefetch; - - if (outType != kPciRangeInvalid) { - fResourceRanges[outType].type = outType; - fResourceRanges[outType].host_addr = parentAdr; - fResourceRanges[outType].pci_addr = childAdr; - fResourceRanges[outType].size = len; - } switch (type & fdtPciRangeTypeMask) { case fdtPciRangeConfig: dprintf("CONFIG"); break;