[SPARC64]: Add initial code to twiddle %gl on trap entry/exit.
[firefly-linux-kernel-4.4.55.git] / include / asm-sparc64 / cpudata.h
index f83768883e983ec67ac6d6394fca4d90560d789f..8666440c89af1c7dfc331b047b9f08eb839aacb3 100644 (file)
@@ -60,9 +60,24 @@ struct trap_per_cpu {
 } __attribute__((aligned(64)));
 extern struct trap_per_cpu trap_block[NR_CPUS];
 extern void init_cur_cpu_trap(void);
-extern void per_cpu_patch(void);
 extern void setup_tba(void);
 
+#ifdef CONFIG_SMP
+struct cpuid_patch_entry {
+       unsigned int    addr;
+       unsigned int    cheetah_safari[4];
+       unsigned int    cheetah_jbus[4];
+       unsigned int    starfire[4];
+       unsigned int    sun4v[4];
+};
+extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end;
+#endif
+
+struct gl_1insn_patch_entry {
+       unsigned int    addr;
+       unsigned int    insn;
+};
+extern struct gl_1insn_patch_entry __gl_1insn_patch, __gl_1insn_patch_end;
 #endif /* !(__ASSEMBLY__) */
 
 #define TRAP_PER_CPU_THREAD    0x00
@@ -70,56 +85,103 @@ extern void setup_tba(void);
 
 #define TRAP_BLOCK_SZ_SHIFT    6
 
-/* Clobbers %g1, loads %g6 with local processor's cpuid */
-#define __GET_CPUID                    \
-       ba,pt   %xcc, __get_cpu_id;     \
-        rd     %pc, %g1;
-
-/* Clobbers %g1, current address space PGD phys address into %g7.  */
-#define TRAP_LOAD_PGD_PHYS                     \
-       __GET_CPUID                             \
-       sllx    %g6, TRAP_BLOCK_SZ_SHIFT, %g6;  \
-       sethi   %hi(trap_block), %g7;           \
-       or      %g7, %lo(trap_block), %g7;      \
-       add     %g7, %g6, %g7;                  \
-       ldx     [%g7 + TRAP_PER_CPU_PGD_PADDR], %g7;
-
-/* Clobbers %g1, loads local processor's IRQ work area into %g6.  */
-#define TRAP_LOAD_IRQ_WORK                     \
-       __GET_CPUID                             \
-       sethi   %hi(__irq_work), %g1;           \
-       sllx    %g6, 6, %g6;                    \
-       or      %g1, %lo(__irq_work), %g1;      \
-       add     %g1, %g6, %g6;
-
-/* Clobbers %g1, loads %g6 with current thread info pointer.  */
-#define TRAP_LOAD_THREAD_REG                   \
-       __GET_CPUID                             \
-       sllx    %g6, TRAP_BLOCK_SZ_SHIFT, %g6;  \
-       sethi   %hi(trap_block), %g1;           \
-       or      %g1, %lo(trap_block), %g1;      \
-       ldx     [%g1 + %g6], %g6;
-
-/* Given the current thread info pointer in %g6, load the per-cpu
- * area base of the current processor into %g5.  REG1, REG2, and REG3 are
+#include <asm/scratchpad.h>
+
+#ifdef CONFIG_SMP
+
+#define __GET_CPUID(REG)                               \
+       /* Spitfire implementation (default). */        \
+661:   ldxa            [%g0] ASI_UPA_CONFIG, REG;      \
+       srlx            REG, 17, REG;                   \
+        and            REG, 0x1f, REG;                 \
+       nop;                                            \
+       .section        .cpuid_patch, "ax";             \
+       /* Instruction location. */                     \
+       .word           661b;                           \
+       /* Cheetah Safari implementation. */            \
+       ldxa            [%g0] ASI_SAFARI_CONFIG, REG;   \
+       srlx            REG, 17, REG;                   \
+       and             REG, 0x3ff, REG;                \
+       nop;                                            \
+       /* Cheetah JBUS implementation. */              \
+       ldxa            [%g0] ASI_JBUS_CONFIG, REG;     \
+       srlx            REG, 17, REG;                   \
+       and             REG, 0x1f, REG;                 \
+       nop;                                            \
+       /* Starfire implementation. */                  \
+       sethi           %hi(0x1fff40000d0 >> 9), REG;   \
+       sllx            REG, 9, REG;                    \
+       or              REG, 0xd0, REG;                 \
+       lduwa           [REG] ASI_PHYS_BYPASS_EC_E, REG;\
+       /* sun4v implementation. */                     \
+       mov             SCRATCHPAD_CPUID, REG;          \
+       nop;                                            \
+       ldxa            [REG] ASI_SCRATCHPAD, REG;      \
+       nop;                                            \
+       .previous;
+
+/* Clobbers TMP, current address space PGD phys address into DEST.  */
+#define TRAP_LOAD_PGD_PHYS(DEST, TMP)          \
+       __GET_CPUID(TMP)                        \
+       sethi   %hi(trap_block), DEST;          \
+       sllx    TMP, TRAP_BLOCK_SZ_SHIFT, TMP;  \
+       or      DEST, %lo(trap_block), DEST;    \
+       add     DEST, TMP, DEST;                \
+       ldx     [DEST + TRAP_PER_CPU_PGD_PADDR], DEST;
+
+/* Clobbers TMP, loads local processor's IRQ work area into DEST.  */
+#define TRAP_LOAD_IRQ_WORK(DEST, TMP)          \
+       __GET_CPUID(TMP)                        \
+       sethi   %hi(__irq_work), DEST;          \
+       sllx    TMP, 6, TMP;                    \
+       or      DEST, %lo(__irq_work), DEST;    \
+       add     DEST, TMP, DEST;
+
+/* Clobbers TMP, loads DEST with current thread info pointer.  */
+#define TRAP_LOAD_THREAD_REG(DEST, TMP)                \
+       __GET_CPUID(TMP)                        \
+       sethi   %hi(trap_block), DEST;          \
+       sllx    TMP, TRAP_BLOCK_SZ_SHIFT, TMP;  \
+       or      DEST, %lo(trap_block), DEST;    \
+       ldx     [DEST + TMP], DEST;
+
+/* Given the current thread info pointer in THR, load the per-cpu
+ * area base of the current processor into DEST.  REG1, REG2, and REG3 are
  * clobbered.
  *
- * You absolutely cannot use %g5 as a temporary in this code.  The
+ * You absolutely cannot use DEST as a temporary in this code.  The
  * reason is that traps can happen during execution, and return from
- * trap will load the fully resolved %g5 per-cpu base.  This can corrupt
+ * trap will load the fully resolved DEST per-cpu base.  This can corrupt
  * the calculations done by the macro mid-stream.
  */
