Fixing hpcarm (all SA11x0?) to mostly work again

Rafal Boni <[email protected]> Tue, 03 Jun 2008 09:57:46 -0400
Newsgroups gmane.os.netbsd.ports.arm,gmane.os.netbsd.ports.hpcarm
Message-ID <[email protected]>
Folks:
	Here's a patch to fix hpcarm to boot and be able to service interrupts 
post the ARMv6 merge.  I suspect Shark has some of the same issues.

This lets me happily complete autoconfig and get a single-user shell 
(whereas before the machine panic'ed before finishing autoconfig or hung 
early), but once in single user my Jornada 720 will still lock up after 
less than a line of output... Any help debugging that would be 
appreciated.  Even with LOCKDEBUG / DIAGNOSTIC I get no output after 
this point, and I can't get into DDB either.

Please send me any feedback you have.. Thanks!
--rafal
hpcarm-bughunt-head.diff (text/plain, 8.1 KB)
Index: arch/arm/arm32/intr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/arm32/intr.c,v
retrieving revision 1.28
diff -u -p -u -p -r1.28 intr.c
--- arch/arm/arm32/intr.c	27 Apr 2008 18:58:44 -0000	1.28
+++ arch/arm/arm32/intr.c	3 Jun 2008 13:46:04 -0000
@@ -69,7 +69,7 @@ set_spl_masks(void)
 	spl_masks[IPL_VM]	= irqmasks[IPL_VM];
 	spl_masks[IPL_SCHED]	= irqmasks[IPL_SCHED];
 	spl_masks[IPL_HIGH]	= irqmasks[IPL_HIGH];
-	spl_masks[IPL_NONE]	= 0;
+	spl_masks[IPL_NONE]	= irqmasks[IPL_NONE];
 
 }
 
Index: arch/arm/include/arm32/machdep.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/include/arm32/machdep.h,v
retrieving revision 1.8
diff -u -p -u -p -r1.8 machdep.h
--- arch/arm/include/arm32/machdep.h	4 Mar 2007 05:59:38 -0000	1.8
+++ arch/arm/include/arm32/machdep.h	3 Jun 2008 13:46:04 -0000
@@ -20,7 +20,7 @@ u_int initarm __P((void *));
 /* from arm/arm32/intr.c */
 void dosoftints __P((void));
 void set_spl_masks __P((void));
-#ifdef DIAGNOSTIC
+#if defined(DIAGNOSTIC) || defined(INTR_DEBUG)
 void dump_spl_masks __P((void));
 #endif
 #endif
Index: arch/arm/include/arm32/psl.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/include/arm32/psl.h,v
retrieving revision 1.16
diff -u -p -u -p -r1.16 psl.h
--- arch/arm/include/arm32/psl.h	27 Apr 2008 18:58:44 -0000	1.16
+++ arch/arm/include/arm32/psl.h	3 Jun 2008 13:46:04 -0000
@@ -54,17 +54,10 @@
  */
 
 #define spl0()		splx(IPL_NONE)
-#ifdef __HAVE_FAST_SOFTINTS
 #define splsoftclock()	raisespl(IPL_SOFTCLOCK)
 #define splsoftbio()	raisespl(IPL_SOFTBIO)
 #define splsoftnet()	raisespl(IPL_SOFTNET)
 #define splsoftserial()	raisespl(IPL_SOFTSERIAL)
-#else
-#define splsoftclock()	spl0()
-#define splsoftbio()	spl0()
-#define splsoftnet()	spl0()
-#define splsoftserial()	spl0()
-#endif
 #define splvm()		raisespl(IPL_VM)
 #define splsched()	raisespl(IPL_SCHED)
 #define splhigh()	raisespl(IPL_HIGH)
