Skip to content

Commit

Permalink
Sprinkle NOPs to avoid load delay hazard on R3000.
Browse files Browse the repository at this point in the history
  • Loading branch information
tsutsui committed Mar 8, 2011
1 parent 908b1c6 commit b23f3db
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 6 deletions.
14 changes: 13 additions & 1 deletion sys/arch/mips/mips/locore.S
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $NetBSD: locore.S,v 1.183 2011/02/26 13:58:34 tsutsui Exp $ */
/* $NetBSD: locore.S,v 1.184 2011/03/08 15:05:40 tsutsui Exp $ */

/*
* Copyright (c) 1992, 1993
Expand Down Expand Up @@ -66,6 +66,12 @@

#include "assym.h"

#if defined(MIPS1) || defined(MIPS2)
#define NOP_L nop
#else
#define NOP_L /* nothing */
#endif

.set noreorder

.globl start
Expand Down Expand Up @@ -252,6 +258,7 @@ NESTED(cpu_switchto, CALLFRAME_SIZ, ra)
PTR_L a0, L_PROC(MIPS_CURLWP) # argument to ras_lookup
PTR_L s5, L_PCB(MIPS_CURLWP) # XXXuvm_lwp_getuarea
PTR_L v1, P_RASLIST(a0) # get raslist
NOP_L # load delay
beqz v1, 1f # skip call if empty
nop
jal _C_LABEL(ras_lookup) # ras_lookup(p, pc)
Expand Down Expand Up @@ -316,11 +323,14 @@ softint_cleanup:
nop
#endif /* PARANOIA */
PTR_L t0, L_CPU(MIPS_CURLWP)
NOP_L # load delay
INT_L t1, CPU_INFO_MTX_COUNT(t0)
NOP_L # load delay
INT_ADDU t1, 1
INT_S t1, CPU_INFO_MTX_COUNT(t0)
REG_L ra, CALLFRAME_RA(sp)
REG_L v0, CALLFRAME_S0(sp) # get softint lwp
NOP_L # load delay
PTR_S zero, L_CTXSWITCH(v0) # clear l_ctxswtch
#if IPL_SCHED != IPL_HIGH
j _C_LABEL(splhigh_noprof)
Expand Down Expand Up @@ -419,6 +429,7 @@ LEAF(lwp_oncpu)
PTR_LA t1, 1f # load addr of cleanup
PTR_S t1, PCB_ONFAULT(t0) # save onfault handler
PTR_L t2, L_CPU(a0) # grab cpu of supplied lwp
NOP_L # load delay
PTR_L t3, CPU_INFO_CURLWP(t2) # grab curlwp of that cpu
li v0, ESRCH # assume the lwp isn't curlwp
bne a0, t3, 1f # branch if true (not equal)
Expand Down Expand Up @@ -640,6 +651,7 @@ XNESTED(mips_fpu_trap)
1:
INT_L a0, 0(a0) # a0 = coproc instruction
2:
NOP_L # load delay

/*
* Check to see if the instruction to be emulated is a floating-point
Expand Down
14 changes: 13 additions & 1 deletion sys/arch/mips/mips/locore_mips1.S
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $NetBSD: locore_mips1.S,v 1.73 2011/02/20 07:45:47 matt Exp $ */
/* $NetBSD: locore_mips1.S,v 1.74 2011/03/08 15:05:40 tsutsui Exp $ */

/*
* Copyright (c) 1992, 1993
Expand Down Expand Up @@ -205,10 +205,12 @@ NESTED_NOPROFILE(MIPSX(kern_gen_exception), KERNFRAME_SIZ, ra)
.mask 0x80000000, -4
#ifdef PARANOIA
PTR_L k0, L_PCB(MIPS_CURLWP)
nop
slt k0, k0, sp # k0 = L_PCB(MIPS_CURLWP) < sp
1: beqz k0, 1b # loop forever if false
nop
PTR_L k0, L_PCB(MIPS_CURLWP)
nop
PTR_ADDU k0, USPACE
slt k0, sp, k0 # k0 = sp < L_PCB(MIPS_CURLWP) + USPACE
2: beqz k0, 2b # loop forever if false
Expand Down Expand Up @@ -270,7 +272,9 @@ NESTED_NOPROFILE(MIPSX(kern_gen_exception), KERNFRAME_SIZ, ra)
* save PPL in trapframe
*/
PTR_L t0, L_CPU(MIPS_CURLWP)
nop
INT_L t1, CPU_INFO_CPL(t0) # get current priority level
nop
INT_S t1, TF_BASE+TF_PPL(sp) # save priority level
#endif /* PARANOIA */

