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.
This commit is contained in:
Juli Mallett 2010-04-19 07:34:26 +00:00
parent 5f3173b517
commit 745bba1ab0
7 changed files with 236 additions and 348 deletions

View File

@ -42,10 +42,6 @@
#ifndef _MACHINE_REGNUM_H_
#define _MACHINE_REGNUM_H_
#define STAND_ARG_SIZE 16
#define STAND_FRAME_SIZE 24
#define STAND_RA_OFFSET 20
/* This must match the numbers
* in pcb.h and is used by
* swtch.S

View File

@ -102,6 +102,7 @@ static void
configure_final(dummy)
void *dummy;
{
intr_enable();
cninit_finish();

View File

@ -66,37 +66,14 @@
#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
/*
* Clear the software-managed bits in a PTE in register pr.
*/
#define CLEAR_PTE_SWBITS(pr) \
sll pr, 2 ; \
srl pr, 2 # keep bottom 30 bits
#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
/*
* Reasonable limit
@ -125,12 +102,12 @@
*
*
*/
.set noat
VECTOR(MipsTLBMiss, unknown)
j _C_LABEL(MipsDoTLBMiss)
mfc0 k0, COP_0_BAD_VADDR # get the fault address
nop
.set push
.set noat
j MipsDoTLBMiss
MFC0 k0, COP_0_BAD_VADDR # get the fault address
.set pop
VECTOR_END(MipsTLBMiss)
/*
@ -145,42 +122,40 @@ VECTOR_END(MipsTLBMiss)
* let the processor trap to load the correct value after service.
*----------------------------------------------------------------------------
*/
.set push
.set noat
MipsDoTLBMiss:
#k0 already has BadVA
bltz k0, 1f #02: k0<0 -> 1f (kernel fault)
srl k0, k0, SEGSHIFT - 2 #03: k0=seg offset (almost)
bltz k0, 1f #02: k0<0 -> 1f (kernel fault)
PTR_SRL k0, k0, SEGSHIFT - 2 #03: k0=seg offset (almost)
GET_CPU_PCPU(k1)
lw k1, PC_SEGBASE(k1)
beqz k1, 2f #05: make sure segbase is not null
andi k0, k0, 0x7fc #06: k0=seg offset (mask 0x3)
#xxx mips64 unsafe?
addu k1, k0, k1 #07: k1=seg entry address
lw k1, 0(k1) #08: k1=seg entry
mfc0 k0, COP_0_BAD_VADDR #09: k0=bad address (again)
beq k1, zero, 2f #0a: ==0 -- no page table
srl k0, PAGE_SHIFT - 2 #0b: k0=VPN (aka va>>10)
PTR_L k1, PC_SEGBASE(k1)
beqz k1, 2f #05: make sure segbase is not null
andi k0, k0, 0xffc #06: k0=seg offset (mask 0x3)
PTR_ADDU k1, k0, k1 #07: k1=seg entry address
andi k0, k0, ((NPTEPG/2) - 1) << 3 #0c: k0=page tab offset
#xxx mips64 unsafe?
addu k1, k1, k0 #0d: k1=pte address
lw k0, 0(k1) #0e: k0=lo0 pte
lw k1, 4(k1) #0f: k1=lo1 pte
_SLL k0, k0, WIRED_SHIFT #10: keep bottom 30 bits
_SRL k0, k0, WIRED_SHIFT #11: keep bottom 30 bits
_MTC0 k0, COP_0_TLB_LO0 #12: lo0 is loaded
_SLL k1, k1, WIRED_SHIFT #13: keep bottom 30 bits
_SRL k1, k1, WIRED_SHIFT #14: keep bottom 30 bits
_MTC0 k1, COP_0_TLB_LO1 #15: lo1 is loaded
PTR_L k1, 0(k1) #08: k1=seg entry
MFC0 k0, COP_0_BAD_VADDR #09: k0=bad address (again)
beq k1, zero, 2f #0a: ==0 -- no page table
srl k0, PAGE_SHIFT - 2 #0b: k0=VPN (aka va>>10)
andi k0, k0, 0xff8 #0c: k0=page tab offset
PTR_ADDU k1, k1, k0 #0d: k1=pte address
lw k0, 0(k1) #0e: k0=lo0 pte
lw k1, 4(k1) #0f: k1=lo0 pte
CLEAR_PTE_SWBITS(k0)
MTC0 k0, COP_0_TLB_LO0 #12: lo0 is loaded
COP0_SYNC
CLEAR_PTE_SWBITS(k1)
MTC0 k1, COP_0_TLB_LO1 #15: lo1 is loaded
COP0_SYNC
tlbwr #1a: write to tlb
HAZARD_DELAY
tlbwr #1a: write to tlb
HAZARD_DELAY
eret #1f: retUrn from exception
1: j _C_LABEL(MipsTLBMissException) #20: kernel exception
nop #21: branch delay slot
2: j SlowFault #22: no page table present
nop #23: branch delay slot
.set at
eret #1f: retUrn from exception
1: j MipsTLBMissException #20: kernel exception
nop #21: branch delay slot
2: j SlowFault #22: no page table present
nop #23: branch delay slot
.set pop
/*
* This code is copied to the general exception vector address to
@ -207,7 +182,7 @@ VECTOR(MipsException, unknown)
# the cause is already
# shifted left by 2 bits so
# we dont have to shift.
lw k0, 0(k0) # Get the function address
PTR_L k0, 0(k0) # Get the function address
nop
j k0 # Jump to the function.
nop
@ -244,20 +219,9 @@ SlowFault:
*
*----------------------------------------------------------------------------
*/
#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 */
#elif defined(ISA_MIPS64)
#define STORE sd /* 64 bit mode regsave instruction */
#define LOAD ld /* 64 bit mode regload instruction */
#define RSIZE 8 /* 64 bit mode register size */
#else
#error "Please write code for this isa."
#endif
#define SAVE_REG(reg, offs, base) \
STORE reg, STAND_ARG_SIZE + (RSIZE * offs) (base)
REG_S reg, CALLFRAME_SIZ + (SZREG * offs) (base)
#ifdef TARGET_OCTEON
#define CLEAR_STATUS \
@ -274,7 +238,7 @@ SlowFault:
and a0, a0, a2 ; \
mtc0 a0, COP_0_STATUS_REG
#endif
/*
* Save CPU and CP0 register state.
*
@ -317,8 +281,8 @@ SlowFault:
mfhi v1 ;\
mfc0 a0, COP_0_STATUS_REG ;\
mfc0 a1, COP_0_CAUSE_REG ;\
mfc0 a2, COP_0_BAD_VADDR ;\
mfc0 a3, COP_0_EXC_PC ;\
MFC0 a2, COP_0_BAD_VADDR ;\
MFC0 a3, COP_0_EXC_PC ;\
SAVE_REG(v0, MULLO, sp) ;\
SAVE_REG(v1, MULHI, sp) ;\
SAVE_REG(a0, SR, sp) ;\
@ -332,20 +296,20 @@ SlowFault:
PTR_ADDU v0, sp, KERN_EXC_FRAME_SIZE ;\
SAVE_REG(v0, SP, sp) ;\
CLEAR_STATUS ;\
PTR_ADDU a0, sp, STAND_ARG_SIZE ;\
PTR_ADDU a0, sp, CALLFRAME_SIZ ;\
ITLBNOPFIX
#define RESTORE_REG(reg, offs, base) \
LOAD reg, STAND_ARG_SIZE + (RSIZE * offs) (base)
REG_L reg, CALLFRAME_SIZ + (SZREG * offs) (base)
#define RESTORE_CPU \
mtc0 zero,COP_0_STATUS_REG ;\
CLEAR_STATUS ;\
RESTORE_REG(k0, SR, sp) ;\
RESTORE_REG(t0, MULLO, sp) ;\
RESTORE_REG(t1, MULHI, sp) ;\
mtlo t0 ;\
mthi t1 ;\
_MTC0 v0, COP_0_EXC_PC ;\
MTC0 v0, COP_0_EXC_PC ;\
.set noat ;\
RESTORE_REG(AT, AST, sp) ;\
RESTORE_REG(v0, V0, sp) ;\
@ -384,13 +348,13 @@ SlowFault:
* the status register and the multiply lo and high registers.
* In addition, we set this up for linkage conventions.
*/
#define KERN_REG_SIZE (NUMSAVEREGS * RSIZE)
#define KERN_EXC_FRAME_SIZE (STAND_FRAME_SIZE + KERN_REG_SIZE + 16)
#define KERN_REG_SIZE (NUMSAVEREGS * SZREG)
#define KERN_EXC_FRAME_SIZE (CALLFRAME_SIZ + KERN_REG_SIZE + 16)
NNON_LEAF(MipsKernGenException, KERN_EXC_FRAME_SIZE, ra)
.set noat
subu sp, sp, KERN_EXC_FRAME_SIZE
.mask 0x80000000, (STAND_RA_OFFSET - KERN_EXC_FRAME_SIZE)
PTR_SUBU sp, sp, KERN_EXC_FRAME_SIZE
.mask 0x80000000, (CALLFRAME_RA - KERN_EXC_FRAME_SIZE)
/*
* Save CPU state, building 'frame'.
*/
@ -401,7 +365,7 @@ NNON_LEAF(MipsKernGenException, KERN_EXC_FRAME_SIZE, ra)
PTR_LA gp, _C_LABEL(_gp)
PTR_LA k0, _C_LABEL(trap)
jalr k0
sw a3, STAND_RA_OFFSET + KERN_REG_SIZE(sp) # for debugging
REG_S a3, CALLFRAME_RA + KERN_REG_SIZE(sp) # for debugging
/*
* Update interrupt mask in saved status register
@ -410,7 +374,6 @@ NNON_LEAF(MipsKernGenException, KERN_EXC_FRAME_SIZE, ra)
* in trap handler
*/
mfc0 a0, COP_0_STATUS_REG
mtc0 zero, COP_0_STATUS_REG
and a0, a0, SR_INT_MASK
RESTORE_REG(a1, SR, sp)
and a1, a1, ~SR_INT_MASK
@ -424,10 +387,10 @@ END(MipsKernGenException)
#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)
/*----------------------------------------------------------------------------
*
@ -443,14 +406,14 @@ END(MipsKernGenException)
*
*----------------------------------------------------------------------------
*/
NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra)
NNON_LEAF(MipsUserGenException, CALLFRAME_SIZ, ra)
.set noat
.mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE)
.mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
/*
* Save all of the registers except for the kernel temporaries in u.u_pcb.
*/
GET_CPU_PCPU(k1)
lw k1, PC_CURPCB(k1)
PTR_L k1, PC_CURPCB(k1)
SAVE_U_PCB_REG(AT, AST, k1)
.set at
SAVE_U_PCB_REG(v0, V0, k1)
@ -476,17 +439,17 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra)
SAVE_U_PCB_REG(s2, S2, k1)
SAVE_U_PCB_REG(s3, S3, k1)
SAVE_U_PCB_REG(s4, S4, k1)
mfc0 a2, COP_0_BAD_VADDR # Third arg is the fault addr
MFC0 a2, COP_0_BAD_VADDR # Third arg is the fault addr
SAVE_U_PCB_REG(s5, S5, k1)
SAVE_U_PCB_REG(s6, S6, k1)
SAVE_U_PCB_REG(s7, S7, k1)
SAVE_U_PCB_REG(t8, T8, k1)
mfc0 a3, COP_0_EXC_PC # Fourth arg is the pc.
MFC0 a3, COP_0_EXC_PC # Fourth arg is the pc.
SAVE_U_PCB_REG(t9, T9, k1)
SAVE_U_PCB_REG(gp, GP, k1)
SAVE_U_PCB_REG(sp, SP, k1)
SAVE_U_PCB_REG(s8, S8, k1)
subu sp, k1, STAND_FRAME_SIZE # switch to kernel SP
PTR_SUBU sp, k1, CALLFRAME_SIZ # switch to kernel SP
SAVE_U_PCB_REG(ra, RA, k1)
SAVE_U_PCB_REG(v0, MULLO, k1)
SAVE_U_PCB_REG(v1, MULHI, k1)
@ -494,12 +457,12 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra)
SAVE_U_PCB_REG(a1, CAUSE, k1)
SAVE_U_PCB_REG(a2, BADVADDR, k1)
SAVE_U_PCB_REG(a3, PC, k1)
sw a3, STAND_RA_OFFSET(sp) # for debugging
REG_S a3, CALLFRAME_RA(sp) # for debugging
PTR_LA gp, _C_LABEL(_gp) # switch to kernel GP
# Turn off fpu and enter kernel mode
and t0, a0, ~(SR_COP_1_BIT | SR_EXL | SR_KSU_MASK | SR_INT_ENAB)
#ifdef TARGET_OCTEON
or t0, t0, (MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX)
or t0, t0, (MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX | MIPS32_SR_PX)
#endif
mtc0 t0, COP_0_STATUS_REG
PTR_ADDU a0, k1, U_PCB_REGS
@ -518,10 +481,7 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra)
*/
DO_AST
mfc0 t0, COP_0_STATUS_REG # disable int
and t0, t0, ~(MIPS_SR_INT_IE)
mtc0 t0, COP_0_STATUS_REG
ITLBNOPFIX
CLEAR_STATUS
/*
* The use of k1 for storing the PCB pointer must be done only
@ -529,7 +489,7 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra)
* by the interrupt code.
*/
GET_CPU_PCPU(k1)
lw k1, PC_CURPCB(k1)
PTR_L k1, PC_CURPCB(k1)
/*
* Update interrupt mask in saved status register
@ -549,7 +509,7 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra)
mthi t1
RESTORE_U_PCB_REG(a0, PC, 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)
RESTORE_U_PCB_REG(a1, A1, k1)
@ -578,9 +538,6 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra)
RESTORE_U_PCB_REG(k0, SR, k1)
RESTORE_U_PCB_REG(s8, S8, k1)
RESTORE_U_PCB_REG(ra, RA, k1)
#ifdef TARGET_OCTEON
and k0, k0, ~(MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX)
#endif
.set noat
RESTORE_U_PCB_REG(AT, AST, k1)
@ -610,27 +567,25 @@ END(MipsUserGenException)
NNON_LEAF(MipsKernIntr, KERN_EXC_FRAME_SIZE, ra)
.set noat
subu sp, sp, KERN_EXC_FRAME_SIZE
.mask 0x80000000, (STAND_RA_OFFSET - KERN_EXC_FRAME_SIZE)
PTR_SUBU sp, sp, KERN_EXC_FRAME_SIZE
.mask 0x80000000, (CALLFRAME_RA - KERN_EXC_FRAME_SIZE)
/*
* Save the relevant kernel registers onto the stack.
* Save CPU state, building 'frame'.
*/
SAVE_CPU
/*
* Call the interrupt handler.
* Call the interrupt handler. a0 points at the saved frame.
*/
PTR_LA gp, _C_LABEL(_gp)
PTR_ADDU a0, sp, STAND_ARG_SIZE
PTR_LA k0, _C_LABEL(cpu_intr)
jalr k0
sw a3, STAND_RA_OFFSET + KERN_REG_SIZE(sp)
/* Why no AST processing here? */
REG_S a3, CALLFRAME_RA + KERN_REG_SIZE(sp) # for debugging
/*
* Update interrupt mask in saved status register
* Some of interrupts could be disabled by
* intr filters
* intr filters if interrupts are enabled later
* in trap handler
*/
mfc0 a0, COP_0_STATUS_REG
and a0, a0, SR_INT_MASK
@ -638,12 +593,8 @@ NNON_LEAF(MipsKernIntr, KERN_EXC_FRAME_SIZE, ra)
and a1, a1, ~SR_INT_MASK
or a1, a1, a0
SAVE_REG(a1, SR, sp)
/*
* Restore registers and return from the interrupt.
*/
lw v0, STAND_RA_OFFSET + KERN_REG_SIZE(sp)
RESTORE_CPU
REG_L v0, CALLFRAME_RA + KERN_REG_SIZE(sp)
RESTORE_CPU # v0 contains the return address.
sync
eret
.set at
@ -668,15 +619,15 @@ END(MipsKernIntr)
*
*----------------------------------------------------------------------------
*/
NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra)
NNON_LEAF(MipsUserIntr, CALLFRAME_SIZ, ra)
.set noat
.mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE)
.mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
/*
* Save the relevant user registers into the u.u_pcb struct.
* We don't need to save s0 - s8 because the compiler does it for us.
*/
GET_CPU_PCPU(k1)
lw k1, PC_CURPCB(k1)
PTR_L k1, PC_CURPCB(k1)
SAVE_U_PCB_REG(AT, AST, k1)
.set at
SAVE_U_PCB_REG(v0, V0, k1)
@ -715,19 +666,19 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra)
mfhi v1
mfc0 a0, COP_0_STATUS_REG
mfc0 a1, COP_0_CAUSE_REG
mfc0 a3, COP_0_EXC_PC
MFC0 a3, COP_0_EXC_PC
SAVE_U_PCB_REG(v0, MULLO, k1)
SAVE_U_PCB_REG(v1, MULHI, k1)
SAVE_U_PCB_REG(a0, SR, k1)
SAVE_U_PCB_REG(a1, CAUSE, k1)
SAVE_U_PCB_REG(a3, PC, k1) # PC in a3, note used later!
subu sp, k1, STAND_FRAME_SIZE # switch to kernel SP
PTR_SUBU sp, k1, CALLFRAME_SIZ # switch to kernel SP
PTR_LA gp, _C_LABEL(_gp) # switch to kernel GP
# Turn off fpu, disable interrupts, set kernel mode kernel mode, clear exception level.
and t0, a0, ~(SR_COP_1_BIT | SR_EXL | SR_INT_ENAB | SR_KSU_MASK)
#ifdef TARGET_OCTEON
or t0, t0, (MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX)
or t0, t0, (MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX | MIPS32_SR_PX)
#endif
mtc0 t0, COP_0_STATUS_REG
ITLBNOPFIX
@ -737,7 +688,7 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra)
*/
PTR_LA k0, _C_LABEL(cpu_intr)
jalr k0
sw a3, STAND_RA_OFFSET(sp) # for debugging
REG_S a3, CALLFRAME_RA(sp) # for debugging
/*
* Enable interrupts before doing ast().
@ -759,13 +710,10 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra)
/*
* Restore user registers and return.
*/
mfc0 t0, COP_0_STATUS_REG # disable int
and t0, t0, ~(MIPS_SR_INT_IE)
mtc0 t0, COP_0_STATUS_REG
ITLBNOPFIX
CLEAR_STATUS
GET_CPU_PCPU(k1)
lw k1, PC_CURPCB(k1)
PTR_L k1, PC_CURPCB(k1)
/*
* Update interrupt mask in saved status register
@ -793,7 +741,7 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra)
RESTORE_U_PCB_REG(t2, PC, k1)
mtlo t0
mthi t1
_MTC0 t2, COP_0_EXC_PC # set return address
MTC0 t2, COP_0_EXC_PC # set return address
RESTORE_U_PCB_REG(v0, V0, k1)
RESTORE_U_PCB_REG(v1, V1, k1)
RESTORE_U_PCB_REG(a0, A0, k1)
@ -814,9 +762,6 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra)
RESTORE_U_PCB_REG(k0, SR, k1)
RESTORE_U_PCB_REG(sp, SP, k1)
RESTORE_U_PCB_REG(ra, RA, k1)
#ifdef TARGET_OCTEON
and k0, k0, ~(MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX)
#endif
.set noat
RESTORE_U_PCB_REG(AT, AST, k1)
@ -832,78 +777,78 @@ NLEAF(MipsTLBInvalidException)
.set noat
.set noreorder
mfc0 k0, COP_0_BAD_VADDR
li k1, VM_MAXUSER_ADDRESS
sltu k1, k0, k1
bnez k1, 1f
MFC0 k0, COP_0_BAD_VADDR
PTR_LI k1, VM_MAXUSER_ADDRESS
sltu k1, k0, k1
bnez k1, 1f
nop
/* badvaddr = kernel address */
lui k1, %hi(_C_LABEL(kernel_segmap))
b 2f
lw k1, %lo(_C_LABEL(kernel_segmap))(k1)
/* Kernel address. */
lui k1, %hi(kernel_segmap) # k1=hi of segbase
b 2f
PTR_L k1, %lo(kernel_segmap)(k1) # k1=segment tab base
1:
/* badvaddr = user address */
1: /* User address. */
GET_CPU_PCPU(k1)
lw k1, PC_SEGBASE(k1)
PTR_L k1, PC_SEGBASE(k1)
2:
beqz k1, 3f /* invalid page directory pointer */
2: /* Validate page directory pointer. */
beqz k1, 3f
nop
srl k0, SEGSHIFT - 2
andi k0, 0xffc
addu k1, k1, k0
lw k1, 0(k1)
beqz k1, 3f /* invalid page table page pointer */
PTR_SRL k0, SEGSHIFT - 2 # k0=seg offset (almost)
beq k1, zero, MipsKernGenException # ==0 -- no seg tab
andi k0, k0, 0xffc # k0=seg offset (mask 0x3)
PTR_ADDU k1, k0, k1 # k1=seg entry address
PTR_L k1, 0(k1) # k1=seg entry
/* Validate page table pointer. */
beqz k1, 3f
nop
mfc0 k0, COP_0_BAD_VADDR
srl k0, PAGE_SHIFT - 2
andi k0, 0xffc
addu k1, k1, k0
MFC0 k0, COP_0_BAD_VADDR # k0=bad address (again)
PTR_SRL k0, PAGE_SHIFT - 2 # k0=VPN
andi k0, k0, 0xffc # k0=page tab offset
PTR_ADDU k1, k1, k0 # k1=pte address
lw k0, 0(k1) # k0=this PTE
lw k0, 0(k1)
andi k0, PTE_V
beqz k0, 3f /* invalid page table entry */
/* Validate page table entry. */
andi k0, PTE_V
beqz k0, 3f
nop
andi k0, k1, 4
bnez k0, odd_page
/* Check whether this is an even or odd entry. */
andi k0, k1, 4
bnez k0, odd_page
nop
even_page:
lw k0, 0(k1)
_SLL k0, k0, WIRED_SHIFT
_SRL k0, k0, WIRED_SHIFT
_MTC0 k0, COP_0_TLB_LO0
lw k0, 0(k1)
lw k1, 4(k1)
CLEAR_PTE_SWBITS(k0)
MTC0 k0, COP_0_TLB_LO0
COP0_SYNC
CLEAR_PTE_SWBITS(k1)
MTC0 k1, COP_0_TLB_LO1
COP0_SYNC
lw k0, 4(k1)
_SLL k0, k0, WIRED_SHIFT
_SRL k0, k0, WIRED_SHIFT
_MTC0 k0, COP_0_TLB_LO1
b tlb_insert_entry
b tlb_insert_entry
nop
odd_page:
lw k0, 0(k1)
_SLL k0, k0, WIRED_SHIFT
_SRL k0, k0, WIRED_SHIFT
_MTC0 k0, COP_0_TLB_LO1
lw k0, -4(k1)
_SLL k0, k0, WIRED_SHIFT
_SRL k0, k0, WIRED_SHIFT
_MTC0 k0, COP_0_TLB_LO0
lw k0, -4(k1)
lw k1, 0(k1)
CLEAR_PTE_SWBITS(k0)
MTC0 k0, COP_0_TLB_LO0
COP0_SYNC
CLEAR_PTE_SWBITS(k1)
MTC0 k1, COP_0_TLB_LO1
COP0_SYNC
tlb_insert_entry:
tlbp
HAZARD_DELAY
mfc0 k0, COP_0_TLB_INDEX
HAZARD_DELAY
bltz k0, tlb_insert_random
mfc0 k0, COP_0_TLB_INDEX
bltz k0, tlb_insert_random
nop
tlbwi
eret
@ -927,8 +872,8 @@ tlb_insert_random:
* Check for kernel stack overflow.
*/
GET_CPU_PCPU(k1)
lw k0, PC_CURTHREAD(k1)
lw k0, TD_KSTACK(k0)
PTR_L k0, PC_CURTHREAD(k1)
PTR_L k0, TD_KSTACK(k0)
sltu k0, k0, sp
bnez k0, _C_LABEL(MipsKernGenException)
nop
@ -944,8 +889,8 @@ tlb_insert_random:
sll k1, k1, PAGE_SHIFT + 1
PTR_LA k0, _C_LABEL(pcpu_space)
addiu k0, (PAGE_SIZE * 2)
addu k0, k0, k1
PTR_ADDU k0, PAGE_SIZE * 2
PTR_ADDU k0, k0, k1
/*
* Stash the original value of 'sp' so we can update trapframe later.
@ -954,12 +899,12 @@ tlb_insert_random:
move k1, sp
move sp, k0
subu sp, sp, KERN_EXC_FRAME_SIZE
PTR_SUBU sp, sp, KERN_EXC_FRAME_SIZE
move k0, ra
move ra, zero
sw ra, CALLFRAME_RA(sp) /* stop the ddb backtrace right here */
sw zero, CALLFRAME_SP(sp)
REG_S ra, CALLFRAME_RA(sp) /* stop the ddb backtrace right here */
REG_S zero, CALLFRAME_SP(sp)
move ra, k0
SAVE_CPU
@ -974,8 +919,8 @@ tlb_insert_random:
* Squelch any more overflow checks by setting the stack base to 0.
*/
GET_CPU_PCPU(k1)
lw k0, PC_CURTHREAD(k1)
sw zero, TD_KSTACK(k0)
PTR_L k0, PC_CURTHREAD(k1)
PTR_S zero, TD_KSTACK(k0)
move a1, a0
PANIC("kernel stack overflow - trapframe at %p")
@ -1008,34 +953,30 @@ END(MipsTLBInvalidException)
*/
NLEAF(MipsTLBMissException)
.set noat
mfc0 k0, COP_0_BAD_VADDR # k0=bad address
li k1, (VM_MAX_KERNEL_ADDRESS) # check fault address against
sltu k1, k1, k0 # upper bound of kernel_segmap
bnez k1, _C_LABEL(MipsKernGenException) # out of bound
lui k1, %hi(_C_LABEL(kernel_segmap)) # k1=hi of segbase
srl k0, 20 # k0=seg offset (almost)
lw k1, %lo(_C_LABEL(kernel_segmap))(k1) # k1=segment tab base
beq k1, zero, _C_LABEL(MipsKernGenException) # ==0 -- no seg tab
andi k0, k0, 0xffc # k0=seg offset (mask 0x3)
#xxx mips64 unsafe
addu k1, k0, k1 # k1=seg entry address
lw k1, 0(k1) # k1=seg entry
mfc0 k0, COP_0_BAD_VADDR # k0=bad address (again)
beq k1, zero, _C_LABEL(MipsKernGenException) # ==0 -- no page table
srl k0, 10 # k0=VPN (aka va>>10)
andi k0, k0, 0xff8 # k0=page tab offset
#xxx mips64 unsafe
addu k1, k1, k0 # k1=pte address
lw k0, 0(k1) # k0=lo0 pte
lw k1, 4(k1) # k1=lo1 pte
_SLL k0, WIRED_SHIFT # chop bits [31..30]
_SRL k0, WIRED_SHIFT # chop bits [31..30]
_MTC0 k0, COP_0_TLB_LO0 # lo0 is loaded
_SLL k1, WIRED_SHIFT # chop bits [31..30]
_SRL k1, WIRED_SHIFT # chop bits [31..30]
_MTC0 k1, COP_0_TLB_LO1 # lo1 is loaded
HAZARD_DELAY
MFC0 k0, COP_0_BAD_VADDR # k0=bad address
PTR_LI k1, VM_MAX_KERNEL_ADDRESS # check fault address against
sltu k1, k1, k0 # upper bound of kernel_segmap
bnez k1, MipsKernGenException # out of bound
lui k1, %hi(kernel_segmap) # k1=hi of segbase
PTR_SRL k0, SEGSHIFT - 2 # k0=seg offset (almost)
PTR_L k1, %lo(kernel_segmap)(k1) # k1=segment tab base
beq k1, zero, MipsKernGenException # ==0 -- no seg tab
andi k0, k0, 0xffc # k0=seg offset (mask 0x3)
PTR_ADDU k1, k0, k1 # k1=seg entry address
PTR_L k1, 0(k1) # k1=seg entry
MFC0 k0, COP_0_BAD_VADDR # k0=bad address (again)
beq k1, zero, MipsKernGenException # ==0 -- no page table
PTR_SRL k0, PAGE_SHIFT - 2 # k0=VPN
andi k0, k0, 0xff8 # k0=page tab offset
PTR_ADDU k1, k1, k0 # k1=pte address
lw k0, 0(k1) # k0=lo0 pte
lw k1, 4(k1) # k1=lo1 pte
CLEAR_PTE_SWBITS(k0)
MTC0 k0, COP_0_TLB_LO0 # lo0 is loaded
COP0_SYNC
CLEAR_PTE_SWBITS(k1)
MTC0 k1, COP_0_TLB_LO1 # lo1 is loaded
COP0_SYNC
tlbwr # write to tlb
HAZARD_DELAY
eret # return from exception
@ -1061,11 +1002,11 @@ END(MipsTLBMissException)
*
*----------------------------------------------------------------------------
*/
NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra)
subu sp, sp, STAND_FRAME_SIZE
NON_LEAF(MipsFPTrap, CALLFRAME_SIZ, ra)
PTR_SUBU sp, sp, CALLFRAME_SIZ
mfc0 t0, COP_0_STATUS_REG
sw ra, STAND_RA_OFFSET(sp)
.mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE)
REG_S ra, CALLFRAME_RA(sp)
.mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
or t1, t0, SR_COP_1_BIT
mtc0 t1, COP_0_STATUS_REG
@ -1086,10 +1027,10 @@ NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra)
* The instruction is in the branch delay slot so the branch will have to
* be emulated to get the resulting PC.
*/
sw a2, STAND_FRAME_SIZE + 8(sp)
PTR_S a2, CALLFRAME_SIZ + 8(sp)
GET_CPU_PCPU(a0)
#mips64 unsafe?
lw a0, PC_CURPCB(a0)
PTR_L a0, PC_CURPCB(a0)
PTR_ADDU a0, a0, U_PCB_REGS # first arg is ptr to CPU registers
move a1, a2 # second arg is instruction PC
move a2, t1 # third arg is floating point CSR
@ -1100,7 +1041,7 @@ NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra)
* Now load the floating-point instruction in the branch delay slot
* to be emulated.
*/
lw a2, STAND_FRAME_SIZE + 8(sp) # restore EXC pc
PTR_L a2, CALLFRAME_SIZ + 8(sp) # restore EXC pc
b 2f
lw a0, 4(a2) # a0 = coproc instruction
/*
@ -1110,10 +1051,10 @@ NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra)
1:
lw a0, 0(a2) # a0 = coproc instruction
#xxx mips64 unsafe?
addu v0, a2, 4 # v0 = next pc
PTR_ADDU v0, a2, 4 # v0 = next pc
2:
GET_CPU_PCPU(t2)
lw t2, PC_CURPCB(t2)
PTR_L t2, PC_CURPCB(t2)
SAVE_U_PCB_REG(v0, PC, t2) # save new pc
/*
* Check to see if the instruction to be emulated is a floating-point
@ -1127,7 +1068,7 @@ NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra)
*/
3:
GET_CPU_PCPU(a0)
lw a0, PC_CURTHREAD(a0) # get current thread
PTR_L a0, PC_CURTHREAD(a0) # get current thread
cfc1 a2, FPC_CSR # code = FP execptions
ctc1 zero, FPC_CSR # Clear exceptions
PTR_LA t3, _C_LABEL(trapsignal)
@ -1149,12 +1090,12 @@ NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra)
*/
FPReturn:
mfc0 t0, COP_0_STATUS_REG
lw ra, STAND_RA_OFFSET(sp)
PTR_L ra, CALLFRAME_RA(sp)
and t0, t0, ~SR_COP_1_BIT
mtc0 t0, COP_0_STATUS_REG
ITLBNOPFIX
j ra
PTR_ADDU sp, sp, STAND_FRAME_SIZE
PTR_ADDU sp, sp, CALLFRAME_SIZ
END(MipsFPTrap)
/*
@ -1182,7 +1123,7 @@ VECTOR(MipsCache, unknown)
PTR_LA k0, _C_LABEL(MipsCacheException)
li k1, MIPS_PHYS_MASK
and k0, k1
li k1, MIPS_KSEG1_START
PTR_LI k1, MIPS_KSEG1_START
or k0, k1
j k0
nop
@ -1200,16 +1141,16 @@ NESTED_NOPROFILE(MipsCacheException, KERN_EXC_FRAME_SIZE, ra)
.mask 0x80000000, -4
PTR_LA k0, _C_LABEL(panic) # return to panic
PTR_LA a0, 9f # panicstr
_MFC0 a1, COP_0_ERROR_PC
MFC0 a1, COP_0_ERROR_PC
mfc0 a2, COP_0_CACHE_ERR # 3rd arg cache error
_MTC0 k0, COP_0_ERROR_PC # set return address
MTC0 k0, COP_0_ERROR_PC # set return address
mfc0 k0, COP_0_STATUS_REG # restore status
li k1, SR_DIAG_DE # ignore further errors
or k0, k1
mtc0 k0, COP_0_STATUS_REG # restore status
HAZARD_DELAY
COP0_SYNC
eret

View File

@ -94,9 +94,9 @@
*
*----------------------------------------------------------------------------
*/
NON_LEAF(MipsEmulateFP, STAND_FRAME_SIZE, ra)
subu sp, sp, STAND_FRAME_SIZE
sw ra, STAND_RA_OFFSET(sp)
NON_LEAF(MipsEmulateFP, CALLFRAME_SIZ, ra)
subu sp, sp, CALLFRAME_SIZ
sw ra, CALLFRAME_RA(sp)
/*
* Decode the FMT field (bits 24-21) and FUNCTION field (bits 5-0).
*/
@ -2247,8 +2247,8 @@ result_fs_d: # result is FS
jal set_fd_d # save result (in t0,t1,t2,t3)
done:
lw ra, STAND_RA_OFFSET(sp)
addu sp, sp, STAND_FRAME_SIZE
lw ra, CALLFRAME_RA(sp)
addu sp, sp, CALLFRAME_SIZ
j ra
END(MipsEmulateFP)

