PCI: handle "non fixed" addresses
If the max address for a PCI bus is not fixed, try to compute it from the minimum and length (if available). Change-Id: I23d87da32779d22324f944b5b359390f523ec7a7 Reviewed-on: https://review.haiku-os.org/c/haiku/+/7111 Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
parent
a38355a483
commit
8e4a60d3f1
@ -83,6 +83,35 @@ ECAMPCIControllerACPI::AcpiCrsScanCallback(acpi_resource *res, void *context)
|
||||
}
|
||||
|
||||
|
||||
/** Convert an ACPI address resource descriptor into a pci_resource_range.
|
||||
*
|
||||
* This is a template because ACPI resources can be encoded using 8, 16, 32 or 64 bit values.
|
||||
*/
|
||||
template<typename T> void
|
||||
DecodeAddress(const T& resource, pci_resource_range& range)
|
||||
{
|
||||
const auto& acpiRange = resource.address;
|
||||
dprintf("PCI: range from ACPI [%lx(%d),%lx(%d)] with length %lx\n",
|
||||
(unsigned long)acpiRange.minimum, resource.minAddress_fixed,
|
||||
(unsigned long)acpiRange.maximum, resource.maxAddress_fixed,
|
||||
(unsigned long)acpiRange.address_length);
|
||||
|
||||
// If address_length isn't set, compute it from minimum and maximum
|
||||
// If maximum isn't set, compute it from minimum and length
|
||||
auto addressLength = acpiRange.address_length;
|
||||
phys_addr_t addressMaximum = acpiRange.maximum;
|
||||
if (addressLength == 0)
|
||||
addressLength = acpiRange.maximum - acpiRange.minimum + 1;
|
||||
else if (!resource.maxAddress_fixed)
|
||||
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.size = addressLength;
|
||||
}
|
||||
|
||||
|
||||
acpi_status
|
||||
ECAMPCIControllerACPI::AcpiCrsScanCallbackInt(acpi_resource *res)
|
||||
{
|
||||
@ -108,39 +137,18 @@ ECAMPCIControllerACPI::AcpiCrsScanCallbackInt(acpi_resource *res)
|
||||
|
||||
switch (res->type) {
|
||||
case ACPI_RESOURCE_TYPE_ADDRESS16: {
|
||||
const auto &address = res->data.address16.address;
|
||||
// If address_length isn't set, compute it from minimum and maximum
|
||||
auto address_length = address.address_length;
|
||||
if (address_length == 0)
|
||||
address_length = address.maximum - address.minimum + 1;
|
||||
ASSERT(address.minimum + address_length - 1 == address.maximum);
|
||||
range.host_addr = address.minimum + address.translation_offset;
|
||||
range.pci_addr = address.minimum;
|
||||
range.size = address_length;
|
||||
const auto &address = res->data.address16;
|
||||
DecodeAddress(address, range);
|
||||
break;
|
||||
}
|
||||
case ACPI_RESOURCE_TYPE_ADDRESS32: {
|
||||
const auto &address = res->data.address32.address;
|
||||
// If address_length isn't set, compute it from minimum and maximum
|
||||
auto address_length = address.address_length;
|
||||
if (address_length == 0)
|
||||
address_length = address.maximum - address.minimum + 1;
|
||||
ASSERT(address.minimum + address_length - 1 == address.maximum);
|
||||
range.host_addr = address.minimum + address.translation_offset;
|
||||
range.pci_addr = address.minimum;
|
||||
range.size = address_length;
|
||||
const auto &address = res->data.address32;
|
||||
DecodeAddress(address, range);
|
||||
break;
|
||||
}
|
||||
case ACPI_RESOURCE_TYPE_ADDRESS64: {
|
||||
const auto &address = res->data.address64.address;
|
||||
// If address_length isn't set, compute it from minimum and maximum
|
||||
auto address_length = address.address_length;
|
||||
if (address_length == 0)
|
||||
address_length = address.maximum - address.minimum + 1;
|
||||
ASSERT(address.minimum + address_length - 1 == address.maximum);
|
||||
range.host_addr = address.minimum + address.translation_offset;
|
||||
range.pci_addr = address.minimum;
|
||||
range.size = address_length;
|
||||
const auto &address = res->data.address64;
|
||||
DecodeAddress(address, range);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user