Subject: next68k softintr(9) patch
To: None <port-next68k@NetBSD.org>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: port-next68k
Date: 03/06/2007 00:56:02
Could anyone try or review attached patch?

There are several possible issues though:
- According to next68k/include/cpu.h, TIMER is at ipl 6
  but current IPL_CLOCK is (PSL_S|PSL_IPL3).
  It was chaned after DMA fixes were integrated, but
  is it really required?
- NEXT_I_SOFTINT[01] are defined in cpu.h and it seems
  that they can generate real hardware interrupts,
  but current siron() doesn't touch any hardware and
  it uses hp300 derived simulated sir to handle softintrs.
  Are these bits are just taken from NEXTSTEP but unused?
- next68k seems to have its own interrupt control register,
  so maybe it should have own spl control routines like x86
  rather than traditional m68k splN() based implementation.

---
Izumi Tsutsui

Index: conf/files.next68k
===================================================================
RCS file: /cvsroot/src/sys/arch/next68k/conf/files.next68k,v
retrieving revision 1.36
diff -u -r1.36 files.next68k
--- conf/files.next68k	11 Dec 2005 12:18:25 -0000	1.36
+++ conf/files.next68k	5 Mar 2007 15:18:03 -0000
@@ -37,6 +37,7 @@
 file	arch/m68k/m68k/kgdb_machdep.c		kgdb
 file	arch/m68k/m68k/pmap_motorola.c
 file	arch/m68k/m68k/procfs_machdep.c		procfs
+file	arch/m68k/m68k/softintr.c
 file	arch/m68k/m68k/sys_machdep.c
 file	arch/m68k/m68k/vm_machdep.c
 
Index: dev/zs.c
===================================================================
RCS file: /cvsroot/src/sys/arch/next68k/dev/zs.c,v
retrieving revision 1.27
diff -u -r1.27 zs.c
--- dev/zs.c	11 Dec 2005 12:18:25 -0000	1.27
+++ dev/zs.c	5 Mar 2007 15:18:03 -0000
@@ -176,7 +176,6 @@
 
 /* Interrupt handlers. */
 static int zshard(void *);
-static void zssoft(void *);
 
 static int zs_get_speed(struct zs_chanstate *);
 
@@ -209,7 +208,7 @@
 	struct zsc_attach_args zsc_args;
 	volatile struct zschan *zc;
 	struct zs_chanstate *cs;
-	int s, channel, sir;
+	int s, channel;
 
 	zs_attached = 1;
 
@@ -275,13 +274,10 @@
 	}
 
 	isrlink_autovec(zshard, NULL, NEXT_I_IPL(NEXT_I_SCC), 0, NULL);
+	zsc->zsc_softintr_cookie = softintr_establish(IPL_SOFTSERIAL,
+	    (void (*)(void *))zsc_intr_soft, zsc);
 	INTR_ENABLE(NEXT_I_SCC);
 
-	sir = allocate_sir(zssoft, zsc);
-	if (sir != SIR_SERIAL) {
-		panic("Unexpected zssoft sir");
-	}
-
 	/*
 	 * Set the master interrupt enable and interrupt vector.
 	 * (common to both channels, do it on A)
@@ -319,12 +315,12 @@
 zshard(void *arg)
 {
 	struct zsc_softc *zsc;
-	int unit, rr3, rval, softreq;
+	int unit, rr3, rval;
 
 	if (!INTR_OCCURRED(NEXT_I_SCC))
 		return 0;
 
-	rval = softreq = 0;
+	rval = 0;
 	for (unit = 0; unit < zsc_cd.cd_ndevs; unit++) {
 		zsc = zsc_cd.cd_devs[unit];
 		if (zsc == NULL)
@@ -335,53 +331,15 @@
 			rval |= rr3;
 			zsc->zsc_intrcnt.ev_count++;
 		}
-		softreq |= zsc->zsc_cs[0]->cs_softreq;
-		softreq |= zsc->zsc_cs[1]->cs_softreq;
+		/* We are at splzs here, so no need to lock. */
+		if (zsc->zsc_cs[0]->cs_softreq || zsc->zsc_cs[1]->cs_softreq)
+			softintr_schedule(zsc->zsc_softintr_cookie);
 	}
 