View File

@ -369,7 +369,6 @@ mips_vector_init(void)
* when handler is installed for it
*/
set_intr_mask(ALL_INT_MASK);
intr_enable();
/* Clear BEV in SR so we start handling our own exceptions */
mips_wr_status(mips_rd_status() & ~SR_BOOT_EXC_VEC);

View File

@ -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.

View File

@ -144,7 +144,7 @@ cpu_fork(register struct thread *td1,register struct proc *p2,
pcb2->pcb_context[PCB_REG_RA] = (register_t)fork_trampoline;
/* Make sp 64-bit aligned */
pcb2->pcb_context[PCB_REG_SP] = (register_t)(((vm_offset_t)td2->td_pcb &
~(sizeof(__int64_t) - 1)) - STAND_FRAME_SIZE);
~(sizeof(__int64_t) - 1)) - CALLFRAME_SIZ);
pcb2->pcb_context[PCB_REG_S0] = (register_t)fork_return;
pcb2->pcb_context[PCB_REG_S1] = (register_t)td2;
pcb2->pcb_context[PCB_REG_S2] = (register_t)td2->td_frame;
@ -339,7 +339,7 @@ cpu_set_upcall(struct thread *td, struct thread *td0)
pcb2->pcb_context[PCB_REG_RA] = (register_t)fork_trampoline;
/* Make sp 64-bit aligned */
pcb2->pcb_context[PCB_REG_SP] = (register_t)(((vm_offset_t)td->td_pcb &
~(sizeof(__int64_t) - 1)) - STAND_FRAME_SIZE);
~(sizeof(__int64_t) - 1)) - CALLFRAME_SIZ);
pcb2->pcb_context[PCB_REG_S0] = (register_t)fork_return;
pcb2->pcb_context[PCB_REG_S1] = (register_t)td;
pcb2->pcb_context[PCB_REG_S2] = (register_t)td->td_frame;
@ -386,7 +386,7 @@ cpu_set_upcall_kse(struct thread *td, void (*entry)(void *), void *arg,
* in ``See MIPS Run'' by D. Sweetman, p. 269
* align stack */
sp = ((register_t)(stack->ss_sp + stack->ss_size) & ~0x7) -
STAND_FRAME_SIZE;
CALLFRAME_SIZ;
/*
* Set the trap frame to point at the beginning of the uts