Merge tag 'cris-for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/jesper...
[cascardo/linux.git] / arch / arm64 / include / asm / assembler.h
index 10b017c..28bfe61 100644 (file)
@@ -24,6 +24,7 @@
 #define __ASM_ASSEMBLER_H
 
 #include <asm/asm-offsets.h>
+#include <asm/cpufeature.h>
 #include <asm/page.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/ptrace.h>
        dmb     \opt
        .endm
 
+/*
+ * NOP sequence
+ */
+       .macro  nops, num
+       .rept   \num
+       nop
+       .endr
+       .endm
+
 /*
  * Emit an entry into the exception table
  */
@@ -215,11 +225,26 @@ lr        .req    x30             // link register
        .macro  mmid, rd, rn
        ldr     \rd, [\rn, #MM_CONTEXT_ID]
        .endm
+/*
+ * read_ctr - read CTR_EL0. If the system has mismatched
+ * cache line sizes, provide the system wide safe value
+ * from arm64_ftr_reg_ctrel0.sys_val
+ */
+       .macro  read_ctr, reg
+alternative_if_not ARM64_MISMATCHED_CACHE_LINE_SIZE
+       mrs     \reg, ctr_el0                   // read CTR
+       nop
+alternative_else
+       ldr_l   \reg, arm64_ftr_reg_ctrel0 + ARM64_FTR_SYSVAL
+alternative_endif
+       .endm
+
 
 /*
- * dcache_line_size - get the minimum D-cache line size from the CTR register.
+ * raw_dcache_line_size - get the minimum D-cache line size on this CPU
+ * from the CTR register.
  */
-       .macro  dcache_line_size, reg, tmp
+       .macro  raw_dcache_line_size, reg, tmp
        mrs     \tmp, ctr_el0                   // read CTR
        ubfm    \tmp, \tmp, #16, #19            // cache line size encoding
        mov     \reg, #4                        // bytes per word
@@ -227,15 +252,36 @@ lr        .req    x30             // link register
        .endm
 
 /*
- * icache_line_size - get the minimum I-cache line size from the CTR register.
+ * dcache_line_size - get the safe D-cache line size across all CPUs
  */
-       .macro  icache_line_size, reg, tmp
+       .macro  dcache_line_size, reg, tmp
+       read_ctr        \tmp
+       ubfm            \tmp, \tmp, #16, #19    // cache line size encoding
+       mov             \reg, #4                // bytes per word
+       lsl             \reg, \reg, \tmp        // actual cache line size
+       .endm
+
+/*
+ * raw_icache_line_size - get the minimum I-cache line size on this CPU
+ * from the CTR register.
+ */
+       .macro  raw_icache_line_size, reg, tmp
        mrs     \tmp, ctr_el0                   // read CTR
        and     \tmp, \tmp, #0xf                // cache line size encoding
        mov     \reg, #4                        // bytes per word
        lsl     \reg, \reg, \tmp                // actual cache line size
        .endm
 
+/*
+ * icache_line_size - get the safe I-cache line size across all CPUs
+ */
+       .macro  icache_line_size, reg, tmp
+       read_ctr        \tmp
+       and             \tmp, \tmp, #0xf        // cache line size encoding
+       mov             \reg, #4                // bytes per word
+       lsl             \reg, \reg, \tmp        // actual cache line size
+       .endm
+
 /*
  * tcr_set_idmap_t0sz - update TCR.T0SZ so that we can load the ID map
  */
@@ -261,7 +307,16 @@ lr .req    x30             // link register
        add     \size, \kaddr, \size
        sub     \tmp2, \tmp1, #1
        bic     \kaddr, \kaddr, \tmp2
-9998:  dc      \op, \kaddr
+9998:
+       .if     (\op == cvau || \op == cvac)
+alternative_if_not ARM64_WORKAROUND_CLEAN_CACHE
+       dc      \op, \kaddr
+alternative_else
+       dc      civac, \kaddr
+alternative_endif
+       .else
+       dc      \op, \kaddr
+       .endif
        add     \kaddr, \kaddr, \tmp1
        cmp     \kaddr, \size
        b.lo    9998b