diff options
author | rrs <rrs@FreeBSD.org> | 2010-02-20 16:30:29 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2010-02-20 16:30:29 +0000 |
commit | c3a2e02803a9c8498b9d463374d0a78a037c4a57 (patch) | |
tree | d1f56abf0589eb2bade888e5ee80ccc8890df5c7 /sys/mips | |
parent | 238d0be5d06d3c6bd1f038e62fdbe89fec04081c (diff) | |
download | FreeBSD-src-c3a2e02803a9c8498b9d463374d0a78a037c4a57.zip FreeBSD-src-c3a2e02803a9c8498b9d463374d0a78a037c4a57.tar.gz |
Some fixes to the current RMI interrupt handling, changes in this patch are:
- (cleanup) remove rmi specific 'struct mips_intrhand' - this is no
longer needed since 'struct intr_event' have all the required hooks
- add xlr_cpu_establish_hardintr, which has args for pre/post ithread
and filter hooks, so that the PCI code can add the PCI controller
interrupt ack code here
- make 'cpu_establish_hardintr' use the above function.
- (fix) change type of eirr/eimr from register_t to uint64_t. These
have to be 64bit otherwise we cannot handle interrupts from 32.
- (fix) use eimr to mask eirr before checking interrupts, so that we
will not handle masked interrupts.
Obtained from: C. Jayachandran - c.jayachandran@gmail.com
Diffstat (limited to 'sys/mips')
-rw-r--r-- | sys/mips/include/intr_machdep.h | 14 | ||||
-rw-r--r-- | sys/mips/rmi/interrupt.h | 12 | ||||
-rw-r--r-- | sys/mips/rmi/intr_machdep.c | 54 |
3 files changed, 45 insertions, 35 deletions
diff --git a/sys/mips/include/intr_machdep.h b/sys/mips/include/intr_machdep.h index 60e969d..575bba4 100644 --- a/sys/mips/include/intr_machdep.h +++ b/sys/mips/include/intr_machdep.h @@ -30,21 +30,7 @@ #define _MACHINE_INTR_MACHDEP_H_ #ifdef TARGET_XLR_XLS -/* - * XLR/XLS uses its own intr_machdep.c and has - * a different number of interupts. This probably - * should be placed somewhere else. - */ - -struct mips_intrhand { - struct intr_event *mih_event; - driver_intr_t *mih_disable; - volatile long *cntp; /* interrupt counter */ -}; - -extern struct mips_intrhand mips_intr_handlers[]; #define XLR_MAX_INTR 64 - #else #define NHARD_IRQS 6 #define NSOFT_IRQS 2 diff --git a/sys/mips/rmi/interrupt.h b/sys/mips/rmi/interrupt.h index 013a8e9..247dc9f 100644 --- a/sys/mips/rmi/interrupt.h +++ b/sys/mips/rmi/interrupt.h @@ -25,7 +25,7 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * + *__FBSDID("$FreeBSD$") * RMI_BSD */ #ifndef _RMI_INTERRUPT_H_ #define _RMI_INTERRUPT_H_ @@ -39,4 +39,14 @@ #define IRQ_MSGRING 6 #define IRQ_TIMER 7 +/* + * XLR needs custom pre and post handlers for PCI/PCI-e interrupts + * XXX: maybe follow i386 intsrc model + */ +void xlr_cpu_establish_hardintr(const char *, driver_filter_t *, + driver_intr_t *, void *, int, int, void **, void (*)(void *), + void (*)(void *), void (*)(void *), int (*)(void *, u_char)); +void xlr_mask_hard_irq(void *); +void xlr_unmask_hard_irq(void *); + #endif /* _RMI_INTERRUPT_H_ */ diff --git a/sys/mips/rmi/intr_machdep.c b/sys/mips/rmi/intr_machdep.c index c1bbe95..8785ac7 100644 --- a/sys/mips/rmi/intr_machdep.c +++ b/sys/mips/rmi/intr_machdep.c @@ -51,19 +51,19 @@ __FBSDID("$FreeBSD$"); /*#include <machine/intrcnt.h>*/ static mips_intrcnt_t mips_intr_counters[XLR_MAX_INTR]; -struct mips_intrhand mips_intr_handlers[XLR_MAX_INTR]; +static struct intr_event *mips_intr_events[XLR_MAX_INTR]; static int intrcnt_index; -static void -mips_mask_hard_irq(void *source) +void +xlr_mask_hard_irq(void *source) { uintptr_t irq = (uintptr_t) source; write_c0_eimr64(read_c0_eimr64() & ~(1ULL << irq)); } -static void -mips_unmask_hard_irq(void *source) +void +xlr_unmask_hard_irq(void *source) { uintptr_t irq = (uintptr_t) source; @@ -71,10 +71,11 @@ mips_unmask_hard_irq(void *source) } void -cpu_establish_hardintr(const char *name, driver_filter_t * filt, - void (*handler) (void *), void *arg, int irq, int flags, void **cookiep) +xlr_cpu_establish_hardintr(const char *name, driver_filter_t * filt, + void (*handler) (void *), void *arg, int irq, int flags, void **cookiep, + void (*pre_ithread)(void *), void (*post_ithread)(void *), + void (*post_filter)(void *), int (*assign_cpu)(void *, u_char)) { - struct mips_intrhand *mih; /* descriptor for the IRQ */ struct intr_event *ie; /* descriptor for the IRQ */ int errcode; @@ -85,25 +86,33 @@ cpu_establish_hardintr(const char *name, driver_filter_t * filt, * FIXME locking - not needed now, because we do this only on * startup from CPU0 */ - mih = &mips_intr_handlers[irq]; + ie = mips_intr_events[irq]; /* mih->cntp = &intrcnt[irq]; */ - ie = mih->mih_event; if (ie == NULL) { errcode = intr_event_create(&ie, (void *)(uintptr_t) irq, 0, - irq, mips_mask_hard_irq, mips_unmask_hard_irq, - NULL, NULL, "hard intr%d:", irq); + irq, pre_ithread, post_ithread, post_filter, assign_cpu, + "hard intr%d:", irq); if (errcode) { printf("Could not create event for intr %d\n", irq); return; } + mips_intr_events[irq] = ie; } + intr_event_add_handler(ie, name, filt, handler, arg, intr_priority(flags), flags, cookiep); - mih->mih_event = ie; - mips_unmask_hard_irq((void *)(uintptr_t) irq); + xlr_unmask_hard_irq((void *)(uintptr_t) irq); } +void +cpu_establish_hardintr(const char *name, driver_filter_t * filt, + void (*handler) (void *), void *arg, int irq, int flags, void **cookiep) +{ + xlr_cpu_establish_hardintr(name, filt, handler, arg, irq, + flags, cookiep, xlr_mask_hard_irq, xlr_unmask_hard_irq, + NULL, NULL); +} void cpu_establish_softintr(const char *name, driver_filter_t * filt, @@ -111,20 +120,26 @@ cpu_establish_softintr(const char *name, driver_filter_t * filt, void **cookiep) { /* we don't separate them into soft/hard like other mips */ - cpu_establish_hardintr(name, filt, handler, arg, irq, flags, cookiep); + xlr_cpu_establish_hardintr(name, filt, handler, arg, irq, + flags, cookiep, xlr_mask_hard_irq, xlr_unmask_hard_irq, + NULL, NULL); } void cpu_intr(struct trapframe *tf) { - struct mips_intrhand *mih; struct intr_event *ie; - register_t eirr; + uint64_t eirr, eimr; int i; critical_enter(); + + /* find a list of enabled interrupts */ eirr = read_c0_eirr64(); - if (eirr == 0) { + eimr = read_c0_eimr64(); + eirr &= eimr; + + if (eirr == 0) { critical_exit(); return; } @@ -162,9 +177,8 @@ cpu_intr(struct trapframe *tf) } #endif #endif - mih = &mips_intr_handlers[i]; + ie = mips_intr_events[i]; /* atomic_add_long(mih->cntp, 1); */ - ie = mih->mih_event; write_c0_eirr64(1ULL << i); pic_ack(i, 0); |