Date: Sat, 25 Apr 2009 21:34:01 GMT From: Arnar Mar Sig <antab@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 161084 for review Message-ID: <200904252134.n3PLY1t5018778@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=161084 Change 161084 by antab@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200904252134.n3PLY1t5018778>
