Module Name: src
Committed By: matt
Date: Fri Dec 24 07:13:19 UTC 2010
Modified Files:
src/sys/arch/mips/mips [matt-nb5-mips64]: lock_stubs.S spl.S
Log Message:
MIPS1 needs load delay nops. Fix a problem in the RAS mips_spin_enter
where we weren't actually decrementing ci_mtx_count.
To generate a diff of this commit:
cvs rdiff -u -r1.9.18.10 -r1.9.18.11 src/sys/arch/mips/mips/lock_stubs.S
cvs rdiff -u -r1.1.2.8 -r1.1.2.9 src/sys/arch/mips/mips/spl.S
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/mips/mips/lock_stubs.S
diff -u src/sys/arch/mips/mips/lock_stubs.S:1.9.18.10 src/sys/arch/mips/mips/lock_stubs.S:1.9.18.11
--- src/sys/arch/mips/mips/lock_stubs.S:1.9.18.10 Sun Feb 28 03:28:54 2010
+++ src/sys/arch/mips/mips/lock_stubs.S Fri Dec 24 07:13:19 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: lock_stubs.S,v 1.9.18.10 2010/02/28 03:28:54 matt Exp $ */
+/* $NetBSD: lock_stubs.S,v 1.9.18.11 2010/12/24 07:13:19 matt Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -236,8 +236,8 @@
NESTED(mutex_spin_enter, CALLFRAME_SIZ, ra)
move t0, a0
PTR_L t2, L_CPU(MIPS_CURLWP)
- INT_L ta1, CPU_INFO_CPL(t2)
INT_L ta0, MTX_IPL(t0)
+ INT_L ta1, CPU_INFO_CPL(t2)
/*
* If the current IPL is less than the mutex's IPL, we need to raise
@@ -268,6 +268,7 @@
*/
1:
INT_L ta2, CPU_INFO_MTX_COUNT(t2)
+ nop
INT_ADDU ta3, ta2, -1
INT_S ta3, CPU_INFO_MTX_COUNT(t2)
bltz ta2, 2f
@@ -277,6 +278,7 @@
#ifdef PARANOIA
INT_L ta1, CPU_INFO_MTX_OLDSPL(t2)
INT_L ta2, CPU_INFO_CPL(t2) # get updated CPL
+ nop
sltu v0, ta2, ta0 # v0 = cpl < mtx_ipl
sltu v1, ta2, ta1 # v1 = cpl < oldspl
sll v0, 1
@@ -322,7 +324,7 @@
*
* o All of the critical sections are 20 bytes in size, and the entry
* to each critical section is aligned on a 16 byte boundary (see
- * top of _lock_ras() for why). The entry is defined here as the
+ * top of _restart_lock_ras() for why). The entry is defined here as the
* point after where a restart occurs if we trap within the section.
*
* o The entire code block is aligned on a 128 byte boundary, and is
@@ -330,7 +332,7 @@
* after taking a trap with:
*
* if ((addr & ~127) == _lock_ras_start)
- * addr = _lock_ras(addr);
+ * addr = _restart_lock_ras(addr);
*
* See definition of MIPS_LOCK_RAS_SIZE in asm.h.
*
@@ -347,12 +349,15 @@
* unsigned long old, unsigned long new);
*/
.text
- .p2align 7
+#if MIPS_LOCK_RAS_SIZE != 256
+#error RAS alignment needs to be fixed
+#endif
+ .p2align 8
EXPORT(_lock_ras_start)
-
- .space 12
-
+ nop
+ nop
+ nop
LEAF_NOPROFILE(_atomic_cas_ulong)
PTR_L t0, (a0) /* <- critical section start */
_atomic_cas_start:
@@ -404,16 +409,16 @@
#ifndef LOCKDEBUG
.p2align 5
-/*
- * int mutex_enter(kmutex_t *mtx);
- */
nop
nop
nop
+/*
+ * int mutex_enter(kmutex_t *mtx);
+ */
LEAF_NOPROFILE(mutex_enter)
PTR_L t0, (a0) /* <- critical section start */
_mutex_enter_start:
- nop
+ nop
bnez t0, 1f
nop
PTR_S MIPS_CURLWP, (a0)/* <- critical section end */
@@ -443,7 +448,10 @@
END(mutex_exit)
nop
- .p2align 7 /* Get out of the RAS block */
+#if MIPS_LOCK_RAS_SIZE != 256
+#error RAS alignment needs to be fixed
+#endif
+ .p2align 8 /* Get out of the RAS block */
/*
* void mutex_spin_enter(kmutex_t *mtx);
@@ -453,6 +461,7 @@
PTR_L t2, L_CPU(MIPS_CURLWP)
INT_L a0, MTX_IPL(t0)
INT_L ta1, CPU_INFO_CPL(t2) # get current cpl
+ nop
/*
* If the current IPL is less than the mutex's IPL, we need to raise
@@ -477,8 +486,9 @@
*/
1:
INT_L ta2, CPU_INFO_MTX_COUNT(t2)
+ nop
INT_ADDU ta3, ta2, -1
- INT_S ta2, CPU_INFO_MTX_COUNT(t2)
+ INT_S ta3, CPU_INFO_MTX_COUNT(t2)
bnez ta2, 2f
nop
@@ -525,7 +535,7 @@
* t2 clobbered
*/
-LEAF_NOPROFILE(_lock_ras)
+LEAF_NOPROFILE(_restart_lock_ras)
li t1, -16
and t2, k1, t1
la t0, _atomic_cas_start
@@ -547,7 +557,7 @@
1:
j ra
addiu k1, t0, -4
-END(_lock_ras)
+END(_restart_lock_ras)
/*
* int ucas_32(volatile uint32_t *ptr, uint32_t old, uint32_t new, uint32_t *ret)
@@ -587,6 +597,7 @@
PTR_L t2, L_CPU(MIPS_CURLWP)
#if defined(DIAGNOSTIC)
INT_L t0, MTX_LOCK(a0)
+ nop
SYNC
beqz t0, 2f
nop
@@ -603,6 +614,7 @@
*/
#ifdef PARANOIA
INT_L a2, MTX_IPL(a0)
+ nop
#endif
INT_L a0, CPU_INFO_MTX_OLDSPL(t2)
@@ -610,6 +622,7 @@
* Increment the mutex count
*/
INT_L t0, CPU_INFO_MTX_COUNT(t2)
+ nop
INT_ADDU t0, t0, 1
INT_S t0, CPU_INFO_MTX_COUNT(t2)
Index: src/sys/arch/mips/mips/spl.S
diff -u src/sys/arch/mips/mips/spl.S:1.1.2.8 src/sys/arch/mips/mips/spl.S:1.1.2.9
--- src/sys/arch/mips/mips/spl.S:1.1.2.8 Wed Dec 22 06:08:10 2010
+++ src/sys/arch/mips/mips/spl.S Fri Dec 24 07:13:19 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: spl.S,v 1.1.2.8 2010/12/22 06:08:10 matt Exp $ */
+/* $NetBSD: spl.S,v 1.1.2.9 2010/12/24 07:13:19 matt Exp $ */
/*-
* Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
@@ -38,10 +38,16 @@
#include <mips/asm.h>
#include <mips/cpuregs.h>
-RCSID("$NetBSD: spl.S,v 1.1.2.8 2010/12/22 06:08:10 matt Exp $")
+RCSID("$NetBSD: spl.S,v 1.1.2.9 2010/12/24 07:13:19 matt Exp $")
#include "assym.h"
+#ifdef MIPS1
+#define NOP_L nop
+#else
+#define NOP_L /* nothing */
+#endif
+
.data
.globl _C_LABEL(ipl_sr_map)
.type _C_LABEL(ipl_sr_map),@object
@@ -56,6 +62,7 @@
.word MIPS_INT_MASK /* IPL_HIGH */
.text
+ .set noreorder
/*
* MIPS processor interrupt control
*
@@ -68,10 +75,13 @@
* Can only use a0-a3 and v0-v1
*/
PTR_L a3, L_CPU(MIPS_CURLWP)
+ NOP_L
INT_L v0, CPU_INFO_CPL(a3) # get current IPL from cpu_info
sltu v1, a1, v0 # newipl < curipl
bnez v1, 1f # yes, don't change.
+ nop # branch delay
mfc0 v1, MIPS_COP_0_STATUS # fetch status register
+ NOP_L # load delay
or v1, MIPS_INT_MASK # enable all interrupts
xor a0, v1 # disable ipl's masked bits
DYNAMIC_STATUS_MASK(a0,v0) # machine dependent masking
@@ -79,34 +89,37 @@
COP0_SYNC
#ifdef MULTIPROCESSOR
PTR_L a3, L_CPU(MIPS_CURLWP) ## make sure curcpu is correct
+ NOP_L ## load delay
#endif
INT_S a1, CPU_INFO_CPL(a3) ## save IPL in cpu_info
mtc0 a0, MIPS_COP_0_STATUS ## store back
COP0_SYNC
#ifdef PARANOIA
j ra
- nop
+ nop # branch delay
#endif /* PARANOIA */
1:
#ifdef PARANOIA
mfc0 v1, MIPS_COP_0_STATUS
+ NOP_L # load delay
and a0, v1 # a1 contains bit that MBZ
3: bnez a0, 3b # loop forever
- nop
+ nop # branch delay
#endif /* PARANOIA */
j ra
- nop
+ nop # branch delay
STATIC_LEAF(_splsw_splx)
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
beq a0, a2, 2f # if same, nothing to do
- nop
+ nop # branch delay
#ifdef PARANOIA
sltu v0, a0, a2 # v0 = a0 < a2
99: beqz v0, 99b # loop forever if false
- nop
+ nop # branch delay
#endif /* PARANOIA */
#move a1, zero # avoid lookup on splx(IPL_NONE)
#beq a0, zero, 1f # skip fetch
@@ -114,8 +127,10 @@
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
or v1, MIPS_INT_MASK # set all INT bits
xor v1, a1 # clear any bits for this IPL
DYNAMIC_STATUS_MASK(v1,t0) # machine dependent masking
@@ -126,7 +141,7 @@
COP0_SYNC
#ifdef PARANOIA
j ra
- nop
+ nop # branch delay
#endif /* PARANOIA */
2:
#ifdef PARANOIA
@@ -138,21 +153,20 @@
and v1, MIPS_INT_MASK
xor a1, MIPS_INT_MASK
3: bne a1, v1, 3b
- nop
+ nop # branch delay
#endif /* PARANOIA */
j ra
- nop
+ nop # branch delay
END(_splsw_splx)
STATIC_LEAF(_splsw_spl0)
INT_L v1, _C_LABEL(ipl_sr_map) + 4*IPL_NONE
- xor v1, MIPS_INT_MASK | MIPS_SR_INT_IE # invert and or in IE
PTR_L a3, L_CPU(MIPS_CURLWP)
+ xor v1, MIPS_INT_MASK | MIPS_SR_INT_IE # invert and or in IE
#mtc0 zero, MIPS_COP_0_CAUSE # clear SOFT_INT bits
- COP0_SYNC
+ #COP0_SYNC
mfc0 v0, MIPS_COP_0_STATUS
- nop
- nop
+ NOP_L # load delay
or v0, v1
DYNAMIC_STATUS_MASK(v0,t0) # machine dependent masking
mtc0 zero, MIPS_COP_0_STATUS ## disable interrupts
@@ -165,7 +179,7 @@
mtc0 v0, MIPS_COP_0_STATUS ## enable all sources
COP0_SYNC
j ra
- nop
+ nop # branch delay
END(_splsw_spl0)
STATIC_LEAF(_splsw_setsoftintr)
@@ -175,14 +189,14 @@
nop
nop
mfc0 v0, MIPS_COP_0_CAUSE # fetch cause register
- nop
+ NOP_L # load delay
or v0, v0, a0 # set soft intr. bits
mtc0 v0, MIPS_COP_0_CAUSE # store back
COP0_SYNC
mtc0 v1, MIPS_COP_0_STATUS # enable interrupts
COP0_SYNC
j ra
- nop
+ nop
END(_splsw_setsoftintr)
STATIC_LEAF(_splsw_clrsoftintr)
@@ -199,7 +213,7 @@
mtc0 v1, MIPS_COP_0_STATUS # enable interrupts
COP0_SYNC
j ra
- nop
+ nop # branch delay
END(_splsw_clrsoftintr)
STATIC_LEAF(_splsw_splraise)
@@ -207,18 +221,20 @@
PTR_LA v1, _C_LABEL(ipl_sr_map)
sll a2, a0, INT_SCALESHIFT
PTR_ADDU v1, a2
- INT_L a0, (v1)
b _splraise
- nop
+ INT_L a0, (v1)
END(_splsw_splraise)
STATIC_LEAF(_splsw_splhigh)
STATIC_XLEAF(_splsw_splhigh_noprof)
PTR_L a3, L_CPU(MIPS_CURLWP)
+ NOP_L # load delay
INT_L v0, CPU_INFO_CPL(a3) # get current IPL from cpu_info
li a1, IPL_HIGH #
beq v0, a1, 1f # don't do anything if IPL_HIGH
+ nop # branch delay
mfc0 v1, MIPS_COP_0_STATUS # fetch status register
+ NOP_L # load delay
and a0, v1, MIPS_INT_MASK # select all interrupts
xor a0, v1 # clear all interrupts
DYNAMIC_STATUS_MASK(a0,a2) # machine dependent masking
@@ -226,106 +242,112 @@
COP0_SYNC
#ifdef MULTIPROCESSOR
PTR_L a3, L_CPU(MIPS_CURLWP) ## make sure curcpu is correct
+ NOP_L ## load delay
#endif
INT_S a1, CPU_INFO_CPL(a3) ## save IPL in cpu_info
#ifdef PARANOIA
j ra ## return
- nop
+ nop # branch delay
#endif /* PARANOIA */
1:
#ifdef PARANOIA
mfc0 v1, MIPS_COP_0_STATUS # fetch status register
and v1, MIPS_INT_MASK # any int bits set?
2: bnez v1, 2b # loop forever.
- nop
+ nop # branch delay
#endif /* PARANOIA */
j ra ## return
- nop
+ nop # branch delay
END(_splsw_splhigh)
+ .p2align 4
STATIC_LEAF(_splsw_splddb)
INT_L a0, _C_LABEL(ipl_sr_map) + 4*IPL_DDB
- li a1, IPL_DDB
b _splraise
- nop
+ li a1, IPL_DDB
+ nop
END(_splsw_splddb)
STATIC_LEAF(_splsw_splsched)
INT_L a0, _C_LABEL(ipl_sr_map) + 4*IPL_SCHED
- li a1, IPL_SCHED
b _splraise
- nop
+ li a1, IPL_SCHED
+ nop
END(_splsw_splsched)
STATIC_LEAF(_splsw_splvm)
INT_L a0, _C_LABEL(ipl_sr_map) + 4*IPL_VM
- li a1, IPL_VM
b _splraise
+ li a1, IPL_VM
+ nop
END(_splsw_splvm)
STATIC_LEAF(_splsw_splsoftserial)
INT_L a0, _C_LABEL(ipl_sr_map) + 4*IPL_SOFTSERIAL
- li a1, IPL_SOFTSERIAL
b _splraise
- nop
+ li a1, IPL_SOFTSERIAL
+ nop
END(_splsw_splsoftserial)
STATIC_LEAF(_splsw_splsoftnet)
INT_L a0, _C_LABEL(ipl_sr_map) + 4*IPL_SOFTNET
- li a1, IPL_SOFTNET
b _splraise
- nop
+ li a1, IPL_SOFTNET
+ nop
END(_splsw_splsoftnet)
STATIC_LEAF(_splsw_splsoftbio)
INT_L a0, _C_LABEL(ipl_sr_map) + 4*IPL_SOFTBIO
- li a1, IPL_SOFTBIO
b _splraise
- nop
+ li a1, IPL_SOFTBIO
+ nop
END(_splsw_splsoftbio)
STATIC_LEAF(_splsw_splsoftclock)
INT_L a0, _C_LABEL(ipl_sr_map) + 4*IPL_SOFTCLOCK
- li a1, IPL_SOFTCLOCK
b _splraise
- nop
+ li a1, IPL_SOFTCLOCK
+ nop
END(_splsw_splsoftclock)
STATIC_LEAF(_splsw_splintr)
mfc0 ta1, MIPS_COP_0_CAUSE # get active interrupts
-
+ NOP_L # load delay
# restrict to hard int bits
and v1, ta1, MIPS_HARD_INT_MASK # now have pending interrupts
li v0, IPL_NONE # return IPL_NONE
beq v1, zero, 2f # quick exit if nothing pending
- nop
+ nop # branch delay
li v0, IPL_VM # start at IPL_VM
PTR_LA ta3, _C_LABEL(ipl_sr_map) + 4*IPL_VM
INT_L ta2, -4(ta3) # load mask for IPL_SOFTSERIAL
+ NOP_L # load delay
xor ta2, MIPS_INT_MASK # invert
and v1, ta2 # apply to pending bits
1:
INT_L ta2, (ta3) # get SR bits for ipl in v0
+ NOP_L # load delay
xor ta2, MIPS_INT_MASK # invert
and ta2, v1 # any match to pending intrs?
beq ta2, zero, 2f # no, return ipl
+ nop # branch delay
PTR_ADDU ta3, 1 << INT_SCALESHIFT # point to next entry
addiu v0, 1 # increase ipl by 1
- move v1, ta2 # whittle down pending intrs
b 1b # and check it
+ move v1, ta2 # whittle down pending intrs
2:
- INT_S v1, (a0) # return a new pending mask
j ra
- #nop
+ INT_S v1, (a0) # return a new pending mask
END(_splsw_splintr)
STATIC_LEAF(_splsw_splcheck)
#ifdef PARANOIA
PTR_L t0, L_CPU(MIPS_CURLWP)
+ NOP_L # load delay
INT_L t1, CPU_INFO_CPL(t0) # get current priority level
mfc0 t0, MIPS_COP_0_STATUS # get current status
@@ -335,12 +357,13 @@
sll t1, INT_SCALESHIFT # shift cpl to array index
PTR_ADDU t2, t1
INT_L t3, (t2) # load value
+ NOP_L # load delay
xor t3, MIPS_INT_MASK # invert
1: bne t0, t3, 1b # loop forever if not equal
- nop
+ nop # branch delay
#endif /* PARANOIA */
j ra
- nop
+ nop # branch delay
END(_splsw_splcheck)
.rdata