PERFORCE change 54880 for review

Juli Mallett jmallett at FreeBSD.org
Mon Jun 14 01:20:35 GMT 2004


http://perforce.freebsd.org/chv.cgi?CH=54880

Change 54880 by jmallett at jmallett_oingo on 2004/06/14 01:20:09

	Handle CPU-level interrupts (soft and hard) and move the clock intr
	handler to the clock code.  XXX all of this is generic MIPS, but I'm
	not comfortable with it being there, so it's with the SGI port for
	now.  Ideally we'd have a "cpu" bus with CPU interrupts off it and
	we'd establish interrupts with that, and it would do the same as the
	hardintr/softintr stuff here.  And off the cpu would hang the normal
	mips clock, which here is being called SGI IP22 solely because of its
	calls to the (abstracted) code for getting cycles per hz, which right
	now only works on the IP22.

Affected files ...

.. //depot/projects/mips/sys/mips/include/cpuregs.h#16 edit
.. //depot/projects/mips/sys/mips/sgimips/clock.c#8 edit
.. //depot/projects/mips/sys/mips/sgimips/intr.h#5 edit
.. //depot/projects/mips/sys/mips/sgimips/machdep_sgimips.c#32 edit

Differences ...

==== //depot/projects/mips/sys/mips/include/cpuregs.h#16 (text+ko) ====

@@ -210,30 +210,18 @@
  * The interrupt masks.
  * If a bit in the mask is 1 then the interrupt is enabled (or pending).
  */
-#define	MIPS_INT_MASKX		0xff00
+#define	MIPS_INT_MASK		0xff00
 #define	MIPS_INT_MASK_5		0x8000
 #define	MIPS_INT_MASK_4		0x4000
 #define	MIPS_INT_MASK_3		0x2000
 #define	MIPS_INT_MASK_2		0x1000
 #define	MIPS_INT_MASK_1		0x0800
 #define	MIPS_INT_MASK_0		0x0400
-#define	MIPS_HARD_INT_MASKX	0xfc00
+#define	MIPS_HARD_INT_MASK	0xfc00
 #define	MIPS_SOFT_INT_MASK_1	0x0200
 #define	MIPS_SOFT_INT_MASK_0	0x0100
 
 /*
- * mips3 CPUs have on-chip timer at INT_MASK_5.  Each platform can
- * choose to enable this interrupt.
- */
-#if defined(MIPS_ENABLE_CLOCK_INTR)
-#define	MIPS_INT_MASK			MIPS_INT_MASKX
-#define	MIPS_HARD_INT_MASK		MIPS_HARD_INT_MASKX
-#else
-#define	MIPS_INT_MASK			(MIPS_INT_MASKX &  ~MIPS_INT_MASK_5)
-#define	MIPS_HARD_INT_MASK		(MIPS_HARD_INT_MASKX & ~MIPS_INT_MASK_5)
-#endif
-
-/*
  * The bits in the context register.
  *
  * XXX XContext

==== //depot/projects/mips/sys/mips/sgimips/clock.c#8 (text+ko) ====

@@ -33,10 +33,13 @@
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/proc.h>
 #include <sys/time.h>
 #include <sys/timetc.h>
 
+#include <machine/cpu.h>
 #include <machine/cpuinfo.h>
+#include <platform/intr.h>
 #include <platform/models.h>
 
 static unsigned
@@ -51,9 +54,28 @@
 	~0,
 	0,
 	"Uninitialized SGIMIPS",
-	1000
+	800
 };
 
+static void
+sgimips_clock5_intr(void *arg)
+{
+	struct clockframe cf;
+	struct trapframe *tf;
+
+	if (curthread == NULL)
+		return;
+
+	/*
+	 * Set next clock edge.
+	 */
+	tf = curthread->td_frame;
+	cf.sr = tf->tf_regs[TF_SR];
+	cf.pc = tf->tf_regs[TF_EPC];
+	hardclock(&cf);
+	mips_wr_compare(mips_rd_count() + curcpu()->ci_cycles_per_hz);
+}
+
 void
 cpu_initclocks(void)
 {
@@ -67,8 +89,7 @@
 	}
 	tc_init(&sgimips_timecounter);
 	mips_wr_compare(mips_rd_count() + curcpu()->ci_cycles_per_hz);
