Commit 5a38bcac authored by Marc Zyngier's avatar Marc Zyngier

arm64: arch_timer: Allow erratum matching with ACPI OEM information

Just as we're able to identify a broken platform using some DT
information, let's enable a way to spot the offenders with ACPI.

The difference is that we can only match on some OEM info instead
of implementation-specific properties. So in order to avoid the
insane multiplication of errata structures, we allow an array
of OEM descriptions to be attached to an erratum structure.
Acked-by: default avatarThomas Gleixner <tglx@linutronix.de>
Tested-by: default avatardann frazier <dann.frazier@canonical.com>
Tested-by: default avatarHanjun Guo <hanjun.guo@linaro.org>
Reviewed-by: default avatarHanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent fa8d815f
...@@ -41,6 +41,7 @@ extern struct static_key_false arch_timer_read_ool_enabled; ...@@ -41,6 +41,7 @@ extern struct static_key_false arch_timer_read_ool_enabled;
enum arch_timer_erratum_match_type { enum arch_timer_erratum_match_type {
ate_match_dt, ate_match_dt,
ate_match_local_cap_id, ate_match_local_cap_id,
ate_match_acpi_oem_info,
}; };
struct clock_event_device; struct clock_event_device;
......
...@@ -190,6 +190,12 @@ static struct cyclecounter cyclecounter __ro_after_init = { ...@@ -190,6 +190,12 @@ static struct cyclecounter cyclecounter __ro_after_init = {
.mask = CLOCKSOURCE_MASK(56), .mask = CLOCKSOURCE_MASK(56),
}; };
struct ate_acpi_oem_info {
char oem_id[ACPI_OEM_ID_SIZE + 1];
char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
u32 oem_revision;
};
#ifdef CONFIG_FSL_ERRATUM_A008585 #ifdef CONFIG_FSL_ERRATUM_A008585
/* /*
* The number of retries is an arbitrary value well beyond the highest number * The number of retries is an arbitrary value well beyond the highest number
...@@ -371,6 +377,28 @@ bool arch_timer_check_local_cap_erratum(const struct arch_timer_erratum_workarou ...@@ -371,6 +377,28 @@ bool arch_timer_check_local_cap_erratum(const struct arch_timer_erratum_workarou
return this_cpu_has_cap((uintptr_t)wa->id); return this_cpu_has_cap((uintptr_t)wa->id);
} }
static
bool arch_timer_check_acpi_oem_erratum(const struct arch_timer_erratum_workaround *wa,
const void *arg)
{
static const struct ate_acpi_oem_info empty_oem_info = {};
const struct ate_acpi_oem_info *info = wa->id;
const struct acpi_table_header *table = arg;
/* Iterate over the ACPI OEM info array, looking for a match */
while (memcmp(info, &empty_oem_info, sizeof(*info))) {
if (!memcmp(info->oem_id, table->oem_id, ACPI_OEM_ID_SIZE) &&
!memcmp(info->oem_table_id, table->oem_table_id, ACPI_OEM_TABLE_ID_SIZE) &&
info->oem_revision == table->oem_revision)
return true;
info++;
}
return false;
}
static const struct arch_timer_erratum_workaround * static const struct arch_timer_erratum_workaround *
arch_timer_iterate_errata(enum arch_timer_erratum_match_type type, arch_timer_iterate_errata(enum arch_timer_erratum_match_type type,
ate_match_fn_t match_fn, ate_match_fn_t match_fn,
...@@ -431,6 +459,9 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t ...@@ -431,6 +459,9 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
match_fn = arch_timer_check_local_cap_erratum; match_fn = arch_timer_check_local_cap_erratum;
local = true; local = true;
break; break;
case ate_match_acpi_oem_info:
match_fn = arch_timer_check_acpi_oem_erratum;
break;
default: default:
WARN_ON(1); WARN_ON(1);
return; return;
...@@ -1277,6 +1308,9 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table) ...@@ -1277,6 +1308,9 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
/* Always-on capability */ /* Always-on capability */
arch_timer_c3stop = !(gtdt->non_secure_el1_flags & ACPI_GTDT_ALWAYS_ON); arch_timer_c3stop = !(gtdt->non_secure_el1_flags & ACPI_GTDT_ALWAYS_ON);
/* Check for globally applicable workarounds */
arch_timer_check_ool_workaround(ate_match_acpi_oem_info, table);
arch_timer_init(); arch_timer_init();
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment