diff --git a/docs/cpu-specific-build-macros.md b/docs/cpu-specific-build-macros.md index 2368fd2..d9b7108 100644 --- a/docs/cpu-specific-build-macros.md +++ b/docs/cpu-specific-build-macros.md @@ -43,6 +43,15 @@ The value of the build flags are 0 by default, that is, disabled. Any other value will enable it. +For Cortex-A53, following errata build flags are defined : + +* `ERRATA_A53_826319`: This applies errata 826319 workaround to Cortex-A53 + CPU. This needs to be enabled only for revision <= r0p2 of the CPU. + +* `ERRATA_A53_836870`: This applies errata 836870 workaround to Cortex-A53 + CPU. This needs to be enabled only for revision <= r0p3 of the CPU. From + r0p4 and onwards, this errata is enabled by default. + For Cortex-A57, following errata build flags are defined : * `ERRATA_A57_806969`: This applies errata 806969 workaround to Cortex-A57 diff --git a/include/lib/cpus/aarch64/cortex_a53.h b/include/lib/cpus/aarch64/cortex_a53.h index 14821ab..6e71f9c 100644 --- a/include/lib/cpus/aarch64/cortex_a53.h +++ b/include/lib/cpus/aarch64/cortex_a53.h @@ -41,4 +41,19 @@ #define CPUECTLR_SMP_BIT (1 << 6) +/******************************************************************************* + * CPU Auxiliary Control register specific definitions. + ******************************************************************************/ +#define CPUACTLR_EL1 S3_1_C15_C2_0 /* Instruction def. */ + +#define CPUACTLR_DTAH (1 << 24) + +/******************************************************************************* + * L2 Auxiliary Control register specific definitions. + ******************************************************************************/ +#define L2ACTLR_EL1 S3_1_C15_C0_0 /* Instruction def. */ + +#define L2ACTLR_ENABLE_UNIQUECLEAN (1 << 14) +#define L2ACTLR_DISABLE_CLEAN_PUSH (1 << 3) + #endif /* __CORTEX_A53_H__ */ diff --git a/lib/cpus/aarch64/cortex_a53.S b/lib/cpus/aarch64/cortex_a53.S index e149e6e..e4b94e8 100644 --- a/lib/cpus/aarch64/cortex_a53.S +++ b/lib/cpus/aarch64/cortex_a53.S @@ -59,11 +59,93 @@ ret endfunc cortex_a53_disable_smp + /* -------------------------------------------------- + * Errata Workaround for Cortex A53 Errata #826319. + * This applies only to revision <= r0p2 of Cortex A53. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Clobbers : x0 - x5 + * -------------------------------------------------- + */ +func errata_a53_826319_wa + /* + * Compare x0 against revision r0p2 + */ + cmp x0, #2 + b.ls apply_826319 +#if DEBUG + b print_revision_warning +#else + ret +#endif +apply_826319: + mrs x1, L2ACTLR_EL1 + bic x1, x1, #L2ACTLR_ENABLE_UNIQUECLEAN + orr x1, x1, #L2ACTLR_DISABLE_CLEAN_PUSH + msr L2ACTLR_EL1, x1 + ret +endfunc errata_a53_826319_wa + + /* -------------------------------------------------- + * Errata Workaround for Cortex A53 Errata #836870. + * This applies only to revision <= r0p3 of Cortex A53. + * From r0p4 and onwards, this errata is enabled by + * default. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Clobbers : x0 - x5 + * -------------------------------------------------- + */ +func errata_a53_836870_wa + /* + * Compare x0 against revision r0p3 + */ + cmp x0, #3 + b.ls apply_836870 +#if DEBUG + b print_revision_warning +#else + ret +#endif +apply_836870: + mrs x1, CPUACTLR_EL1 + orr x1, x1, #CPUACTLR_DTAH + msr CPUACTLR_EL1, x1 + ret +endfunc errata_a53_836870_wa + + /* ------------------------------------------------- + * The CPU Ops reset function for Cortex-A53. + * Clobbers: x0-x5, x15, x19, x30 + * ------------------------------------------------- + */ func cortex_a53_reset_func + mov x19, x30 + mrs x0, midr_el1 + + /* + * Extract the variant[20:23] and revision[0:3] from x0 + * and pack it in x15[0:7] as variant[4:7] and revision[0:3]. + * First extract x0[16:23] to x15[0:7] and zero fill the rest. + * Then extract x0[0:3] into x15[0:3] retaining other bits. + */ + ubfx x15, x0, #(MIDR_VAR_SHIFT - MIDR_REV_BITS), \ + #(MIDR_REV_BITS + MIDR_VAR_BITS) + bfxil x15, x0, #MIDR_REV_SHIFT, #MIDR_REV_BITS + +#if ERRATA_A53_826319 + mov x0, x15 + bl errata_a53_826319_wa +#endif + +#if ERRATA_A53_836870 + mov x0, x15 + bl errata_a53_836870_wa +#endif + /* --------------------------------------------- * As a bare minimum enable the SMP bit if it is * not already set. - * Clobbers : x0 * --------------------------------------------- */ mrs x0, CPUECTLR_EL1 @@ -71,9 +153,9 @@ b.ne skip_smp_setup orr x0, x0, #CPUECTLR_SMP_BIT msr CPUECTLR_EL1, x0 - isb skip_smp_setup: - ret + isb + ret x19 endfunc cortex_a53_reset_func func cortex_a53_core_pwr_dwn diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 1c5512e..a872360 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -40,6 +40,15 @@ # CPU Errata Build flags. These should be enabled by the # platform if the errata needs to be applied. +# Flag to apply errata 826319 during reset. This errata applies only to +# revision <= r0p2 of the Cortex A53 cpu. +ERRATA_A53_826319 ?=0 + +# Flag to apply errata 836870 during reset. This errata applies only to +# revision <= r0p3 of the Cortex A53 cpu. From r0p4 and onwards, this +# errata is enabled by default. +ERRATA_A53_836870 ?=0 + # Flag to apply errata 806969 during reset. This errata applies only to # revision r0p0 of the Cortex A57 cpu. ERRATA_A57_806969 ?=0 @@ -48,6 +57,14 @@ # revision r0p0 of the Cortex A57 cpu. ERRATA_A57_813420 ?=0 +# Process ERRATA_A53_826319 flag +$(eval $(call assert_boolean,ERRATA_A53_826319)) +$(eval $(call add_define,ERRATA_A53_826319)) + +# Process ERRATA_A53_836870 flag +$(eval $(call assert_boolean,ERRATA_A53_836870)) +$(eval $(call add_define,ERRATA_A53_836870)) + # Process ERRATA_A57_806969 flag $(eval $(call assert_boolean,ERRATA_A57_806969)) $(eval $(call add_define,ERRATA_A57_806969))