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

Reply via email to