Index: arch/arm/sa11x0/sa11x0.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/sa11x0/sa11x0.c,v
retrieving revision 1.22
diff -u -p -u -p -r1.22 sa11x0.c
--- arch/arm/sa11x0/sa11x0.c	28 Apr 2008 20:23:14 -0000	1.22
+++ arch/arm/sa11x0/sa11x0.c	3 Jun 2008 13:46:04 -0000
@@ -75,6 +75,8 @@ __KERNEL_RCSID(0, "$NetBSD: sa11x0.c,v 1
 #include <machine/cpu.h>
 #include <machine/bus.h>
 
+#include <arm/arm32/psl.h>
+#include <arm/arm32/machdep.h>
 #include <arm/mainbus/mainbus.h>
 #include <arm/sa11x0/sa11x0_reg.h>
 #include <arm/sa11x0/sa11x0_var.h>
@@ -188,6 +190,9 @@ sa11x0_attach(struct device *parent, str
 	 * XXX enabled before intr mask is set.
 	 * XXX Having sane imask[] suffice??
 	 */
+	set_spl_masks();
+	raisespl(IPL_HIGH);
+
 	SetCPSR(I32_bit, 0);
 
 	/*
Index: arch/arm/sa11x0/sa11x0_irq.S
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/sa11x0/sa11x0_irq.S,v
retrieving revision 1.13
diff -u -p -u -p -r1.13 sa11x0_irq.S
--- arch/arm/sa11x0/sa11x0_irq.S	27 Apr 2008 18:58:45 -0000	1.13
+++ arch/arm/sa11x0/sa11x0_irq.S	3 Jun 2008 13:46:04 -0000
@@ -52,6 +52,9 @@
 Lspl_masks:
 	.word	_C_LABEL(spl_masks)
 
+Lcpu_info_store:
+        .word   _C_LABEL(cpu_info_store)
+
 	.globl	_C_LABEL(saipic_base)
 _C_LABEL(saipic_base):
 	.word	0x00000000
@@ -59,6 +62,7 @@ _C_LABEL(saipic_base):
 #ifdef INTR_DEBUG
 Ldbg_str:
 	.asciz	"irq_entry %x %x\n"
+	.align 5
 #endif
 
 LOCK_CAS_CHECK_LOCALS
@@ -247,22 +251,38 @@ nextirq:
 	b	. - 8
 
 ENTRY(irq_setmasks)
+	stmfd	sp!, {r0, r1, r4, lr}	/* Preserve registers */
+
 	/* Disable interrupts */
-	mrs	r3, cpsr_all
-	orr	r1, r3,  #(I32_bit)
-	msr	cpsr_all, r1
+	mrs	r1, cpsr_all
+	orr	r3, r1,  #(I32_bit)
+	msr	cpsr_c, r3
 
 	/* Calculate interrupt mask */
 	ldr	r0, Lspl_masks
+	ldr	r4, Lcpu_info_store
 	ldr	r2, [r4, #CI_CPL]
 	ldr	r2, [r0, r2, lsl #2]
 
+#ifdef INTR_DEBUG
+	stmfd	sp!, {r0, r1, r2}
+	adr	r0, Lsetmask_str
+	ldr	r1, [r4, #CI_CPL]
+	bl	_C_LABEL(printf)
+	ldmia	sp!, {r0, r1, r2}
+#endif
 	ldr	r0, _C_LABEL(saipic_base)
 	str	r2, [r0, #(SAIPIC_MR)]	/* Set mask register */
 
 	/* Restore old cpsr and exit */
-	msr	cpsr_all, r3
-	mov	pc, lr
+	msr	cpsr_c, r1
+	ldmfd	sp!, {r0, r1, r4, pc}	/* Restore registers */
+
+#ifdef INTR_DEBUG
+Lsetmask_str:
+	.asciz "irq_setmasks %x %x\n"
+	.align  5
+#endif
 
 Lcnt:
 	.word	_C_LABEL(uvmexp)
Index: arch/arm/sa11x0/sa11x0_irqhandler.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/sa11x0/sa11x0_irqhandler.c,v
retrieving revision 1.15
diff -u -p -u -p -r1.15 sa11x0_irqhandler.c
--- arch/arm/sa11x0/sa11x0_irqhandler.c	28 Apr 2008 20:23:14 -0000	1.15
+++ arch/arm/sa11x0/sa11x0_irqhandler.c	3 Jun 2008 13:46:04 -0000
@@ -94,6 +94,7 @@ u_int irqmasks[NIPL];
 extern void set_spl_masks(void);
 static int fakeintr(void *);
 #ifdef INTR_DEBUG
+void dump_spl_masks(void);
 static int dumpirqhandlers(void);
 #endif
 void intr_calculatemasks(void);
@@ -113,7 +114,7 @@ void stray_irqhandler(void *);
 void
 intr_calculatemasks(void)
 {
-	int irq, ipl;
+	int i, irq, ipl;
 	struct irqhandler *q;
 	int intrlevel[ICU_LEN];
 
@@ -131,15 +132,23 @@ intr_calculatemasks(void)
 		for (irq = 0; irq < ICU_LEN; irq++)
 			if (intrlevel[irq] & (1 << ipl))
 				irqs |= 1 << irq;
-		irqmasks[ipl] = irqs;
+
+		/* First enable the interrupt(s) at all lower level(s) */
+		for(i = 0; i < ipl; ++i)
+			irqmasks[i] |= irqs;
+
+		/* Then disable the interrupt(s) at all higher level(s) */
+		for( ; i < NIPL-1; ++i)
+			irqmasks[i] &= ~irqs;
+
 	}
 
 	/*
 	 * Enforce a hierarchy that gives slow devices a better chance at not
 	 * dropping data.
 	 */
-	for (ipl = IPL_NONE; ipl < NIPL - 1; ipl++)
-		irqmasks[ipl + 1] |= irqmasks[ipl];
+	for (ipl = 0; ipl < NIPL - 1; ipl++)
+		irqmasks[ipl + 1] &= irqmasks[ipl];
 }
 
 
@@ -212,6 +221,7 @@ sa11x0_intr_establish(sa11x0_chipset_tag
 
 	SetCPSR(I32_bit, saved_cpsr & I32_bit);
 #ifdef INTR_DEBUG
+	dump_spl_masks();
 	dumpirqhandlers();
 #endif
 	return ih;
Index: arch/hpcarm/hpcarm/autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hpcarm/hpcarm/autoconf.c,v
retrieving revision 1.16
diff -u -p -u -p -r1.16 autoconf.c
--- arch/hpcarm/hpcarm/autoconf.c	12 Feb 2008 17:30:57 -0000	1.16
+++ arch/hpcarm/hpcarm/autoconf.c	3 Jun 2008 13:46:05 -0000
@@ -52,6 +52,7 @@ __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v
 #include <machine/bootconfig.h>
 #include <machine/config_hook.h>
 #include <machine/intr.h>
+#include <arm/arm32/machdep.h>
 
 #include "sacom.h"
 
@@ -162,13 +163,8 @@ cpu_configure(void)
 		panic("configure: mainbus not configured");
 
 	/* Debugging information */
-#ifdef DEBUG
-	printf("ipl_bio=%08x ipl_net=%08x ipl_tty=%08x ipl_vm=%08x\n",
-	    imask[IPL_BIO], imask[IPL_NET], imask[IPL_TTY],
-	    imask[IPL_VM]);
-	printf("ipl_audio=%08x ipl_imp=%08x ipl_high=%08x ipl_serial=%08x\n",
-	    imask[IPL_AUDIO], imask[IPL_CLOCK], imask[IPL_HIGH],
-	    imask[IPL_SERIAL]);
+#ifdef 	DIAGNOSTIC
+	dump_spl_masks();
 #endif
 
 	/* Time to start taking interrupts so lets open the flood gates .... */
Index: arch/hpcarm/hpcarm/hpc_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hpcarm/hpcarm/hpc_machdep.c,v
retrieving revision 1.85
diff -u -p -u -p -r1.85 hpc_machdep.c
--- arch/hpcarm/hpcarm/hpc_machdep.c	27 Apr 2008 18:58:47 -0000	1.85
+++ arch/hpcarm/hpcarm/hpc_machdep.c	3 Jun 2008 13:46:05 -0000
@@ -310,6 +310,7 @@ initarm(int argc, char **argv, struct bo
 	 * Heads up ... Setup the CPU / MMU / TLB functions.
 	 */
 	set_cpufuncs();
+	IRQdisable;
 
 #ifdef DEBUG_BEFOREMMU
 	/*
Index: arch/hpcarm/include/irqhandler.h
===================================================================
RCS file: /cvsroot/src/sys/arch/hpcarm/include/irqhandler.h,v
retrieving revision 1.8
diff -u -p -u -p -r1.8 irqhandler.h
--- arch/hpcarm/include/irqhandler.h	27 Apr 2008 18:58:47 -0000	1.8
+++ arch/hpcarm/include/irqhandler.h	3 Jun 2008 13:46:05 -0000
@@ -73,7 +73,7 @@ typedef struct irqhandler {
 } irqhandler_t;
 
 #ifdef _KERNEL
-extern u_int irqmask[NIPL];
+extern u_int irqmasks[NIPL];
 extern irqhandler_t *irqhandlers[NIRQS];
 
 void irq_init(void);