diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S index a43746f7a..c35503a09 100644 --- a/include/lib/cpus/aarch64/cpu_macros.S +++ b/include/lib/cpus/aarch64/cpu_macros.S @@ -235,10 +235,11 @@ * _chosen: * Compile time flag on whether the erratum is included * - * _apply_at_reset: - * Whether the erratum should be automatically applied at reset + * _split_wa: + * Flag that indicates whether an erratum has split workaround or not. + * Default value is 0. */ -.macro add_erratum_entry _cpu:req, _cve:req, _id:req, _chosen:req +.macro add_erratum_entry _cpu:req, _cve:req, _id:req, _chosen:req, _split_wa=0 #if REPORT_ERRATA || ERRATA_ABI_SUPPORT .pushsection .rodata.errata_entries .align 3 @@ -250,7 +251,8 @@ /* Will fit CVEs with up to 10 character in the ID field */ .word \_id .hword \_cve - .byte \_chosen + /* bit magic that appends chosen field based on _split_wa */ + .byte ((\_chosen * 0b11) & ((\_split_wa << 1) | \_chosen)) .byte 0x0 /* alignment */ .popsection #endif @@ -276,14 +278,20 @@ * _chosen: * Compile time flag on whether the erratum is included * + * _split_wa: + * Flag that indicates whether an erratum has split workaround or not. + * Default value is 0. + * * in body: * clobber x0 to x7 (please only use those) * argument x7 - cpu_rev_var * * _wa clobbers: x0-x8 (PCS compliant) */ -.macro workaround_reset_start _cpu:req, _cve:req, _id:req, _chosen:req - add_erratum_entry \_cpu, \_cve, \_id, \_chosen +.macro workaround_reset_start _cpu:req, _cve:req, _id:req, \ + _chosen:req, _split_wa=0 + + add_erratum_entry \_cpu, \_cve, \_id, \_chosen, \_split_wa .if \_chosen /* put errata directly into the reset function */ diff --git a/include/lib/cpus/errata.h b/include/lib/cpus/errata.h index 10b949f6c..9eae2767c 100644 --- a/include/lib/cpus/errata.h +++ b/include/lib/cpus/errata.h @@ -42,6 +42,12 @@ struct erratum_entry { uint32_t id; /* Denote CVEs with their year or errata with 0 */ uint16_t cve; + /* + * a bitfield: + * bit 0 - denotes if the erratum is enabled in build. + * bit 1 - denotes if the erratum workaround is split and + * also needs to be implemented at a lower EL. + */ uint8_t chosen; uint8_t _alignment; } __packed; @@ -96,4 +102,11 @@ bool errata_ich_vmcr_el2_applies(void); /* Macro to get CPU revision code for checking errata version compatibility. */ #define CPU_REV(r, p) ((r << 4) | p) +/* Used for errata that have split workaround */ +#define SPLIT_WA 1 + +/* chosen bitfield entries */ +#define WA_ENABLED_MASK BIT(0) +#define SPLIT_WA_MASK BIT(1) + #endif /* ERRATA_H */ diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S index 1ad9557db..5868bf281 100644 --- a/lib/cpus/aarch64/neoverse_n1.S +++ b/lib/cpus/aarch64/neoverse_n1.S @@ -116,7 +116,7 @@ workaround_reset_end neoverse_n1, ERRATUM(1315703) check_erratum_ls neoverse_n1, ERRATUM(1315703), CPU_REV(3, 0) -workaround_reset_start neoverse_n1, ERRATUM(1542419), ERRATA_N1_1542419 +workaround_reset_start neoverse_n1, ERRATUM(1542419), ERRATA_N1_1542419, SPLIT_WA /* Apply instruction patching sequence */ ldr x0, =0x0 msr CPUPSELR_EL3, x0 diff --git a/services/std_svc/errata_abi/errata_abi_main.c b/services/std_svc/errata_abi/errata_abi_main.c index 0d0ecc3d7..a945637b1 100644 --- a/services/std_svc/errata_abi/errata_abi_main.c +++ b/services/std_svc/errata_abi/errata_abi_main.c @@ -197,8 +197,11 @@ int32_t verify_errata_implemented(uint32_t errata_id, uint32_t forward_flag) while ((entry <= end) && (ret_val == EM_UNKNOWN_ERRATUM)) { if (entry->id == errata_id) { if (entry->check_func(rev_var)) { - if (entry->chosen) - return EM_HIGHER_EL_MITIGATION; + if (entry->chosen & WA_ENABLED_MASK) + if (entry->chosen & SPLIT_WA_MASK) + return EM_AFFECTED; + else + return EM_HIGHER_EL_MITIGATION; else return EM_AFFECTED; }