summaryrefslogtreecommitdiffstats
path: root/sys/mips/mips/swtch.S
diff options
context:
space:
mode:
authorjmallett <jmallett@FreeBSD.org>2010-04-19 07:34:26 +0000
committerjmallett <jmallett@FreeBSD.org>2010-04-19 07:34:26 +0000
commitf845b731f76911442e1141a3f8600349cf284bf7 (patch)
treecc0ccc5043eddb8e8bdf674dbbca1cc37b1e9e0d /sys/mips/mips/swtch.S
parent7e6abd8eb5abd6eed5d9c485f162aadee832c004 (diff)
downloadFreeBSD-src-f845b731f76911442e1141a3f8600349cf284bf7.zip
FreeBSD-src-f845b731f76911442e1141a3f8600349cf284bf7.tar.gz
o) Eliminate the "stand" frame and its use. Use CALLFRAME_* everywhere.
o) Use <machine/asm.h> macros for register-width, etc., rather than doing it by hand in a few more assembly files. o) Reduce diffs between various bits of TLB refill code in exception.S and between interrupt processing code. o) Use PTR_* to operate on registers that are pointers (e.g. sp). o) Add and use a macro, CLEAR_PTE_SWBITS rather than using the mysteriously-named WIRED_SHIFT to select bits to truncate when loading PTEs. o) Don't doubly disable interrupts by moving zero to the status register, especially since that has the nasty side-effect of taking us out of 64-bit mode. o) Use CLEAR_STATUS to disable interrupts the first time. o) Keep SR_PX set as well as SR_[KSU]X when doing exception processing. This is the bit that determines whether 64-bit operations are allowed. o) Don't enable interrupts until configure_final(), like most other ports.
Diffstat (limited to 'sys/mips/mips/swtch.S')
-rw-r--r--sys/mips/mips/swtch.S131
1 files changed, 41 insertions, 90 deletions
diff --git a/sys/mips/mips/swtch.S b/sys/mips/mips/swtch.S
index 2919d21..f287476 100644
--- a/sys/mips/mips/swtch.S
+++ b/sys/mips/mips/swtch.S
@@ -65,53 +65,7 @@
#include "assym.s"
-#if defined(ISA_MIPS32)
-#undef WITH_64BIT_CP0
-#elif defined(ISA_MIPS64)
-#define WITH_64BIT_CP0
-#elif defined(ISA_MIPS3)
-#define WITH_64BIT_CP0
-#else
-#error "Please write the code for this ISA"
-#endif
-
-#ifdef WITH_64BIT_CP0
-#define _SLL dsll
-#define _SRL dsrl
-#define _MFC0 dmfc0
-#define _MTC0 dmtc0
-#define WIRED_SHIFT 34
-#else
-#define _SLL sll
-#define _SRL srl
-#define _MFC0 mfc0
-#define _MTC0 mtc0
-#define WIRED_SHIFT 2
-#endif
.set noreorder # Noreorder is default style!
-#if defined(ISA_MIPS32)
- .set mips32
-#elif defined(ISA_MIPS64)
- .set mips64
-#elif defined(ISA_MIPS3)
- .set mips3
-#endif
-
-#if defined(ISA_MIPS32)
-#define STORE sw /* 32 bit mode regsave instruction */
-#define LOAD lw /* 32 bit mode regload instruction */
-#define RSIZE 4 /* 32 bit mode register size */
-#define STORE_FP swc1 /* 32 bit mode fp regsave instruction */
-#define LOAD_FP lwc1 /* 32 bit mode fp regload instruction */
-#define FP_RSIZE 4 /* 32 bit mode fp register size */
-#else
-#define STORE sd /* 64 bit mode regsave instruction */
-#define LOAD ld /* 64 bit mode regload instruction */
-#define RSIZE 8 /* 64 bit mode register size */
-#define STORE_FP sdc1 /* 64 bit mode fp regsave instruction */
-#define LOAD_FP ldc1 /* 64 bit mode fp regload instruction */
-#define FP_RSIZE 8 /* 64 bit mode fp register size */
-#endif
/*
* FREEBSD_DEVELOPERS_FIXME
@@ -125,28 +79,28 @@
#endif
#define SAVE_U_PCB_REG(reg, offs, base) \
- STORE reg, U_PCB_REGS + (RSIZE * offs) (base)
+ REG_S reg, U_PCB_REGS + (SZREG * offs) (base)
#define RESTORE_U_PCB_REG(reg, offs, base) \
- LOAD reg, U_PCB_REGS + (RSIZE * offs) (base)
+ REG_L reg, U_PCB_REGS + (SZREG * offs) (base)
#define SAVE_U_PCB_FPREG(reg, offs, base) \
- STORE_FP reg, U_PCB_FPREGS + (FP_RSIZE * offs) (base)
+ FP_S reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
#define RESTORE_U_PCB_FPREG(reg, offs, base) \
- LOAD_FP reg, U_PCB_FPREGS + (FP_RSIZE * offs) (base)
+ FP_L reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
#define SAVE_U_PCB_FPSR(reg, offs, base) \
- STORE reg, U_PCB_FPREGS + (FP_RSIZE * offs) (base)
+ REG_S reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
#define RESTORE_U_PCB_FPSR(reg, offs, base) \
- LOAD reg, U_PCB_FPREGS + (FP_RSIZE * offs) (base)
+ REG_L reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
#define SAVE_U_PCB_CONTEXT(reg, offs, base) \
- STORE reg, U_PCB_CONTEXT + (RSIZE * offs) (base)
+ REG_S reg, U_PCB_CONTEXT + (SZREG * offs) (base)
#define RESTORE_U_PCB_CONTEXT(reg, offs, base) \
- LOAD reg, U_PCB_CONTEXT + (RSIZE * offs) (base)
+ REG_L reg, U_PCB_CONTEXT + (SZREG * offs) (base)
#define ITLBNOPFIX nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
@@ -172,7 +126,7 @@ LEAF(fork_trampoline)
*/
.set noat
GET_CPU_PCPU(k1)
- lw k1, PC_CURPCB(k1)
+ PTR_L k1, PC_CURPCB(k1)
RESTORE_U_PCB_REG(t0, MULLO, k1)
RESTORE_U_PCB_REG(t1, MULHI, k1)
@@ -181,7 +135,7 @@ LEAF(fork_trampoline)
RESTORE_U_PCB_REG(a0, PC, k1)
RESTORE_U_PCB_REG(AT, AST, k1)
RESTORE_U_PCB_REG(v0, V0, k1)
- _MTC0 a0, COP_0_EXC_PC # set return address
+ MTC0 a0, COP_0_EXC_PC # set return address
RESTORE_U_PCB_REG(v1, V1, k1)
RESTORE_U_PCB_REG(a0, A0, k1)
@@ -265,7 +219,7 @@ END(savectx)
KSEG0TEXT_START;
-NON_LEAF(mips_cpu_throw, STAND_FRAME_SIZE, ra)
+NON_LEAF(mips_cpu_throw, CALLFRAME_SIZ, ra)
mfc0 t0, COP_0_STATUS_REG # t0 = saved status register
nop
nop
@@ -285,7 +239,7 @@ END(mips_cpu_throw)
* a2 - mtx
* Find the highest priority process and resume it.
*/
-NON_LEAF(cpu_switch, STAND_FRAME_SIZE, ra)
+NON_LEAF(cpu_switch, CALLFRAME_SIZ, ra)
mfc0 t0, COP_0_STATUS_REG # t0 = saved status register
nop
nop
@@ -294,11 +248,11 @@ NON_LEAF(cpu_switch, STAND_FRAME_SIZE, ra)
ITLBNOPFIX
beqz a0, mips_sw1
move a3, a0
- lw a0, TD_PCB(a0) # load PCB addr of curproc
+ PTR_L a0, TD_PCB(a0) # load PCB addr of curproc
SAVE_U_PCB_CONTEXT(sp, PREG_SP, a0) # save old sp
- subu sp, sp, STAND_FRAME_SIZE
- sw ra, STAND_RA_OFFSET(sp)
- .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE)
+ PTR_SUBU sp, sp, CALLFRAME_SIZ
+ REG_S ra, CALLFRAME_RA(sp)
+ .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
SAVE_U_PCB_CONTEXT(s0, PREG_S0, a0) # do a 'savectx()'
SAVE_U_PCB_CONTEXT(s1, PREG_S1, a0)
SAVE_U_PCB_CONTEXT(s2, PREG_S2, a0)
@@ -321,13 +275,13 @@ getpc:
* to be saved with the other registers do so here.
*/
- sw a2, TD_LOCK(a3) # Switchout td_lock
+ PTR_S a2, TD_LOCK(a3) # Switchout td_lock
mips_sw1:
#if defined(SMP) && defined(SCHED_ULE)
PTR_LA t0, _C_LABEL(blocked_lock)
blocked_loop:
- lw t1, TD_LOCK(a1)
+ PTR_L t1, TD_LOCK(a1)
beq t0, t1, blocked_loop
nop
#endif
@@ -336,20 +290,16 @@ blocked_loop:
* Switch to new context.
*/
GET_CPU_PCPU(a3)
- sw a1, PC_CURTHREAD(a3)
- lw a2, TD_PCB(a1)
- sw a2, PC_CURPCB(a3)
- lw v0, TD_KSTACK(a1)
- li s0, MIPS_KSEG2_START # If Uarea addr is below kseg2,
+ PTR_S a1, PC_CURTHREAD(a3)
+ PTR_L a2, TD_PCB(a1)
+ PTR_S a2, PC_CURPCB(a3)
+ PTR_L v0, TD_KSTACK(a1)
+#if !defined(__mips_n64)
+ PTR_LI s0, MIPS_KSEG2_START # If Uarea addr is below kseg2,
bltu v0, s0, sw2 # no need to insert in TLB.
- lw a1, TD_UPTE+0(s7) # t0 = first u. pte
- lw a2, TD_UPTE+4(s7) # t1 = 2nd u. pte
- and s0, v0, PTE_ODDPG
- beq s0, zero, entry0
- nop
-
- PANIC_KSEG0("USPACE sat on odd page boundary", t1)
-
+#endif
+ lw a1, TD_UPTE + 0(s7) # a1 = u. pte #0
+ lw a2, TD_UPTE + 4(s7) # a2 = u. pte #1
/*
* Wiredown the USPACE of newproc in TLB entry#0. Check whether target
* USPACE is already in another place of TLB before that, and if so
@@ -357,31 +307,32 @@ blocked_loop:
* NOTE: This is hard coded to UPAGES == 2.
* Also, there should be no TLB faults at this point.
*/
-entry0:
- mtc0 v0, COP_0_TLB_HI # VPN = va
+ MTC0 v0, COP_0_TLB_HI # VPN = va
HAZARD_DELAY
tlbp # probe VPN
HAZARD_DELAY
mfc0 s0, COP_0_TLB_INDEX
- nop
-pgm:
+ HAZARD_DELAY
+
+ PTR_LI t1, MIPS_KSEG0_START # invalidate tlb entry
bltz s0, entry0set
- li t1, MIPS_KSEG0_START # invalidate tlb entry
+ nop
sll s0, PAGE_SHIFT + 1
addu t1, s0
- mtc0 t1, COP_0_TLB_HI
+ MTC0 t1, COP_0_TLB_HI
mtc0 zero, COP_0_TLB_LO0
mtc0 zero, COP_0_TLB_LO1
HAZARD_DELAY
tlbwi
HAZARD_DELAY
- mtc0 v0, COP_0_TLB_HI # set VPN again
+ MTC0 v0, COP_0_TLB_HI # set VPN again
+
entry0set:
/* SMP!! - Works only for unshared TLB case - i.e. no v-cpus */
mtc0 zero, COP_0_TLB_INDEX # TLB entry #0
-# or a1, PG_G
+ HAZARD_DELAY
mtc0 a1, COP_0_TLB_LO0 # upte[0]
-# or a2, PG_G
+ HAZARD_DELAY
mtc0 a2, COP_0_TLB_LO1 # upte[1]
HAZARD_DELAY
tlbwi # set TLB entry #0
@@ -396,7 +347,7 @@ sw2:
/*
* Restore registers and return.
*/
- lw a0, TD_PCB(s7)
+ PTR_L a0, TD_PCB(s7)
RESTORE_U_PCB_CONTEXT(gp, PREG_GP, a0)
RESTORE_U_PCB_CONTEXT(v0, PREG_SR, a0) # restore kernel context
RESTORE_U_PCB_CONTEXT(ra, PREG_RA, a0)
@@ -457,7 +408,7 @@ LEAF(MipsSwitchFPState)
* First read out the status register to make sure that all FP operations
* have completed.
*/
- lw a0, TD_PCB(a0) # get pointer to pcb for proc
+ PTR_L a0, TD_PCB(a0) # get pointer to pcb for proc
cfc1 t0, FPC_CSR # stall til FP done
cfc1 t0, FPC_CSR # now get status
li t3, ~SR_COP_1_BIT
@@ -567,13 +518,13 @@ END(MipsSwitchFPState)
*----------------------------------------------------------------------------
*/
LEAF(MipsSaveCurFPState)
- lw a0, TD_PCB(a0) # get pointer to pcb for thread
+ PTR_L a0, TD_PCB(a0) # get pointer to pcb for thread
mfc0 t1, COP_0_STATUS_REG # Disable interrupts and
li t0, SR_COP_1_BIT # enable the coprocessor
mtc0 t0, COP_0_STATUS_REG
ITLBNOPFIX
GET_CPU_PCPU(a1)
- sw zero, PC_FPCURTHREAD(a1) # indicate state has been saved
+ PTR_S zero, PC_FPCURTHREAD(a1) # indicate state has been saved
/*
* First read out the status register to make sure that all FP operations
* have completed.
OpenPOWER on IntegriCloud