mirror of
https://github.com/torvalds/linux.git
synced 2024-12-02 00:51:44 +00:00
irqchip/gic-v3: Enable non-coherent redistributors/ITSes ACPI probing
The GIC architecture specification defines a set of registers for redistributors and ITSes that control the sharebility and cacheability attributes of redistributors/ITSes initiator ports on the interconnect (GICR_[V]PROPBASER, GICR_[V]PENDBASER, GITS_BASER<n>). Architecturally the GIC provides a means to drive shareability and cacheability attributes signals but it is not mandatory for designs to wire up the corresponding interconnect signals that control the cacheability/shareability of transactions. Redistributors and ITSes interconnect ports can be connected to non-coherent interconnects that are not able to manage the shareability/cacheability attributes; this implicitly makes the redistributors and ITSes non-coherent observers. To enable non-coherent GIC designs on ACPI based systems, parse the MADT GICC/GICR/ITS subtables non-coherent flags to determine whether the respective components are non-coherent observers and force the shareability attributes to be programmed into the redistributors and ITSes registers. An ACPI global function (acpi_get_madt_revision()) is added to retrieve the MADT revision, in that it is essential to check the MADT revision before checking for flags that were added with MADT revision 7 so that if the kernel is booted with an ACPI MADT table with revision < 7 it skips parsing the newly added flags (that should be zeroed reserved values for MADT versions < 7 but they could turn out to be buggy and should be ignored). Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Robin Murphy <robin.murphy@arm.com> Acked-by: Marc Zyngier <maz@kernel.org> Cc: "Rafael J. Wysocki" <rafael@kernel.org> Link: https://lore.kernel.org/r/20240606094238.757649-2-lpieralisi@kernel.org
This commit is contained in:
parent
d011c022ef
commit
ababa16fd9
@ -215,6 +215,21 @@ phys_cpuid_t __init acpi_map_madt_entry(u32 acpi_id)
|
||||
return rv;
|
||||
}
|
||||
|
||||
int __init acpi_get_madt_revision(void)
|
||||
{
|
||||
struct acpi_table_header *madt = NULL;
|
||||
int revision;
|
||||
|
||||
if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, &madt)))
|
||||
return -EINVAL;
|
||||
|
||||
revision = madt->revision;
|
||||
|
||||
acpi_put_table(madt);
|
||||
|
||||
return revision;
|
||||
}
|
||||
|
||||
static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
|
||||
{
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
|
@ -5600,6 +5600,10 @@ static int __init gic_acpi_parse_madt_its(union acpi_subtable_headers *header,
|
||||
goto node_err;
|
||||
}
|
||||
|
||||
if (acpi_get_madt_revision() >= 7 &&
|
||||
(its_entry->flags & ACPI_MADT_ITS_NON_COHERENT))
|
||||
its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE;
|
||||
|
||||
err = its_probe_one(its);
|
||||
if (!err)
|
||||
return 0;
|
||||
|
@ -2349,6 +2349,11 @@ gic_acpi_parse_madt_redist(union acpi_subtable_headers *header,
|
||||
pr_err("Couldn't map GICR region @%llx\n", redist->base_address);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (acpi_get_madt_revision() >= 7 &&
|
||||
(redist->flags & ACPI_MADT_GICR_NON_COHERENT))
|
||||
gic_data.rdists.flags |= RDIST_FLAGS_FORCE_NON_SHAREABLE;
|
||||
|
||||
gic_request_region(redist->base_address, redist->length, "GICR");
|
||||
|
||||
gic_acpi_register_redist(redist->base_address, redist_base);
|
||||
@ -2373,6 +2378,10 @@ gic_acpi_parse_madt_gicc(union acpi_subtable_headers *header,
|
||||
return -ENOMEM;
|
||||
gic_request_region(gicc->gicr_base_address, size, "GICR");
|
||||
|
||||
if (acpi_get_madt_revision() >= 7 &&
|
||||
(gicc->flags & ACPI_MADT_GICC_NON_COHERENT))
|
||||
gic_data.rdists.flags |= RDIST_FLAGS_FORCE_NON_SHAREABLE;
|
||||
|
||||
gic_acpi_register_redist(gicc->gicr_base_address, redist_base);
|
||||
return 0;
|
||||
}
|
||||
|
@ -279,6 +279,9 @@ static inline bool invalid_phys_cpuid(phys_cpuid_t phys_id)
|
||||
return phys_id == PHYS_CPUID_INVALID;
|
||||
}
|
||||
|
||||
|
||||
int __init acpi_get_madt_revision(void);
|
||||
|
||||
/* Validate the processor object's proc_id */
|
||||
bool acpi_duplicate_processor_id(int proc_id);
|
||||
/* Processor _CTS control */
|
||||
|
Loading…
Reference in New Issue
Block a user