summaryrefslogtreecommitdiffstats
path: root/sys/mips
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2010-02-20 16:30:29 +0000
committerrrs <rrs@FreeBSD.org>2010-02-20 16:30:29 +0000
commitc3a2e02803a9c8498b9d463374d0a78a037c4a57 (patch)
treed1f56abf0589eb2bade888e5ee80ccc8890df5c7 /sys/mips
parent238d0be5d06d3c6bd1f038e62fdbe89fec04081c (diff)
downloadFreeBSD-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.h14
-rw-r--r--sys/mips/rmi/interrupt.h12
-rw-r--r--sys/mips/rmi/intr_machdep.c54
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);
OpenPOWER on IntegriCloud