PERFORCE change 161084 for review

Arnar Mar Sig antab at FreeBSD.org
Sat Apr 25 21:34:02 UTC 2009


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

Change 161084 by antab at antab_farm on 2009/04/25 21:33:55

	Fix interrupt handling to get ithreads working

Affected files ...

.. //depot/projects/avr32/src/sys/avr32/avr32/intr.c#6 edit
.. //depot/projects/avr32/src/sys/avr32/include/intr.h#5 edit

Differences ...

==== //depot/projects/avr32/src/sys/avr32/avr32/intr.c#6 (text+ko) ====

@@ -24,6 +24,15 @@
  * SUCH DAMAGE.
  */
 
+/**
+ * AVR32 has 4 interrupt priorities and 64 interrupt sources. Individual
+ * interrupt sources can not be masked, only the priority groups they
+ * belong to.
+ *
+ * INT3 will be permanently masked so we can mask individual sources to
+ * implement ithread support.
+ */
+
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD: $");
 
@@ -45,7 +54,9 @@
 #include <machine/at32ap700x.h>
 
 /* Private data */
+static void intr_change_priority(int irq, int pri);
 static struct intr_event *intr_event[IRQ_COUNT];
+static int intr_intlevel[IRQ_COUNT];
 static int intrcnt_tab[IRQ_COUNT];
 static int intrcnt_index = 0;
 extern vm_offset_t _evba;
@@ -84,6 +95,7 @@
 
 	/* Setup INTC, every interrupt is at priority 0 */
 	for (i = 0; i < IRQ_COUNT; i++) {
+		intr_intlevel[i] = 0;
 		offset = AT32AP700X_BASE + AT32AP700X_INTC_OFFSET +
 			(i * sizeof(register_t));
 
@@ -91,19 +103,31 @@
 			(vm_offset_t)intr_handle0 - (vm_offset_t)&_evba);
 	}
 
-	/* Enable interrupts */
+	/* Enable interrupts, note, INT3 is always masked */
 	sysreg_write(COMPARE, 0);
-	sysreg_write(SR, sysreg_read(SR) & ~INTR_MASK);
+	sysreg_write(SR, (sysreg_read(SR) & ~INTR_MASK) |
+		bit_offset(SYS, SR, I3M));
+}
+
+static void
+intr_change_priority(int irq, int pri)
+{
+	size_t offset;
+
+	/* Few sanity checks */
+	KASSERT(irq < IRQ_COUNT, ("Invalid interrupt group"));
+	KASSERT(pri < 4, ("Invalid priority level"));
+
+	offset = AT32AP700X_BASE + AT32AP700X_INTC_OFFSET +
+		(irq * sizeof(register_t));
+	reg_write(offset, INTC, IPR,
+		(reg_read(offset, INTC, IPR) & ~bit_mask(INTC, IPR, INTLEVEL)) |
+		(pri << bit_shift(INTC, IPR, INTLEVEL)));
 }
 
 void
 intr_handle(struct trapframe *tf, int irq, int pri)
 {
-	if (!intr_event[irq] || TAILQ_EMPTY(&intr_event[irq]->ie_handlers)) {
-		printf("stray interrupt %d, priority %d\n", irq, pri);
-		return;
-	}
-
 	if (intr_event_handle(intr_event[irq], tf) != 0) {
 		panic("stray interrupt %d, priority %d\n", irq, pri);
 	}
@@ -113,23 +137,19 @@
 void
 avr32_mask_irq(uintptr_t irq)
 {
-	int pri;
+	/* Sanity check */
+	KASSERT(irq < IRQ_COUNT, ("Invalid interrupt group"));
 
-	pri = bit_value(INTC, IPR, INTLEVEL,
-		reg_read(AT32AP700X_BASE + AT32AP700X_INTC_OFFSET +
-			(irq * sizeof(register_t)), INTC, IPR));
-	sysreg_write(SR, sysreg_read(SR) | (bit_offset(SYS, SR, I0M) << pri));
+	intr_change_priority(irq, 3);
 }
 
 void
 avr32_unmask_irq(uintptr_t irq)
 {
-	int pri;
+	/* Sanity check */
+	KASSERT(irq < IRQ_COUNT, ("Invalid interrupt group"));
 
-	pri = bit_value(INTC, IPR, INTLEVEL,
-		reg_read(AT32AP700X_BASE + AT32AP700X_INTC_OFFSET +
-			(irq * sizeof(register_t)), INTC, IPR));
-	sysreg_write(SR, sysreg_read(SR) | ~(bit_offset(SYS, SR, I0M) << pri));
+	intr_change_priority(irq, intr_intlevel[irq]);
 }
 
 void
@@ -161,6 +181,7 @@
 	intr_event_add_handler(event, name, filt, hand, arg,
 		intr_priority(flags), flags, cookiep);
 }
+
 int
 avr32_remove_irqhandler(int irq, void *cookie)
 {

==== //depot/projects/avr32/src/sys/avr32/include/intr.h#5 (text+ko) ====

@@ -34,8 +34,7 @@
     (bit_offset(SYS, SR, GM) |	\
     bit_offset(SYS, SR, I0M) |	\
     bit_offset(SYS, SR, I1M) |	\
-    bit_offset(SYS, SR, I2M) |	\
-    bit_offset(SYS, SR, I3M))
+    bit_offset(SYS, SR, I2M))
 
 #ifndef LOCORE
 


More information about the p4-projects mailing list