aarch32: Apply workaround for errata 813419 of Cortex-A57
authorDimitris Papastamos <dimitris.papastamos@arm.com>
Tue, 20 Jun 2017 08:25:10 +0000 (09:25 +0100)
committerDimitris Papastamos <dimitris.papastamos@arm.com>
Thu, 22 Jun 2017 15:42:23 +0000 (16:42 +0100)
TLBI instructions for monitor mode won't have the desired effect under
specific circumstances in Cortex-A57 r0p0. The workaround is to
execute DSB and TLBI twice each time.

Even though this errata is only needed in r0p0, the current errata
framework is not prepared to apply run-time workarounds. The current one
is always applied if compiled in, regardless of the CPU or its revision.

The `DSB` instruction used when initializing the translation tables has
been changed to `DSB ISH` as an optimization and to be consistent with
the barriers used for the workaround.

NOTE: This workaround is present in AArch64 TF and already enabled by
default on Juno.

Change-Id: I10b0baa304ed64b13b7b26ea766e61461e759dfa
Signed-off-by: Dimitris Papastamos <dimitris.papastamos@arm.com>
include/lib/aarch32/arch_helpers.h
lib/xlat_tables/aarch32/xlat_tables.c
lib/xlat_tables_v2/aarch32/xlat_tables_arch.c

index e652a59ec631459983d4830f56897caa53854483..bd1ac25e40d9c2de115e502e10b749a44b2f1565 100644 (file)
@@ -100,15 +100,30 @@ static inline void write_ ## _name(const u_register_t v)          \
  * Macros to create inline functions for tlbi operations
  *********************************************************************/
 
+#if ERRATA_A57_813419
+/*
+ * Define function for TLBI instruction with type specifier that
+ * implements the workaround for errata 813419 of Cortex-A57
+ */
 #define _DEFINE_TLBIOP_FUNC(_op, coproc, opc1, CRn, CRm, opc2)         \
 static inline void tlbi##_op(void)                                     \
 {                                                                      \
        u_register_t v = 0;                                             \
        __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
+       __asm__ volatile ("dsb ish");\
+       __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
 }
 
-#define _DEFINE_BPIOP_FUNC(_op, coproc, opc1, CRn, CRm, opc2)          \
-static inline void bpi##_op(void)                                      \
+#define _DEFINE_TLBIOP_PARAM_FUNC(_op, coproc, opc1, CRn, CRm, opc2)   \
+static inline void tlbi##_op(u_register_t v)                           \
+{                                                                      \
+       __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
+       __asm__ volatile ("dsb ish");\
+       __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
+}
+#else
+#define _DEFINE_TLBIOP_FUNC(_op, coproc, opc1, CRn, CRm, opc2)         \
+static inline void tlbi##_op(void)                                     \
 {                                                                      \
        u_register_t v = 0;                                             \
        __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
@@ -119,6 +134,14 @@ static inline void tlbi##_op(u_register_t v)                               \
 {                                                                      \
        __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
 }
+#endif /* ERRATA_A57_813419 */
+
+#define _DEFINE_BPIOP_FUNC(_op, coproc, opc1, CRn, CRm, opc2)          \
+static inline void bpi##_op(void)                                      \
+{                                                                      \
+       u_register_t v = 0;                                             \
+       __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
+}
 
 /* Define function for simple TLBI operation */
 #define DEFINE_TLBIOP_FUNC(_op, ...)                                   \
index 3c9051c345b8902d7c3b7e3cd93d18d6e2669d83..9c1562407be3ead109b94d1f2d55e227f3ab4505 100644 (file)
@@ -149,7 +149,7 @@ void enable_mmu_secure(unsigned int flags)
         * and translation register writes are committed
         * before enabling the MMU
         */
-       dsb();
+       dsbish();
        isb();
 
        sctlr = read_sctlr();
index afc65e7d0b1a02c68af21276cbca9c0bd8a60141..40fd2d0b059ea090f419644a2e504b2abad9ec3c 100644 (file)
@@ -141,7 +141,7 @@ void enable_mmu_internal_secure(unsigned int flags, uint64_t *base_table)
         * and translation register writes are committed
         * before enabling the MMU
         */
-       dsb();
+       dsbish();
        isb();
 
        sctlr = read_sctlr();