Expand All @@ -297,6 +301,7 @@ NESTED_NOPROFILE(MIPSX(kern_gen_exception), KERNFRAME_SIZ, ra)
* Restore registers and return from the exception.
*/
REG_L a0, TF_BASE+TF_REG_SR(sp)
nop
mtc0 a0, MIPS_COP_0_STATUS # restore the SR, disable intrs

/*
Expand All @@ -313,7 +318,9 @@ MIPSX(kern_return):
#ifdef PARANOIA
INT_L t2, TF_BASE+TF_PPL(sp) # get saved priority level
PTR_L t0, L_CPU(MIPS_CURLWP)
nop
INT_L t1, CPU_INFO_CPL(t0) # get current priority level
nop
11: bne t2, t1, 11b # loop forever if unequal
nop

Expand Down Expand Up @@ -384,16 +391,20 @@ NESTED_NOPROFILE(MIPSX(kern_intr), KERNFRAME_SIZ, ra)
.mask 0x80000000, -4
#ifdef PARANOIA
PTR_L k0, L_PCB(MIPS_CURLWP)
nop
slt k0, k0, sp # k0 = L_PCB(MIPS_CURLWP) < sp
1: beqz k0, 1b # loop forever if false
nop
PTR_L k0, L_PCB(MIPS_CURLWP)
nop
PTR_ADDU k0, USPACE
slt k0, sp, k0 # k0 = sp < L_PCB(MIPS_CURLWP) + USPACE
2: beqz k0, 2b # loop forever if false
nop
PTR_L k0, L_CPU(MIPS_CURLWP)
nop
INT_L k0, CPU_INFO_IDEPTH(k0) # grab interrupt depth
nop
sltu k0, k0, 3 # must be < 3
3: beqz k0, 3b # loop forever if false
nop
Expand Down Expand Up @@ -795,6 +806,7 @@ NESTED_NOPROFILE(MIPSX(user_intr), CALLFRAME_SIZ, ra)
* Interrupt depth is now back to 0.
*/
PTR_L t0, L_CPU(MIPS_CURLWP)
nop
INT_S zero, CPU_INFO_IDEPTH(t0)

#ifdef __HAVE_FAST_SOFTINTS
Expand Down
9 changes: 5 additions & 4 deletions sys/arch/mips/mips/spl.S
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $NetBSD: spl.S,v 1.3 2011/02/25 14:57:45 tsutsui Exp $ */
/* $NetBSD: spl.S,v 1.4 2011/03/08 15:05:40 tsutsui Exp $ */

/*-
* Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
Expand Down Expand Up @@ -38,7 +38,7 @@
#include <mips/asm.h>
#include <mips/cpuregs.h>

RCSID("$NetBSD: spl.S,v 1.3 2011/02/25 14:57:45 tsutsui Exp $")
RCSID("$NetBSD: spl.S,v 1.4 2011/03/08 15:05:40 tsutsui Exp $")

#include "assym.h"

Expand Down Expand Up @@ -88,8 +88,9 @@ _splraise:
* Can only use a0-a3 and v0-v1
*/
PTR_L a3, L_CPU(MIPS_CURLWP)
NOP_L
NOP_L # load delay
INT_L v0, CPU_INFO_CPL(a3) # get current IPL from cpu_info
NOP_L # load delay
sltu v1, a1, v0 # newipl < curipl
bnez v1, 1f # yes, don't change.
nop # branch delay
Expand Down Expand Up @@ -132,6 +133,7 @@ STATIC_XLEAF(_splsw_splx_noprof) # does not get mcount hooks
PTR_L a3, L_CPU(MIPS_CURLWP) # get cpu_info
NOP_L # load delay
INT_L a2, CPU_INFO_CPL(a3) # get IPL from cpu_info
NOP_L # load delay
beq a0, a2, 2f # if same, nothing to do
nop # branch delay
#ifdef PARANOIA
Expand All @@ -143,7 +145,6 @@ STATIC_XLEAF(_splsw_splx_noprof) # does not get mcount hooks
sll a2, a0, INT_SCALESHIFT # convert IPL to array offset
PTR_ADDU v1, a2 # add to table addr
INT_L a1, (v1) # load SR bits for this IPL
NOP_L # load delay
1:
mfc0 v1, MIPS_COP_0_STATUS # fetch status register
NOP_L # load delay
Expand Down

0 comments on commit b23f3db

Please sign in to comment.