-	/* We are at splzs here, so no need to lock. */
-	if (softreq && (zssoftpending == 0)) {
-		zssoftpending = 1;
-		setsoftserial();
-	}
 	return(1);
 }
 
 /*
- * Similar scheme as for zshard (look at all of them)
- */
-static void
-zssoft(void *arg)
-{
-	struct zsc_softc *zsc;
-	int s, unit;
-
-	/* This is not the only ISR on this IPL. */
-	if (zssoftpending == 0)
-		panic("zssoft not pending");
-
-	/*
-	 * The soft intr. bit will be set by zshard only if
-	 * the variable zssoftpending is zero.  The order of
-	 * these next two statements prevents our clearing
-	 * the soft intr bit just after zshard has set it.
-	 */
-	/* ienab_bic(IE_ZSSOFT); */
-	zssoftpending = 0;
-
-	/* Make sure we call the tty layer at spltty. */
-	s = spltty();
-	for (unit = 0; unit < zsc_cd.cd_ndevs; unit++) {
-		zsc = zsc_cd.cd_devs[unit];
-		if (zsc == NULL)
-			continue;
-		(void)zsc_intr_soft(zsc);
-	}
-	splx(s);
-}
-
-
-/*
  * Compute the current baud rate given a ZS channel.
  */
 static int
Index: include/intr.h
===================================================================
RCS file: /cvsroot/src/sys/arch/next68k/include/intr.h,v
retrieving revision 1.17
diff -u -r1.17 intr.h
--- include/intr.h	16 Feb 2007 02:53:49 -0000	1.17
+++ include/intr.h	5 Mar 2007 15:18:03 -0000
@@ -42,72 +42,60 @@
 /* watch out for side effects */
 #define splx(s)         ((s) & PSL_IPL ? _spl(s) : spl0())
 
+#define splsoft()	splraise1()
+#define splsoftnet()	splsoft()
+#define splsoftclock()	splsoft()
+#define splsoftserial()	splsoft()
+#define splbio()        splraise3()
+#define splnet()        splraise3()
+#define spltty()        splraise3()
+#define splserial()     splraise5()
+#define splvm()         splraise6()
+#define splclock()      splraise3()	/* ??? */
+#define splstatclock()  splclock()
+#define splhigh()       spl7()
+#define splsched()      spl7()
+#define spllock()       spl7()
+
+#define spldma()        splraise6()
+
 /****************************************************************/
 
-#define	IPL_HIGH	(PSL_S|PSL_IPL7)
-#define	IPL_SERIAL	(PSL_S|PSL_IPL5)
-#define	IPL_SCHED	(PSL_S|PSL_IPL7)
-#define	IPL_LOCK	(PSL_S|PSL_IPL7)
-#define	IPL_CLOCK	(PSL_S|PSL_IPL3)
-#define	IPL_STATCLOCK	IPL_CLOCK
-#define	IPL_VM		(PSL_S|PSL_IPL6)
-#define	IPL_TTY		(PSL_S|PSL_IPL3)
-#define	IPL_BIO		(PSL_S|PSL_IPL3)
-#define	IPL_NET		(PSL_S|PSL_IPL3)
-#define	IPL_SOFTNET	(PSL_S|PSL_IPL2)
-#define	IPL_SOFTCLOCK	(PSL_S|PSL_IPL1)
 #define	IPL_NONE	0
+#define	IPL_SOFTCLOCK	1
+#define	IPL_SOFTNET	2
+#define	IPL_SOFTSERIAL	3
+#define	IPL_SOFT	4
+#define	IPL_BIO		5
+#define	IPL_NET		6
+#define	IPL_TTY		7
+#define	IPL_SERIAL	8
+#define	IPL_VM		9
+#define	IPL_CLOCK	10
+#define	IPL_STATCLOCK	IPL_CLOCK
+#define	IPL_HIGH	11
+#define	IPL_LOCK	IPL_HIGH
+#define	IPL_SCHED	IPL_HIGH
+#define	NIPL		12
 
 typedef int ipl_t;
 typedef struct {
-	ipl_t _ipl;
+	ipl_t _psl;
 } ipl_cookie_t;
 
