PCI: try harder to fixup broken resource ranges in ACPI tables
Try to handle two cases mentionned here: https://github.com/xCuri0/ReBarUEFI/wiki/DSDT-Patching - Min/Max/Length/Gran are all zero, but no resource tag (ignore the range) - Length is larger than Min/Max window (recompute the length) Should fix #18454 Change-Id: I536dc06fcfbfc9aacf5eb6b9563cf03f9d09178a Reviewed-on: https://review.haiku-os.org/c/haiku/+/7581 Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org> Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
parent
dae087ed53
commit
5c6e17e773
@ -87,7 +87,7 @@ ECAMPCIControllerACPI::AcpiCrsScanCallback(acpi_resource *res, void *context)
|
||||
*
|
||||
* This is a template because ACPI resources can be encoded using 8, 16, 32 or 64 bit values.
|
||||
*/
|
||||
template<typename T> void
|
||||
template<typename T> bool
|
||||
DecodeAddress(const T& resource, pci_resource_range& range)
|
||||
{
|
||||
const auto& acpiRange = resource.address;
|
||||
@ -100,15 +100,29 @@ DecodeAddress(const T& resource, pci_resource_range& range)
|
||||
// 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)
|
||||
|
||||
if (addressLength == 0 && addressMaximum <= acpiRange.minimum) {
|
||||
// There's nothing we can do with that...
|
||||
dprintf("PCI: Ignore empty ACPI range\n");
|
||||
return false;
|
||||
} else if (!resource.maxAddress_fixed) {
|
||||
if (addressLength == 0) {
|
||||
dprintf("PCI: maxAddress and addressLength are not set, ignore range\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
dprintf("PCI: maxAddress is not set, compute it\n");
|
||||
addressMaximum = acpiRange.minimum + addressLength - 1;
|
||||
ASSERT((phys_addr_t)(acpiRange.minimum + addressLength - 1) == addressMaximum);
|
||||
} else if (addressLength != addressMaximum - acpiRange.minimum + 1) {
|
||||
dprintf("PCI: Fixup invalid length from ACPI!\n");
|
||||
addressLength = addressMaximum - acpiRange.minimum + 1;
|
||||
}
|
||||
|
||||
range.host_address = acpiRange.minimum + acpiRange.translation_offset;
|
||||
range.pci_address = acpiRange.minimum;
|
||||
range.size = addressLength;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -120,18 +134,21 @@ ECAMPCIControllerACPI::AcpiCrsScanCallbackInt(acpi_resource *res)
|
||||
switch (res->type) {
|
||||
case ACPI_RESOURCE_TYPE_ADDRESS16: {
|
||||
const auto& address = res->data.address16;
|
||||
DecodeAddress(address, range);
|
||||
if (!DecodeAddress(address, range))
|
||||
return B_OK;
|
||||
break;
|
||||
}
|
||||
case ACPI_RESOURCE_TYPE_ADDRESS32: {
|
||||
const auto& address = res->data.address32;
|
||||
DecodeAddress(address, range);
|
||||
if (!DecodeAddress(address, range))
|
||||
return B_OK;
|
||||
range.address_type |= PCI_address_type_32;
|
||||
break;
|
||||
}
|
||||
case ACPI_RESOURCE_TYPE_ADDRESS64: {
|
||||
const auto& address = res->data.address64;
|
||||
DecodeAddress(address, range);
|
||||
if (!DecodeAddress(address, range))
|
||||
return B_OK;
|
||||
range.address_type |= PCI_address_type_64;
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user