提交 5a38bcac 编写于 作者: M 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: NThomas Gleixner <tglx@linutronix.de>
Tested-by: Ndann frazier <dann.frazier@canonical.com>
Tested-by: NHanjun Guo <hanjun.guo@linaro.org>
Reviewed-by: NHanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
上级 fa8d815f
......@@ -41,6 +41,7 @@ extern struct static_key_false arch_timer_read_ool_enabled;
enum arch_timer_erratum_match_type {
ate_match_dt,
ate_match_local_cap_id,
ate_match_acpi_oem_info,
};
struct clock_event_device;
......
......@@ -190,6 +190,12 @@ static struct cyclecounter cyclecounter __ro_after_init = {
.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
/*
* 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
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 *
arch_timer_iterate_errata(enum arch_timer_erratum_match_type type,
ate_match_fn_t match_fn,
......@@ -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;
local = true;
break;
case ate_match_acpi_oem_info:
match_fn = arch_timer_check_acpi_oem_erratum;
break;
default:
WARN_ON(1);
return;
......@@ -1277,6 +1308,9 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
/* Always-on capability */
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();
return 0;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册