fix(errata): workaround for Cortex-A510 erratum 2250311

Cortex-A510 erratum 2250311 is a Cat B erratum that applies to revisions
r0p0, r0p1, r0p2, r0p3 and r1p0 and is fixed in r1p1.

This erratum workaround is a bit different because it interacts with a
feature supported in TFA. The typical method of implementing an errata
workaround will not work in this case as the MPMM feature would just be
re-enabled by context management at every core power on after being
disabled by the errata framework. So in addition to disabling MPMM, this
workaround also sets a flag in the MPMM runtime framework indicating
that the feature should not be enabled even if ENABLE_MPMM=1.

SDEN can be found here:
https://developer.arm.com/documentation/SDEN2397239

Signed-off-by: John Powell <john.powell@arm.com>
Change-Id: I7805756e65ec90b6ef8af47e200617c9e07a3a7e
This commit is contained in:
johpow01 2022-02-13 21:00:10 -06:00 committed by John Powell
parent e72bbe47ba
commit 7f304b02a8
4 changed files with 77 additions and 4 deletions

View File

@ -493,6 +493,11 @@ For Cortex-A510, the following errata build flags are defined :
in r0p3. The issue is also present in r0p0 and r0p1 but there is no in r0p3. The issue is also present in r0p0 and r0p1 but there is no
workaround for those revisions. workaround for those revisions.
- ``ERRATA_A510_2250311``: This applies errata 2250311 workaround to
Cortex-A510 CPU. This needs to be enabled for revisions r0p0, r0p1, r0p2,
r0p3 and r1p0, it is fixed in r1p1. This workaround disables MPMM even if
ENABLE_MPMM=1.
DSU Errata Workarounds DSU Errata Workarounds
---------------------- ----------------------

View File

@ -153,6 +153,46 @@ func check_errata_2041909
b cpu_rev_var_range b cpu_rev_var_range
endfunc check_errata_2041909 endfunc check_errata_2041909
/* --------------------------------------------------
* Errata Workaround for Cortex-A510 Errata #2250311.
* This applies only to revisions r0p0, r0p1, r0p2,
* r0p3 and r1p0, and is fixed in r1p1.
* This workaround is not a typical errata fix. MPMM
* is disabled here, but this conflicts with the BL31
* MPMM support. So in addition to simply disabling
* the feature, a flag is set in the MPMM library
* indicating that it should not be enabled even if
* ENABLE_MPMM=1.
* x0: variant[4:7] and revision[0:3] of current cpu.
* Shall clobber: x0, x1, x17
* --------------------------------------------------
*/
func errata_cortex_a510_2250311_wa
/* Check workaround compatibility. */
mov x17, x30
bl check_errata_2250311
cbz x0, 1f
/* Disable MPMM */
mrs x0, CPUMPMMCR_EL3
bfm x0, xzr, #0, #0 /* bfc instruction does not work in GCC */
msr CPUMPMMCR_EL3, x0
#if ENABLE_MPMM && IMAGE_BL31
/* If ENABLE_MPMM is set, tell the runtime lib to skip enabling it. */
bl mpmm_errata_disable
#endif
1:
ret x17
endfunc errata_cortex_a510_2250311_wa
func check_errata_2250311
/* Applies to r1p0 and lower */
mov x1, #0x10
b cpu_rev_var_ls
endfunc check_errata_2250311
/* ---------------------------------------------------- /* ----------------------------------------------------
* HW will do the cache maintenance while powering down * HW will do the cache maintenance while powering down
* ---------------------------------------------------- * ----------------------------------------------------
@ -187,6 +227,7 @@ func cortex_a510_errata_report
report_errata ERRATA_A510_2288014, cortex_a510, 2288014 report_errata ERRATA_A510_2288014, cortex_a510, 2288014
report_errata ERRATA_A510_2042739, cortex_a510, 2042739 report_errata ERRATA_A510_2042739, cortex_a510, 2042739
report_errata ERRATA_A510_2041909, cortex_a510, 2041909 report_errata ERRATA_A510_2041909, cortex_a510, 2041909
report_errata ERRATA_A510_2250311, cortex_a510, 2250311
ldp x8, x30, [sp], #16 ldp x8, x30, [sp], #16
ret ret
@ -224,6 +265,11 @@ func cortex_a510_reset_func
bl errata_cortex_a510_2041909_wa bl errata_cortex_a510_2041909_wa
#endif #endif
#if ERRATA_A510_2250311
mov x0, x18
bl errata_cortex_a510_2250311_wa
#endif
ret x19 ret x19
endfunc cortex_a510_reset_func endfunc cortex_a510_reset_func

View File

@ -548,6 +548,10 @@ ERRATA_A510_2042739 ?=0
# present in r0p0 and r0p1 but there is no workaround for those revisions. # present in r0p0 and r0p1 but there is no workaround for those revisions.
ERRATA_A510_2041909 ?=0 ERRATA_A510_2041909 ?=0
# Flag to apply erratum 2250311 workaround during reset. This erratum applies
# to revisions r0p0, r0p1, r0p2, r0p3 and r1p0, and is fixed in r1p1.
ERRATA_A510_2250311 ?=0
# Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0. # Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0.
# Applying the workaround results in higher DSU power consumption on idle. # Applying the workaround results in higher DSU power consumption on idle.
ERRATA_DSU_798953 ?=0 ERRATA_DSU_798953 ?=0
@ -1021,6 +1025,10 @@ $(eval $(call add_define,ERRATA_A510_2042739))
$(eval $(call assert_boolean,ERRATA_A510_2041909)) $(eval $(call assert_boolean,ERRATA_A510_2041909))
$(eval $(call add_define,ERRATA_A510_2041909)) $(eval $(call add_define,ERRATA_A510_2041909))
# Process ERRATA_A510_2250311 flag
$(eval $(call assert_boolean,ERRATA_A510_2250311))
$(eval $(call add_define,ERRATA_A510_2250311))
# Process ERRATA_DSU_798953 flag # Process ERRATA_DSU_798953 flag
$(eval $(call assert_boolean,ERRATA_DSU_798953)) $(eval $(call assert_boolean,ERRATA_DSU_798953))
$(eval $(call add_define,ERRATA_DSU_798953)) $(eval $(call add_define,ERRATA_DSU_798953))

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, Arm Limited. All rights reserved. * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
@ -62,11 +62,25 @@ static bool mpmm_supported(void)
return supported; return supported;
} }
/* Defaults to false */
static bool mpmm_disable_for_errata;
void mpmm_enable(void) void mpmm_enable(void)
{ {
bool supported = mpmm_supported(); if (mpmm_supported()) {
if (mpmm_disable_for_errata) {
if (supported) { WARN("MPMM: disabled by errata workaround\n");
return;
}
write_cpumpmmcr_el3_mpmm_en(1U); write_cpumpmmcr_el3_mpmm_en(1U);
} }
} }
/*
* This function is called from assembly code very early in BL31 so it must be
* small and simple.
*/
void mpmm_errata_disable(void)
{
mpmm_disable_for_errata = true;
}