-	/* XXX intr_establish? */
-	mips_wr_status(mips_rd_status() | MIPS_INT_MASK_5);
+	platform_establish_hardintr(5, sgimips_clock5_intr, NULL);
 }
 
 void

==== //depot/projects/mips/sys/mips/sgimips/intr.h#5 (text+ko) ====

@@ -23,14 +23,13 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $P4: //depot/projects/mips/sys/mips/sgimips/intr.h#4 $
+ * $P4: //depot/projects/mips/sys/mips/sgimips/intr.h#5 $
  */
 
 #ifndef	_SGIMIPS_INTR_H_
 #define	_SGIMIPS_INTR_H_
 
-/*
- * Nothing to see here.
- */
+void platform_establish_hardintr(int, void (*)(void *), void *);
+void platform_establish_softintr(int, void (*)(void *), void *);
 
 #endif /* _SGIMIPS_INTR_H_ */

==== //depot/projects/mips/sys/mips/sgimips/machdep_sgimips.c#32 (text+ko) ====

@@ -51,7 +51,7 @@
 
 #include "opt_model.h"
 
-struct machine_type {
+static struct machine_type {
 	const char *identifier;
 	void (*init)(void);
 	int type;
@@ -62,6 +62,13 @@
 	{ NULL,		NULL,		0 }
 };
 
+struct intrhand {
+	void (*handler)(void *);
+	void *arg;
+};
+static struct intrhand intrhard[6];
+static struct intrhand intrsoft[2];
+
 int arcsmem, availmem, lpmem;
 int mach_type, mach_subtype, mach_boardrev;
 
@@ -168,26 +175,72 @@
 }
 
 void
+platform_establish_hardintr(int intr, void (*handler)(void *), void *arg)
+{
+	struct intrhand *ih;
+
+	if (intr < 0 || intr > 5)
+		panic("%s called for unknown hard intr %d", __func__, intr);
+	ih = &intrhard[intr];
+	ih->handler = handler;
+	ih->arg = arg;
+
+	/* Route above the 2 lower software interrupt bits.  */
+	mips_wr_status(mips_rd_status() | (((1 << intr) << 8) << 2));
+}
+
+void
+platform_establish_softintr(int intr, void (*handler)(void *), void *arg)
+{
+	struct intrhand *ih;
+
+	if (intr < 0 || intr > 1)
+		panic("%s called for unknown soft intr %d", __func__, intr);
+	ih = &intrsoft[intr];
+	ih->handler = handler;
+	ih->arg = arg;
+
+	mips_wr_status(mips_rd_status() | ((1 << intr) << 8));
+}
+
+void
 platform_intr(struct trapframe *tf)
 {
+	struct intrhand *ih;
 	register_t cause;
+	int hard;
+	int intr;
+	int i;
 
 	cause = mips_rd_cause();
+	intr = (cause & MIPS_INT_MASK) >> 8;
+	cause &= ~MIPS_INT_MASK;
+	mips_wr_cause(cause);
 
-	if (cause & MIPS_INT_MASK_5) {
-		struct clockframe cf;
-
-		/*
-		 * Set next clock edge.
-		 */
-		cf.sr = tf->tf_regs[TF_SR];
-		cf.pc = tf->tf_regs[TF_EPC];
-		hardclock(&cf);
-		mips_wr_compare(mips_rd_count() +
-				curcpu()->ci_cycles_per_hz);
-	} else {
-		printf("stray intr cause %lx\n", cause);
+	while ((i = fls(intr)) != 0) {
+		intr &= ~(1 << (i - 1));
+		switch (i) {
+		case 1: case 2:
+			/* Software interrupt. */
+			i--; /* Get a 0-offset interrupt. */
+			hard = 0;
+			ih = &intrsoft[i];
+			break;
+		default:
+			/* Hardware interrupt. */
+			i -= 2; /* Trim software interrupt bits. */
+			i--; /* Get a 0-offset interrupt. */
+			hard = 1;
+			ih = &intrhard[i];
+			break;
+		}
+		if (ih->handler != NULL)
+			(*ih->handler)(ih->arg);
+		else
+			printf("stray %s interrupt %d\n",
+			       hard ? "hard" : "soft", i);
 	}
+	KASSERT(i == 0, ("all interrupts handled"));
 }
 
 void


More information about the p4-projects mailing list