summaryrefslogtreecommitdiff
path: root/arch/mips/include/asm/stackframe.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/include/asm/stackframe.h')
-rw-r--r--arch/mips/include/asm/stackframe.h590
1 files changed, 236 insertions, 354 deletions
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h
index 23fc95e65673..a13431379073 100644
--- a/arch/mips/include/asm/stackframe.h
+++ b/arch/mips/include/asm/stackframe.h
@@ -17,31 +17,45 @@
#include <asm/asmmacro.h>
#include <asm/mipsregs.h>
#include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
-/*
- * For SMTC kernel, global IE should be left set, and interrupts
- * controlled exclusively via IXMT.
- */
-#ifdef CONFIG_MIPS_MT_SMTC
-#define STATMASK 0x1e
-#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+/* Make the addition of cfi info a little easier. */
+ .macro cfi_rel_offset reg offset=0 docfi=0
+ .if \docfi
+ .cfi_rel_offset \reg, \offset
+ .endif
+ .endm
+
+ .macro cfi_st reg offset=0 docfi=0
+ LONG_S \reg, \offset(sp)
+ cfi_rel_offset \reg, \offset, \docfi
+ .endm
+
+ .macro cfi_restore reg offset=0 docfi=0
+ .if \docfi
+ .cfi_restore \reg
+ .endif
+ .endm
+
+ .macro cfi_ld reg offset=0 docfi=0
+ LONG_L \reg, \offset(sp)
+ cfi_restore \reg \offset \docfi
+ .endm
+
+#if defined(CONFIG_CPU_R3000)
#define STATMASK 0x3f
#else
#define STATMASK 0x1f
#endif
-#ifdef CONFIG_MIPS_MT_SMTC
-#include <asm/mipsmtregs.h>
-#endif /* CONFIG_MIPS_MT_SMTC */
-
- .macro SAVE_AT
+ .macro SAVE_AT docfi=0
.set push
.set noat
- LONG_S $1, PT_R1(sp)
+ cfi_st $1, PT_R1, \docfi
.set pop
.endm
- .macro SAVE_TEMP
+ .macro SAVE_TEMP docfi=0
#ifdef CONFIG_CPU_HAS_SMARTMIPS
mflhxu v1
LONG_S v1, PT_LO(sp)
@@ -49,25 +63,25 @@
LONG_S v1, PT_HI(sp)
mflhxu v1
LONG_S v1, PT_ACX(sp)
-#else
+#elif !defined(CONFIG_CPU_MIPSR6)
mfhi v1
#endif
#ifdef CONFIG_32BIT
- LONG_S $8, PT_R8(sp)
- LONG_S $9, PT_R9(sp)
+ cfi_st $8, PT_R8, \docfi
+ cfi_st $9, PT_R9, \docfi
#endif
- LONG_S $10, PT_R10(sp)
- LONG_S $11, PT_R11(sp)
- LONG_S $12, PT_R12(sp)
-#ifndef CONFIG_CPU_HAS_SMARTMIPS
+ cfi_st $10, PT_R10, \docfi
+ cfi_st $11, PT_R11, \docfi
+ cfi_st $12, PT_R12, \docfi
+#if !defined(CONFIG_CPU_HAS_SMARTMIPS) && !defined(CONFIG_CPU_MIPSR6)
LONG_S v1, PT_HI(sp)
mflo v1
#endif
- LONG_S $13, PT_R13(sp)
- LONG_S $14, PT_R14(sp)
- LONG_S $15, PT_R15(sp)
- LONG_S $24, PT_R24(sp)
-#ifndef CONFIG_CPU_HAS_SMARTMIPS
+ cfi_st $13, PT_R13, \docfi
+ cfi_st $14, PT_R14, \docfi
+ cfi_st $15, PT_R15, \docfi
+ cfi_st $24, PT_R24, \docfi
+#if !defined(CONFIG_CPU_HAS_SMARTMIPS) && !defined(CONFIG_CPU_MIPSR6)
LONG_S v1, PT_LO(sp)
#endif
#ifdef CONFIG_CPU_CAVIUM_OCTEON
@@ -80,34 +94,29 @@
#endif
.endm
- .macro SAVE_STATIC
- LONG_S $16, PT_R16(sp)
- LONG_S $17, PT_R17(sp)
- LONG_S $18, PT_R18(sp)
- LONG_S $19, PT_R19(sp)
- LONG_S $20, PT_R20(sp)
- LONG_S $21, PT_R21(sp)
- LONG_S $22, PT_R22(sp)
- LONG_S $23, PT_R23(sp)
- LONG_S $30, PT_R30(sp)
+ .macro SAVE_STATIC docfi=0
+ cfi_st $16, PT_R16, \docfi
+ cfi_st $17, PT_R17, \docfi
+ cfi_st $18, PT_R18, \docfi
+ cfi_st $19, PT_R19, \docfi
+ cfi_st $20, PT_R20, \docfi
+ cfi_st $21, PT_R21, \docfi
+ cfi_st $22, PT_R22, \docfi
+ cfi_st $23, PT_R23, \docfi
+ cfi_st $30, PT_R30, \docfi
.endm
+/*
+ * get_saved_sp returns the SP for the current CPU by looking in the
+ * kernelsp array for it. If tosp is set, it stores the current sp in
+ * k0 and loads the new value in sp. If not, it clobbers k0 and
+ * stores the new value in k1, leaving sp unaffected.
+ */
#ifdef CONFIG_SMP
-#ifdef CONFIG_MIPS_MT_SMTC
-#define PTEBASE_SHIFT 19 /* TCBIND */
-#define CPU_ID_REG CP0_TCBIND
-#define CPU_ID_MFC0 mfc0
-#elif defined(CONFIG_MIPS_PGD_C0_CONTEXT)
-#define PTEBASE_SHIFT 48 /* XCONTEXT */
-#define CPU_ID_REG CP0_XCONTEXT
-#define CPU_ID_MFC0 MFC0
-#else
-#define PTEBASE_SHIFT 23 /* CONTEXT */
-#define CPU_ID_REG CP0_CONTEXT
-#define CPU_ID_MFC0 MFC0
-#endif
- .macro get_saved_sp /* SMP variation */
- CPU_ID_MFC0 k0, CPU_ID_REG
+
+ /* SMP variation */
+ .macro get_saved_sp docfi=0 tosp=0
+ ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG
#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
lui k1, %hi(kernelsp)
#else
@@ -117,18 +126,27 @@
daddiu k1, %hi(kernelsp)
dsll k1, 16
#endif
- LONG_SRL k0, PTEBASE_SHIFT
+ LONG_SRL k0, SMP_CPUID_PTRSHIFT
LONG_ADDU k1, k0
+ .if \tosp
+ move k0, sp
+ .if \docfi
+ .cfi_register sp, k0
+ .endif
+ LONG_L sp, %lo(kernelsp)(k1)
+ .else
LONG_L k1, %lo(kernelsp)(k1)
+ .endif
.endm
.macro set_saved_sp stackp temp temp2
- CPU_ID_MFC0 \temp, CPU_ID_REG
- LONG_SRL \temp, PTEBASE_SHIFT
+ ASM_CPUID_MFC0 \temp, ASM_SMP_CPUID_REG
+ LONG_SRL \temp, SMP_CPUID_PTRSHIFT
LONG_S \stackp, kernelsp(\temp)
.endm
-#else
- .macro get_saved_sp /* Uniprocessor variation */
+#else /* !CONFIG_SMP */
+ /* Uniprocessor variation */
+ .macro get_saved_sp docfi=0 tosp=0
#ifdef CONFIG_CPU_JUMP_WORKAROUNDS
/*
* Clear BTB (branch target buffer), forbid RAS (return address
@@ -157,7 +175,15 @@
daddiu k1, %hi(kernelsp)
dsll k1, k1, 16
#endif
+ .if \tosp
+ move k0, sp
+ .if \docfi
+ .cfi_register sp, k0
+ .endif
+ LONG_L sp, %lo(kernelsp)(k1)
+ .else
LONG_L k1, %lo(kernelsp)(k1)
+ .endif
.endm
.macro set_saved_sp stackp temp temp2
@@ -165,7 +191,7 @@
.endm
#endif
- .macro SAVE_SOME
+ .macro SAVE_SOME docfi=0
.set push
.set noat
.set reorder
@@ -173,22 +199,52 @@
sll k0, 3 /* extract cu0 bit */
.set noreorder
bltz k0, 8f
- move k1, sp
+ move k0, sp
+ .if \docfi
+ .cfi_register sp, k0
+ .endif
+#ifdef CONFIG_EVA
+ /*
+ * Flush interAptiv's Return Prediction Stack (RPS) by writing
+ * EntryHi. Toggling Config7.RPS is slower and less portable.
+ *
+ * The RPS isn't automatically flushed when exceptions are
+ * taken, which can result in kernel mode speculative accesses
+ * to user addresses if the RPS mispredicts. That's harmless
+ * when user and kernel share the same address space, but with
+ * EVA the same user segments may be unmapped to kernel mode,
+ * even containing sensitive MMIO regions or invalid memory.
+ *
+ * This can happen when the kernel sets the return address to
+ * ret_from_* and jr's to the exception handler, which looks
+ * more like a tail call than a function call. If nested calls
+ * don't evict the last user address in the RPS, it will
+ * mispredict the return and fetch from a user controlled
+ * address into the icache.
+ *
+ * More recent EVA-capable cores with MAAR to restrict
+ * speculative accesses aren't affected.
+ */
+ MFC0 k0, CP0_ENTRYHI
+ MTC0 k0, CP0_ENTRYHI
+#endif
.set reorder
/* Called from user mode, new stack. */
- get_saved_sp
-#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
-8: move k0, sp
- PTR_SUBU sp, k1, PT_SIZE
-#else
- .set at=k0
-8: PTR_SUBU k1, PT_SIZE
+ get_saved_sp docfi=\docfi tosp=1
+8:
+#ifdef CONFIG_CPU_DADDI_WORKAROUNDS
+ .set at=k1
+#endif
+ PTR_SUBU sp, PT_SIZE
+#ifdef CONFIG_CPU_DADDI_WORKAROUNDS
.set noat
- move k0, sp
- move sp, k1
#endif
- LONG_S k0, PT_R29(sp)
- LONG_S $3, PT_R3(sp)
+ .if \docfi
+ .cfi_def_cfa sp,0
+ .endif
+ cfi_st k0, PT_R29, \docfi
+ cfi_rel_offset sp, PT_R29, \docfi
+ cfi_st v1, PT_R3, \docfi
/*
* You might think that you don't need to save $0,
* but the FPU emulator and gdb remote debug stub
@@ -196,107 +252,114 @@
*/
LONG_S $0, PT_R0(sp)
mfc0 v1, CP0_STATUS
- LONG_S $2, PT_R2(sp)
+ cfi_st v0, PT_R2, \docfi
LONG_S v1, PT_STATUS(sp)
-#ifdef CONFIG_MIPS_MT_SMTC
- /*
- * Ideally, these instructions would be shuffled in
- * to cover the pipeline delay.
- */
- .set mips32
- mfc0 k0, CP0_TCSTATUS
- .set mips0
- LONG_S k0, PT_TCSTATUS(sp)
-#endif /* CONFIG_MIPS_MT_SMTC */
- LONG_S $4, PT_R4(sp)
+ cfi_st $4, PT_R4, \docfi
mfc0 v1, CP0_CAUSE
- LONG_S $5, PT_R5(sp)
+ cfi_st $5, PT_R5, \docfi
LONG_S v1, PT_CAUSE(sp)
- LONG_S $6, PT_R6(sp)
- MFC0 v1, CP0_EPC
- LONG_S $7, PT_R7(sp)
+ cfi_st $6, PT_R6, \docfi
+ cfi_st ra, PT_R31, \docfi
+ MFC0 ra, CP0_EPC
+ cfi_st $7, PT_R7, \docfi
#ifdef CONFIG_64BIT
- LONG_S $8, PT_R8(sp)
- LONG_S $9, PT_R9(sp)
+ cfi_st $8, PT_R8, \docfi
+ cfi_st $9, PT_R9, \docfi
#endif
- LONG_S v1, PT_EPC(sp)
- LONG_S $25, PT_R25(sp)
- LONG_S $28, PT_R28(sp)
- LONG_S $31, PT_R31(sp)
+ LONG_S ra, PT_EPC(sp)
+ .if \docfi
+ .cfi_rel_offset ra, PT_EPC
+ .endif
+ cfi_st $25, PT_R25, \docfi
+ cfi_st $28, PT_R28, \docfi
+
+ /* Set thread_info if we're coming from user mode */
+ mfc0 k0, CP0_STATUS
+ sll k0, 3 /* extract cu0 bit */
+ bltz k0, 9f
+
ori $28, sp, _THREAD_MASK
xori $28, _THREAD_MASK
#ifdef CONFIG_CPU_CAVIUM_OCTEON
.set mips64
pref 0, 0($28) /* Prefetch the current pointer */
#endif
+9:
.set pop
.endm
- .macro SAVE_ALL
- SAVE_SOME
- SAVE_AT
- SAVE_TEMP
- SAVE_STATIC
+ .macro SAVE_ALL docfi=0
+ SAVE_SOME \docfi
+ SAVE_AT \docfi
+ SAVE_TEMP \docfi
+ SAVE_STATIC \docfi
.endm
- .macro RESTORE_AT
+ .macro RESTORE_AT docfi=0
.set push
.set noat
- LONG_L $1, PT_R1(sp)
+ cfi_ld $1, PT_R1, \docfi
.set pop
.endm
- .macro RESTORE_TEMP
+ .macro RESTORE_TEMP docfi=0
#ifdef CONFIG_CPU_CAVIUM_OCTEON
/* Restore the Octeon multiplier state */
jal octeon_mult_restore
#endif
#ifdef CONFIG_CPU_HAS_SMARTMIPS
- LONG_L $24, PT_ACX(sp)
- mtlhx $24
- LONG_L $24, PT_HI(sp)
- mtlhx $24
+ LONG_L $14, PT_ACX(sp)
LONG_L $24, PT_LO(sp)
- mtlhx $24
-#else
+ LONG_L $15, PT_HI(sp)
+#elif !defined(CONFIG_CPU_MIPSR6)
LONG_L $24, PT_LO(sp)
- mtlo $24
- LONG_L $24, PT_HI(sp)
- mthi $24
+ LONG_L $15, PT_HI(sp)
#endif
#ifdef CONFIG_32BIT
- LONG_L $8, PT_R8(sp)
- LONG_L $9, PT_R9(sp)
+ cfi_ld $8, PT_R8, \docfi
+ cfi_ld $9, PT_R9, \docfi
+#endif
+ cfi_ld $10, PT_R10, \docfi
+ cfi_ld $11, PT_R11, \docfi
+ cfi_ld $12, PT_R12, \docfi
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ mtlhx $14
+ mtlhx $15
+ mtlhx $24
+#elif !defined(CONFIG_CPU_MIPSR6)
+ mtlo $24
+ mthi $15
#endif
- LONG_L $10, PT_R10(sp)
- LONG_L $11, PT_R11(sp)
- LONG_L $12, PT_R12(sp)
- LONG_L $13, PT_R13(sp)
- LONG_L $14, PT_R14(sp)
- LONG_L $15, PT_R15(sp)
- LONG_L $24, PT_R24(sp)
+ cfi_ld $13, PT_R13, \docfi
+ cfi_ld $14, PT_R14, \docfi
+ cfi_ld $15, PT_R15, \docfi
+ cfi_ld $24, PT_R24, \docfi
+ .endm
+
+ .macro RESTORE_STATIC docfi=0
+ cfi_ld $16, PT_R16, \docfi
+ cfi_ld $17, PT_R17, \docfi
+ cfi_ld $18, PT_R18, \docfi
+ cfi_ld $19, PT_R19, \docfi
+ cfi_ld $20, PT_R20, \docfi
+ cfi_ld $21, PT_R21, \docfi
+ cfi_ld $22, PT_R22, \docfi
+ cfi_ld $23, PT_R23, \docfi
+ cfi_ld $30, PT_R30, \docfi
.endm
- .macro RESTORE_STATIC
- LONG_L $16, PT_R16(sp)
- LONG_L $17, PT_R17(sp)
- LONG_L $18, PT_R18(sp)
- LONG_L $19, PT_R19(sp)
- LONG_L $20, PT_R20(sp)
- LONG_L $21, PT_R21(sp)
- LONG_L $22, PT_R22(sp)
- LONG_L $23, PT_R23(sp)
- LONG_L $30, PT_R30(sp)
+ .macro RESTORE_SP docfi=0
+ cfi_ld sp, PT_R29, \docfi
.endm
-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+#if defined(CONFIG_CPU_R3000)
- .macro RESTORE_SOME
+ .macro RESTORE_SOME docfi=0
.set push
.set reorder
.set noat
mfc0 a0, CP0_STATUS
- li v1, 0xff00
+ li v1, ST0_CU1 | ST0_IM
ori a0, STATMASK
xori a0, STATMASK
mtc0 a0, CP0_STATUS
@@ -306,172 +369,82 @@
and v0, v1
or v0, a0
mtc0 v0, CP0_STATUS
- LONG_L $31, PT_R31(sp)
- LONG_L $28, PT_R28(sp)
- LONG_L $25, PT_R25(sp)
- LONG_L $7, PT_R7(sp)
- LONG_L $6, PT_R6(sp)
- LONG_L $5, PT_R5(sp)
- LONG_L $4, PT_R4(sp)
- LONG_L $3, PT_R3(sp)
- LONG_L $2, PT_R2(sp)
+ cfi_ld $31, PT_R31, \docfi
+ cfi_ld $28, PT_R28, \docfi
+ cfi_ld $25, PT_R25, \docfi
+ cfi_ld $7, PT_R7, \docfi
+ cfi_ld $6, PT_R6, \docfi
+ cfi_ld $5, PT_R5, \docfi
+ cfi_ld $4, PT_R4, \docfi
+ cfi_ld $3, PT_R3, \docfi
+ cfi_ld $2, PT_R2, \docfi
.set pop
.endm
- .macro RESTORE_SP_AND_RET
+ .macro RESTORE_SP_AND_RET docfi=0
.set push
.set noreorder
LONG_L k0, PT_EPC(sp)
- LONG_L sp, PT_R29(sp)
+ RESTORE_SP \docfi
jr k0
rfe
.set pop
.endm
#else
- .macro RESTORE_SOME
+ .macro RESTORE_SOME docfi=0
.set push
.set reorder
.set noat
-#ifdef CONFIG_MIPS_MT_SMTC
- .set mips32r2
- /*
- * We need to make sure the read-modify-write
- * of Status below isn't perturbed by an interrupt
- * or cross-TC access, so we need to do at least a DMT,
- * protected by an interrupt-inhibit. But setting IXMT
- * also creates a few-cycle window where an IPI could
- * be queued and not be detected before potentially
- * returning to a WAIT or user-mode loop. It must be
- * replayed.
- *
- * We're in the middle of a context switch, and
- * we can't dispatch it directly without trashing
- * some registers, so we'll try to detect this unlikely
- * case and program a software interrupt in the VPE,
- * as would be done for a cross-VPE IPI. To accommodate
- * the handling of that case, we're doing a DVPE instead
- * of just a DMT here to protect against other threads.
- * This is a lot of cruft to cover a tiny window.
- * If you can find a better design, implement it!
- *
- */
- mfc0 v0, CP0_TCSTATUS
- ori v0, TCSTATUS_IXMT
- mtc0 v0, CP0_TCSTATUS
- _ehb
- DVPE 5 # dvpe a1
- jal mips_ihb
-#endif /* CONFIG_MIPS_MT_SMTC */
mfc0 a0, CP0_STATUS
ori a0, STATMASK
xori a0, STATMASK
mtc0 a0, CP0_STATUS
- li v1, 0xff00
+ li v1, ST0_CU1 | ST0_FR | ST0_IM
and a0, v1
LONG_L v0, PT_STATUS(sp)
nor v1, $0, v1
and v0, v1
or v0, a0
mtc0 v0, CP0_STATUS
-#ifdef CONFIG_MIPS_MT_SMTC
-/*
- * Only after EXL/ERL have been restored to status can we
- * restore TCStatus.IXMT.
- */
- LONG_L v1, PT_TCSTATUS(sp)
- _ehb
- mfc0 a0, CP0_TCSTATUS
- andi v1, TCSTATUS_IXMT
- bnez v1, 0f
-
-/*
- * We'd like to detect any IPIs queued in the tiny window
- * above and request an software interrupt to service them
- * when we ERET.
- *
- * Computing the offset into the IPIQ array of the executing
- * TC's IPI queue in-line would be tedious. We use part of
- * the TCContext register to hold 16 bits of offset that we
- * can add in-line to find the queue head.
- */
- mfc0 v0, CP0_TCCONTEXT
- la a2, IPIQ
- srl v0, v0, 16
- addu a2, a2, v0
- LONG_L v0, 0(a2)
- beqz v0, 0f
-/*
- * If we have a queue, provoke dispatch within the VPE by setting C_SW1
- */
- mfc0 v0, CP0_CAUSE
- ori v0, v0, C_SW1
- mtc0 v0, CP0_CAUSE
-0:
- /*
- * This test should really never branch but
- * let's be prudent here. Having atomized
- * the shared register modifications, we can
- * now EVPE, and must do so before interrupts
- * are potentially re-enabled.
- */
- andi a1, a1, MVPCONTROL_EVP
- beqz a1, 1f
- evpe
-1:
- /* We know that TCStatua.IXMT should be set from above */
- xori a0, a0, TCSTATUS_IXMT
- or a0, a0, v1
- mtc0 a0, CP0_TCSTATUS
- _ehb
-
- .set mips0
-#endif /* CONFIG_MIPS_MT_SMTC */
LONG_L v1, PT_EPC(sp)
MTC0 v1, CP0_EPC
- LONG_L $31, PT_R31(sp)
- LONG_L $28, PT_R28(sp)
- LONG_L $25, PT_R25(sp)
+ cfi_ld $31, PT_R31, \docfi
+ cfi_ld $28, PT_R28, \docfi
+ cfi_ld $25, PT_R25, \docfi
#ifdef CONFIG_64BIT
- LONG_L $8, PT_R8(sp)
- LONG_L $9, PT_R9(sp)
+ cfi_ld $8, PT_R8, \docfi
+ cfi_ld $9, PT_R9, \docfi
#endif
- LONG_L $7, PT_R7(sp)
- LONG_L $6, PT_R6(sp)
- LONG_L $5, PT_R5(sp)
- LONG_L $4, PT_R4(sp)
- LONG_L $3, PT_R3(sp)
- LONG_L $2, PT_R2(sp)
+ cfi_ld $7, PT_R7, \docfi
+ cfi_ld $6, PT_R6, \docfi
+ cfi_ld $5, PT_R5, \docfi
+ cfi_ld $4, PT_R4, \docfi
+ cfi_ld $3, PT_R3, \docfi
+ cfi_ld $2, PT_R2, \docfi
.set pop
.endm
- .macro RESTORE_SP_AND_RET
- LONG_L sp, PT_R29(sp)
- .set mips3
+ .macro RESTORE_SP_AND_RET docfi=0
+ RESTORE_SP \docfi
+#if defined(CONFIG_CPU_MIPSR5) || defined(CONFIG_CPU_MIPSR6)
+ eretnc
+#else
+ .set push
+ .set arch=r4000
eret
- .set mips0
- .endm
-
+ .set pop
#endif
-
- .macro RESTORE_SP
- LONG_L sp, PT_R29(sp)
.endm
- .macro RESTORE_ALL
- RESTORE_TEMP
- RESTORE_STATIC
- RESTORE_AT
- RESTORE_SOME
- RESTORE_SP
- .endm
+#endif
- .macro RESTORE_ALL_AND_RET
- RESTORE_TEMP
- RESTORE_STATIC
- RESTORE_AT
- RESTORE_SOME
- RESTORE_SP_AND_RET
+ .macro RESTORE_ALL docfi=0
+ RESTORE_TEMP \docfi
+ RESTORE_STATIC \docfi
+ RESTORE_AT \docfi
+ RESTORE_SOME \docfi
+ RESTORE_SP \docfi
.endm
/*
@@ -479,33 +452,11 @@
* Set cp0 enable bit as sign that we're running on the kernel stack
*/
.macro CLI
-#if !defined(CONFIG_MIPS_MT_SMTC)
mfc0 t0, CP0_STATUS
- li t1, ST0_CU0 | STATMASK
+ li t1, ST0_KERNEL_CUMASK | STATMASK
or t0, t1
xori t0, STATMASK
mtc0 t0, CP0_STATUS
-#else /* CONFIG_MIPS_MT_SMTC */
- /*
- * For SMTC, we need to set privilege
- * and disable interrupts only for the
- * current TC, using the TCStatus register.
- */
- mfc0 t0, CP0_TCSTATUS
- /* Fortunately CU 0 is in the same place in both registers */
- /* Set TCU0, TMX, TKSU (for later inversion) and IXMT */
- li t1, ST0_CU0 | 0x08001c00
- or t0, t1
- /* Clear TKSU, leave IXMT */
- xori t0, 0x00001800
- mtc0 t0, CP0_TCSTATUS
- _ehb
- /* We need to leave the global IE bit set, but clear EXL...*/
- mfc0 t0, CP0_STATUS
- ori t0, ST0_EXL | ST0_ERL
- xori t0, ST0_EXL | ST0_ERL
- mtc0 t0, CP0_STATUS
-#endif /* CONFIG_MIPS_MT_SMTC */
irq_disable_hazard
.endm
@@ -514,35 +465,11 @@
* Set cp0 enable bit as sign that we're running on the kernel stack
*/
.macro STI
-#if !defined(CONFIG_MIPS_MT_SMTC)
mfc0 t0, CP0_STATUS
- li t1, ST0_CU0 | STATMASK
+ li t1, ST0_KERNEL_CUMASK | STATMASK
or t0, t1
xori t0, STATMASK & ~1
mtc0 t0, CP0_STATUS
-#else /* CONFIG_MIPS_MT_SMTC */
- /*
- * For SMTC, we need to set privilege
- * and enable interrupts only for the
- * current TC, using the TCStatus register.
- */
- _ehb
- mfc0 t0, CP0_TCSTATUS
- /* Fortunately CU 0 is in the same place in both registers */
- /* Set TCU0, TKSU (for later inversion) and IXMT */
- li t1, ST0_CU0 | 0x08001c00
- or t0, t1
- /* Clear TKSU *and* IXMT */
- xori t0, 0x00001c00
- mtc0 t0, CP0_TCSTATUS
- _ehb
- /* We need to leave the global IE bit set, but clear EXL...*/
- mfc0 t0, CP0_STATUS
- ori t0, ST0_EXL
- xori t0, ST0_EXL
- mtc0 t0, CP0_STATUS
- /* irq_enable_hazard below should expand to EHB for 24K/34K cpus */
-#endif /* CONFIG_MIPS_MT_SMTC */
irq_enable_hazard
.endm
@@ -552,35 +479,9 @@
* Set cp0 enable bit as sign that we're running on the kernel stack
*/
.macro KMODE
-#ifdef CONFIG_MIPS_MT_SMTC
- /*
- * This gets baroque in SMTC. We want to
- * protect the non-atomic clearing of EXL
- * with DMT/EMT, but we don't want to take
- * an interrupt while DMT is still in effect.
- */
-
- /* KMODE gets invoked from both reorder and noreorder code */
- .set push
- .set mips32r2
- .set noreorder
- mfc0 v0, CP0_TCSTATUS
- andi v1, v0, TCSTATUS_IXMT
- ori v0, TCSTATUS_IXMT
- mtc0 v0, CP0_TCSTATUS
- _ehb
- DMT 2 # dmt v0
- /*
- * We don't know a priori if ra is "live"
- */
- move t0, ra
- jal mips_ihb
- nop /* delay slot */
- move ra, t0
-#endif /* CONFIG_MIPS_MT_SMTC */
mfc0 t0, CP0_STATUS
- li t1, ST0_CU0 | (STATMASK & ~1)
-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+ li t1, ST0_KERNEL_CUMASK | (STATMASK & ~1)
+#if defined(CONFIG_CPU_R3000)
andi t2, t0, ST0_IEP
srl t2, 2
or t0, t2
@@ -588,25 +489,6 @@
or t0, t1
xori t0, STATMASK & ~1
mtc0 t0, CP0_STATUS
-#ifdef CONFIG_MIPS_MT_SMTC
- _ehb
- andi v0, v0, VPECONTROL_TE
- beqz v0, 2f
- nop /* delay slot */
- emt
-2:
- mfc0 v0, CP0_TCSTATUS
- /* Clear IXMT, then OR in previous value */
- ori v0, TCSTATUS_IXMT
- xori v0, TCSTATUS_IXMT
- or v0, v1, v0
- mtc0 v0, CP0_TCSTATUS
- /*
- * irq_disable_hazard below should expand to EHB
- * on 24K/34K CPUS
- */
- .set pop
-#endif /* CONFIG_MIPS_MT_SMTC */
irq_disable_hazard
.endm