Subject: Re: port-shark/22355 [was: Help needed to fix NetBSD/shark]
To: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
From: Chris Gilbert <chris@dokein.co.uk>
List: port-arm
Date: 08/04/2007 17:08:47
This is a multi-part message in MIME format.
--------------000800080105060800030209
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

Izumi Tsutsui wrote:
> chris@dokein.co.uk wrote:
> 
> 
>> when it hangs are you able to print the contents of:
>> i8259_mask
>> spl_mask
>> current_mask
>> disabled_mask
>> current_spl_level
>> current_intr_depth
> 
> Quick sanity checks in cpu_idle() show:
> 
> i8259_mask         = 0x00002c41 or 0x00002ce7 (and more?)
> spl_mask           = 0xffff2c5d (== spl_masks[_SPL_CLOCK])
> current_mask       = 0x0000d3ba (== all unestablished irqs are disabled)
> disabled_mask      = 0x00000000
> current_spl_level  = 0
> current_intr_depth = 0
> 
> So at least spl_mask seems wrong.

That's definetly wrong.  jmmv's found that the attached isa_irq.S patch
helps, but still causes hangs.

All the patch really does is use the raisespl and splx calls to fix the
masks, and so should make sure that the spl_mask always matches the
current_spl_level.

However, the irq handler never touched the spl_mask before.

Thanks,
Chris

--------------000800080105060800030209
Content-Type: text/plain;
 name="isa_irq.S.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="isa_irq.S.diff"

Index: isa_irq.S
===================================================================
RCS file: /cvsroot/src/sys/arch/shark/isa/isa_irq.S,v
retrieving revision 1.7
diff -d -u -p -r1.7 isa_irq.S
--- isa_irq.S	9 Mar 2007 19:21:59 -0000	1.7
+++ isa_irq.S	4 Aug 2007 12:47:47 -0000
@@ -172,9 +172,9 @@ ASENTRY_NP(irq_entry)
 	/* Block the current requested interrupts */
 
 	ldr	r1, Ldisabled_mask
-	ldr	r0, [r1]
-	stmfd	sp!, {r0}
-	orr	r0, r0, r8
+	ldr	r10, [r1]
+	orr	r0, r10, r8
+	str	r0, [r1]	
 
 	/*
  	 * Need to block all interrupts at the IPL or lower for
@@ -199,20 +199,14 @@ Lfind_highest_ipl:
 	beq	Lfind_highest_ipl
 
 	/* r9 = SPL level of highest priority interrupt */
-	add	r9, r9, #1
-	ldr	r2, [r7, r9, lsl #2]
-	mvn	r2, r2
-	orr	r0, r0, r2
-
-	str	r0, [r1]	
+	add	r0, r9, #1
 
-	ldr	r0, Lcurrent_spl_level
-	ldr	r1, [r0]
-	str	r9, [r0]
-	stmfd	sp!, {r1}
+	/* call raise spl to reach this spl level, which will update the
+         * hardware mask */
+	bl	_C_LABEL(raisespl)
 
-	/* Update the IOMD irq masks */
-	bl	_C_LABEL(irq_setmasks)
+	/* store the previous spl_level and disabled mask */
+	stmfd	sp!, {r0, r10}
 
 	mrs     r0, cpsr_all		/* Enable IRQ's */
 	bic	r0, r0, #I32_bit
@@ -266,17 +260,15 @@ nextirq:
 	teq	r9, #(1 << 16)		/* done the last bit ? */
 	bne	irqloop			/* no - loop back. */
 
-	ldmfd	sp!, {r2}
-	ldr	r1, Lcurrent_spl_level
-	str	r2, [r1]
+	ldmfd	sp!, {r0, r10}		/* previous spl_level & disabled_mask */
 
 	/* Restore previous disabled mask */
-	ldmfd	sp!, {r2}
 	ldr	r1, Ldisabled_mask
-	str	r2, [r1]
-	bl	_C_LABEL(irq_setmasks)
+	str	r10, [r1]
 
-	bl	_C_LABEL(dosoftints)	/* Handle the soft interrupts */
+	/* restore spl level, which will update hardware mask and run soft
+	 * interrupts */
+	bl	_C_LABEL(splx)
 
 	/* Kill IRQ's in preparation for exit */
 	mrs     r0, cpsr_all

--------------000800080105060800030209--