-static inline ipl_cookie_t
-makeiplcookie(ipl_t ipl)
-{
+extern const int ipl2psl_table[NIPL];
 
-	return (ipl_cookie_t){._ipl = ipl};
-}
+ipl_cookie_t makeiplcookie(ipl_t);
 
 static inline int
 splraiseipl(ipl_cookie_t icookie)
 {
 
-	return _splraise(icookie._ipl);
+	return _splraise(icookie._psl);
 }
 
-#include <sys/spl.h>
-
-#define spldma()        _splraise(PSL_S|PSL_IPL6)
-
 /****************************************************************/
 
-/*
- * simulated software interrupt register
- */
-extern volatile u_int8_t ssir;
-
-#define	SIR_NET		0x01
-#define	SIR_CLOCK	0x02
-#define	SIR_SERIAL	0x04
-#define SIR_DTMGR	0x08
-#define SIR_ADB		0x10
-
-#define	siron(mask)	\
-	__asm volatile ( "orb %1,%0" : "=m" (ssir) : "i" (mask))
-#define	siroff(mask)	\
-	__asm volatile ( "andb %1,%0" : "=m" (ssir) : "ir" (~(mask)));
-
-#define	setsoftnet()	siron(SIR_NET)
-#define	setsoftclock()	siron(SIR_CLOCK)
-#define	setsoftserial()	siron(SIR_SERIAL)
-#define	setsoftdtmgr()	siron(SIR_DTMGR)
-#define	setsoftadb()	siron(SIR_ADB)
-
-extern u_long allocate_sir(void (*)(void *),void *);
-extern void init_sir(void);
-
 /* locore.s */
 int	spl0(void);
 
@@ -118,6 +106,8 @@
 #define INTR_DISABLE(x)		(*intrmask &= (~NEXT_I_BIT(x)))
 #define INTR_OCCURRED(x)	(*intrstat & NEXT_I_BIT(x))
 
+#include <m68k/softintr.h>
+
 #endif /* _KERNEL */
 
 #endif /* _NEXT68K_INTR_H_ */
Index: include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/next68k/include/types.h,v
retrieving revision 1.2
diff -u -r1.2 types.h
--- include/types.h	11 Sep 2006 15:07:50 -0000	1.2
+++ include/types.h	5 Mar 2007 15:18:03 -0000
@@ -3,4 +3,5 @@
 #include <m68k/types.h>
 
 #define __HAVE_TIMECOUNTER
+#define	__HAVE_GENERIC_SOFT_INTERRUPTS
 #define	__HAVE_GENERIC_TODR
Index: include/z8530var.h
===================================================================
RCS file: /cvsroot/src/sys/arch/next68k/include/z8530var.h,v
retrieving revision 1.5
diff -u -r1.5 z8530var.h
--- include/z8530var.h	11 Dec 2005 12:18:25 -0000	1.5
+++ include/z8530var.h	5 Mar 2007 15:18:03 -0000
@@ -50,6 +50,7 @@
 	/* Machine-dependent part follows... */
 	struct	evcnt zsc_intrcnt;		/* count interrupts */
 	struct zs_chanstate  zsc_cs_store[2];
+	void	*zsc_softintr_cookie;
 };
 
 /*
Index: next68k/autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/next68k/next68k/autoconf.c,v
retrieving revision 1.18
diff -u -r1.18 autoconf.c
--- next68k/autoconf.c	11 Dec 2005 12:18:29 -0000	1.18
+++ next68k/autoconf.c	5 Mar 2007 15:18:03 -0000
@@ -159,7 +159,7 @@
 
 	INTR_SETMASK(0);
 
-	init_sir();
+	softintr_init();
 
 	if (config_rootfound("mainbus", NULL) == NULL)
 		panic("autoconfig failed, no root");
Index: next68k/isr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/next68k/next68k/isr.c,v
retrieving revision 1.22
diff -u -r1.22 isr.c
--- next68k/isr.c	11 Dec 2005 12:18:29 -0000	1.22
+++ next68k/isr.c	5 Mar 2007 15:18:03 -0000
@@ -386,36 +386,6 @@
 		isr->isr_evcnt->ev_count++;
 }
 
-/*
- * netisr junk...
- * should use an array of chars instead of
- * a bitmask to avoid atomicity locking issues.
- */
-
-void
-netintr(void)
-{
-	int n, s;
-
-	s = splhigh();
-	n = netisr;
-	netisr = 0;
-	splx(s);
-
-#define DONETISR(bit, fn) do {		\
-		if (n & (1 << bit))	\
-			fn();		\
-		} while (0)
-
-	s = splsoftnet();
-
-#include <net/netisr_dispatch.h>
-
-#undef DONETISR
-
-	splx(s);
-}
-
 #if 0
 /* ARGSUSED */
 static int