-#ifdef CONFIG_SMP
-#define LOAD_PER_CPU_BASE(REG1, REG2, REG3)            \
-       ldub    [%g6 + TI_CPU], REG1;                   \
+#define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3) \
+       ldub    [THR + TI_CPU], REG1;                   \
        sethi   %hi(__per_cpu_shift), REG3;             \
        sethi   %hi(__per_cpu_base), REG2;              \
        ldx     [REG3 + %lo(__per_cpu_shift)], REG3;    \
        ldx     [REG2 + %lo(__per_cpu_base)], REG2;     \
        sllx    REG1, REG3, REG3;                       \
-       add     REG3, REG2, %g5;
+       add     REG3, REG2, DEST;
+
 #else
-#define LOAD_PER_CPU_BASE(REG1, REG2, REG3)
-#endif
+
+/* Uniprocessor versions, we know the cpuid is zero.  */
+#define TRAP_LOAD_PGD_PHYS(DEST, TMP)          \
+       sethi   %hi(trap_block), DEST;          \
+       or      DEST, %lo(trap_block), DEST;    \
+       ldx     [DEST + TRAP_PER_CPU_PGD_PADDR], DEST;
+
+#define TRAP_LOAD_IRQ_WORK(DEST, TMP)          \
+       sethi   %hi(__irq_work), DEST;          \
+       or      DEST, %lo(__irq_work), DEST;
+
+#define TRAP_LOAD_THREAD_REG(DEST, TMP)                \
+       sethi   %hi(trap_block), DEST;          \
+       ldx     [DEST + %lo(trap_block)], DEST;
+
+/* No per-cpu areas on uniprocessor, so no need to load DEST.  */
+#define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3)
+
+#endif /* !(CONFIG_SMP) */
 
 #endif /* _SPARC64_CPUDATA_H */