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