@@ -425,3 +395,25 @@
 	return (1);
 }
 #endif
+
+const int ipl2psl_table[NIPL] = {
+	[IPL_NONE]       = PSL_IPL0,
+	[IPL_SOFTCLOCK]  = PSL_IPL1,
+	[IPL_SOFTNET]    = PSL_IPL1,
+	[IPL_SOFTSERIAL] = PSL_IPL1,
+	[IPL_SOFT]       = PSL_IPL1,
+	[IPL_BIO]        = PSL_IPL3,
+	[IPL_NET]        = PSL_IPL3,
+	[IPL_TTY]        = PSL_IPL3,
+	[IPL_SERIAL]     = PSL_IPL5,
+	[IPL_VM]         = PSL_IPL6,
+	[IPL_CLOCK]      = PSL_IPL3,	/* ??? */
+	[IPL_HIGH]       = PSL_IPL7,
+};
+
+ipl_cookie_t
+makeiplcookie(ipl_t ipl)
+{
+
+	return (ipl_cookie_t){._psl = ipl2psl_table[ipl] | PSL_S};
+}
Index: next68k/locore.s
===================================================================
RCS file: /cvsroot/src/sys/arch/next68k/next68k/locore.s,v
retrieving revision 1.45
diff -u -r1.45 locore.s
--- next68k/locore.s	11 Dec 2005 12:18:29 -0000	1.45
+++ next68k/locore.s	5 Mar 2007 15:18:03 -0000
@@ -1018,8 +1018,6 @@
  * necessitating a stack cleanup.
  */
 
-BSS(ssir,1)
-
 ASENTRY_NOPROFILE(rei)
 	tstl	_C_LABEL(astpending)	| AST pending?
 	jeq	Lchksir			| no, go check for SIR
Index: next68k/trap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/next68k/next68k/trap.c,v
retrieving revision 1.64
diff -u -r1.64 trap.c
--- next68k/trap.c	4 Mar 2007 06:00:27 -0000	1.64
+++ next68k/trap.c	5 Mar 2007 15:18:04 -0000
@@ -220,12 +220,6 @@
 #define MDB_ISPID(p)	((p) == mmupid)
 #endif
 
-
-#define NSIR	32
-void (*sir_routines[NSIR])(void *);
-void *sir_args[NSIR];
-int next_sir;
-
 /*
  * trap and syscall both need the following work done before returning
  * to user mode.
@@ -315,7 +309,6 @@
 	ksiginfo_t ksi;
 	int s;
 	u_quad_t sticks = 0 /* XXX initialiser works around compiler bug */;
-	int bit;
 	static int panicking = 0;
 
 	uvmexp.traps++;
@@ -585,13 +578,9 @@
 
 	case T_SSIR:		/* software interrupt */
 	case T_SSIR|T_USER:
-		while ((bit = ffs(ssir))) {
-			--bit;
-			ssir &= ~(1 << bit);
-			uvmexp.softs++;
-			if (sir_routines[bit])
-				sir_routines[bit](sir_args[bit]);
-		}
+
+		softintr_dispatch();
+
 		/*
 		 * If this was not an AST trap, we are all done.
 		 */
@@ -1039,29 +1028,3 @@
 }
 #endif
 #endif
-
-/*
- * Allocation routines for software interrupts.
- */
-u_long
-allocate_sir(void (*proc)(void *), void *arg)
-{
-	int bit;
-
-	if( next_sir >= NSIR )
-		panic("allocate_sir: none left");
-	bit = next_sir++;
-	sir_routines[bit] = proc;
-	sir_args[bit] = arg;
-	return (1 << bit);
-}
-
-void
-init_sir(void)
-{
-	extern void netintr(void);
-
-	sir_routines[0] = (void (*)(void *))netintr;
-	sir_routines[1] = softclock;
-	next_sir = 2;
-}