]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
Add wrapper for AT instruction
authorManish V Badarkhe <Manish.Badarkhe@arm.com>
Tue, 14 Jul 2020 13:43:12 +0000 (14:43 +0100)
committerManish V Badarkhe <Manish.Badarkhe@arm.com>
Tue, 18 Aug 2020 09:49:27 +0000 (10:49 +0100)
In case of AT speculative workaround applied, page table walk
is disabled for lower ELs (EL1 and EL0) in EL3.
Hence added a wrapper function which temporarily enables page
table walk to execute AT instruction for lower ELs and then
disables page table walk.

Execute AT instructions directly for lower ELs (EL1 and EL0)
assuming page table walk is enabled always when AT speculative
workaround is not applied.

Change-Id: I4ad4c0bcbb761448af257e9f72ae979473c0dde8
Signed-off-by: Manish V Badarkhe <Manish.Badarkhe@arm.com>
common/backtrace/backtrace.c
include/arch/aarch64/arch_helpers.h
plat/arm/common/arm_common.c
services/spd/tlkd/tlkd_common.c

index ef575006fd47d4c5b64e379a57cd000875783a1b..a07c066ceaf1a28d6c32b7ba7955d64d7efc23dd 100644 (file)
@@ -70,7 +70,7 @@ static bool is_address_readable(uintptr_t addr)
        } else if (el == 2U) {
                ats1e2r(addr);
        } else {
-               ats1e1r(addr);
+               AT(ats1e1r, addr);
        }
 
        isb();
index 4bff0f6f0b5fc1157d5bb2497be944bd7a459bc7..1f2f4a92338767c31103887f183d21b194b0b95b 100644 (file)
@@ -590,4 +590,24 @@ static inline uint64_t el_implemented(unsigned int el)
 #define read_clusterpwrdn()    read_clusterpwrdn_el1()
 #define write_clusterpwrdn(_v) write_clusterpwrdn_el1(_v)
 
+#if ERRATA_SPECULATIVE_AT
+/*
+ * Assuming SCTLR.M bit is already enabled
+ * 1. Enable page table walk by clearing TCR_EL1.EPDx bits
+ * 2. Execute AT instruction for lower EL1/0
+ * 3. Disable page table walk by setting TCR_EL1.EPDx bits
+ */
+#define AT(_at_inst, _va)      \
+{      \
+       assert((read_sctlr_el1() & SCTLR_M_BIT) != 0ULL);       \
+       write_tcr_el1(read_tcr_el1() & ~(TCR_EPD0_BIT | TCR_EPD1_BIT)); \
+       isb();  \
+       _at_inst(_va);  \
+       write_tcr_el1(read_tcr_el1() | (TCR_EPD0_BIT | TCR_EPD1_BIT));  \
+       isb();  \
+}
+#else
+#define AT(_at_inst, _va)      _at_inst(_va);
+#endif
+
 #endif /* ARCH_HELPERS_H */
index e2b99a3d6dd2dcf5f9474b1fb2357c05f1c528f6..e55ea90f890c6a79b0e50e09a66f45ee5bbf9220 100644 (file)
@@ -216,7 +216,7 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode)
                 * Translate entry point to Physical Address using the EL1&0
                 * translation regime, including stage 2.
                 */
-               ats12e1r(ep);
+               AT(ats12e1r, ep);
        }
        isb();
        par = read_par_el1();
index dbe6c2e34b1078021542395c90c7cbda556a40ec..820bd8a7209a3ff170fd5060977c8d95fe725ca7 100644 (file)
@@ -38,16 +38,16 @@ uint64_t tlkd_va_translate(uintptr_t va, int type)
        int at = type & AT_MASK;
        switch (at) {
        case 0:
-               ats12e1r(va);
+               AT(ats12e1r, va);
                break;
        case 1:
-               ats12e1w(va);
+               AT(ats12e1w, va);
                break;
        case 2:
-               ats12e0r(va);
+               AT(ats12e0r, va);
                break;
        case 3:
-               ats12e0w(va);
+               AT(ats12e0w, va);
                break;
        default:
                assert(0); /* Unreachable */