Subject: ibm4xx interrupts
To: None <port-powerpc@netbsd.org>
From: Jachym Holecek <freza@dspfpga.com>
List: port-powerpc
Date: 06/27/2006 01:55:23
Hello,
the diff below converts ibm4xx to:
* generic soft interrupts
* evcnt interrupt counters (cpu_info evcnts used where applicable)
* more flexible interrupt code layout, so that slighly different
intr controllers, like Xilinx XINTC, may be supported easily
Included are changes needed to compile all affected evbppc kernels.
The change was successfully tested on a Walnut (thanks simonb@).
Unless there are objections/problems, I'd like to commit in a few days.
It would also be good to hear how this works on !Walnut boards.
Thanks,
-- Jachym
Index: arch/powerpc/ibm4xx/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/ibm4xx/clock.c,v
retrieving revision 1.16
diff -d -p -u -r1.16 clock.c
--- arch/powerpc/ibm4xx/clock.c 5 May 2006 18:04:42 -0000 1.16
+++ arch/powerpc/ibm4xx/clock.c 26 Jun 2006 23:39:00 -0000
@@ -72,10 +72,8 @@ void stat_intr(struct clockframe *); /*
void
stat_intr(struct clockframe *frame)
{
- extern u_long intrcnt[];
-
mtspr(SPR_TSR, TSR_FIS); /* Clear TSR[FIS] */
- intrcnt[CNT_STATCLOCK]++;
+ curcpu()->ci_ev_statclock.ev_count++;
statclock(frame);
}
@@ -85,7 +83,7 @@ decr_intr(struct clockframe *frame)
int pri;
long tbtick, xticks;
int nticks;
- extern u_long intrcnt[];
+
/*
* Check whether we are initialized.
*/
@@ -100,11 +98,11 @@ decr_intr(struct clockframe *frame)
xticks -= ticks_per_intr;
lasttb2 = tbtick - xticks;
- intrcnt[CNT_CLOCK]++;
+ curcpu()->ci_ev_clock.ev_count++;
pri = splclock();
- if (pri & SPL_CLOCK) {
+ if (pri & mask_clock) {
tickspending += nticks;
- ticksmissed+= nticks;
+ ticksmissed += nticks;
} else {
nticks += tickspending;
tickspending = 0;
@@ -124,7 +122,7 @@ decr_intr(struct clockframe *frame)
* Do standard timer interrupt stuff.
* Do softclock stuff only on the last iteration.
*/
- frame->pri = pri | SINT_CLOCK;
+ frame->pri = pri | mask_clock;
while (--nticks > 0)
hardclock(frame);
frame->pri = pri;
@@ -136,12 +134,19 @@ decr_intr(struct clockframe *frame)
void
cpu_initclocks(void)
{
+ /* Initialized in powerpc/ibm4xx/cpu.c */
+ evcnt_attach_static(&curcpu()->ci_ev_clock);
+ evcnt_attach_static(&curcpu()->ci_ev_statclock);
ticks_per_intr = ticks_per_sec / hz;
stathz = profhz = ticks_per_sec / (1 << PERIOD_POWER);
- printf("Setting PIT to %ld/%d = %ld\n", ticks_per_sec, hz, ticks_per_intr);
+
+ printf("Setting PIT to %ld/%d = %ld\n", ticks_per_sec, hz,
+ ticks_per_intr);
+
lasttb2 = lasttb = mftbl();
mtspr(SPR_PIT, ticks_per_intr);
+
/* Enable PIT & FIT(2^17c = 0.655ms) interrupts and auto-reload */
mtspr(SPR_TCR, TCR_PIE | TCR_ARE | TCR_FIE | TCR_PERIOD);
}
Index: arch/powerpc/ibm4xx/cpu.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/ibm4xx/cpu.c,v
retrieving revision 1.23
diff -d -p -u -r1.23 cpu.c
--- arch/powerpc/ibm4xx/cpu.c 5 May 2006 18:04:42 -0000 1.23
+++ arch/powerpc/ibm4xx/cpu.c 26 Jun 2006 23:39:00 -0000
@@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.23
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <sys/evcnt.h>
#include <uvm/uvm_extern.h>
@@ -75,7 +76,21 @@ CFATTACH_DECL(cpu, sizeof(struct device)
int ncpus;
-struct cpu_info cpu_info[1];
+struct cpu_info cpu_info[1] = {
+ {
+ /* XXX add more ci_ev_* as we teach 4xx about them */
+ .ci_ev_clock = EVCNT_INITIALIZER(EVCNT_TYPE_INTR,
+ NULL, "cpu0", "clock"),
+ .ci_ev_statclock = EVCNT_INITIALIZER(EVCNT_TYPE_INTR,
+ NULL, "cpu0", "stat clock"),
+ .ci_ev_softclock = EVCNT_INITIALIZER(EVCNT_TYPE_INTR,
+ NULL, "cpu0", "soft clock"),
+ .ci_ev_softnet = EVCNT_INITIALIZER(EVCNT_TYPE_INTR,
+ NULL, "cpu0", "soft net"),
+ .ci_ev_softserial = EVCNT_INITIALIZER(EVCNT_TYPE_INTR,
+ NULL, "cpu0", "soft serial"),
+ }
+};
char cpu_model[80];
Index: arch/powerpc/ibm4xx/intr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/ibm4xx/intr.c,v
retrieving revision 1.11
diff -d -p -u -r1.11 intr.c
--- arch/powerpc/ibm4xx/intr.c 13 Jun 2006 18:24:37 -0000 1.11
+++ arch/powerpc/ibm4xx/intr.c 26 Jun 2006 23:39:01 -0000
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.c,v 1.11 2006/06/13 18:24:37 freza Exp $ */
+/* $NetBSD: intr.c,v 1.10 2005/12/24 22:45:36 perry Exp $ */
/*
* Copyright 2002 Wasabi Systems, Inc.
@@ -36,20 +36,49 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.11 2006/06/13 18:24:37 freza Exp $");
+__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.10 2005/12/24 22:45:36 perry Exp $");
#include <sys/param.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
+#include <sys/evcnt.h>
#include <uvm/uvm_extern.h>
-#include <machine/cpu.h>
#include <machine/intr.h>
#include <machine/psl.h>
+#include <powerpc/cpu.h>
#include <powerpc/spr.h>
+#include <powerpc/softintr.h>
+
+/*
+ * Number of interrupts (hard + soft), irq number legality test,
+ * mapping of irq number to mask and a way to pick irq number
+ * off a mask of active intrs.
+ */
+#define ICU_LEN 32
+#define LEGAL_IRQ(x) ((x) >= 0 && (x) < ICU_LEN)
+
+#define IRQ_TO_MASK(irq) (0x80000000UL >> (irq))
+#define IRQ_OF_MASK(mask) cntlzw(mask)
+
+/*
+ * Assign these to unused (reserved) interrupt bits.
+ *
+ * For 405GP (and 403CGX?) interrupt bits 0-18 and 25-31 are used
+ * by hardware. This leaves us bits 19-24 for software.
+ */
+#define IRQ_SOFTNET 19
+#define IRQ_SOFTCLOCK 20
+#define IRQ_SOFTSERIAL 21
+#define IRQ_CLOCK 22
+#define IRQ_STATCLOCK 23
+
+/*
+ * Platform specific code may override any of the above.
+ */
#ifdef PPC_IBM403
#include <powerpc/ibm4xx/dcr403cgx.h>
#define INTR_STATUS DCR_EXISR
@@ -62,27 +91,75 @@ __KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.1
#define INTR_ENABLE DCR_UIC0_ER
#endif
+#define MASK_SOFTNET IRQ_TO_MASK(IRQ_SOFTNET)
+#define MASK_SOFTCLOCK IRQ_TO_MASK(IRQ_SOFTCLOCK)
+#define MASK_SOFTSERIAL IRQ_TO_MASK(IRQ_SOFTSERIAL)
+#define MASK_CLOCK (IRQ_TO_MASK(IRQ_CLOCK) | IRQ_TO_MASK(IRQ_STATCLOCK))
+#define MASK_SOFTINTR (MASK_SOFTCLOCK|MASK_SOFTNET|MASK_SOFTSERIAL)
+#define MASK_HARDINTR ~(MASK_SOFTINTR|MASK_CLOCK)
+
static inline void disable_irq(int irq);
static inline void enable_irq(int irq);
static void intr_calculatemasks(void);
+static void do_pending_int(void);
static const char *intr_typename(int);
-static int fakeintr(void *);
+/*
+ * Interrupt handler chains. intr_establish() inserts a handler into
+ * the list. The handler is called with its (single) argument.
+ */
+struct intrhand {
+ int (*ih_fun)(void *);
+ void *ih_arg;
+ struct intrhand *ih_next;
+ int ih_level;
+};
-volatile int cpl, ipending;
-u_long imask[NIPL];
+struct intrsrc {
+ struct evcnt is_evcnt;
+ struct intrhand *is_head;
+ u_int is_mask;
+ int is_level; /* spls bitmask */
+ int is_type; /* sensitivity */
+};
-static int intrtype[ICU_LEN], intrmask[ICU_LEN], intrlevel[ICU_LEN];
-static struct intrhand *intrhand[ICU_LEN];
+volatile u_int imask[NIPL];
+const int mask_clock = MASK_CLOCK;
-static int
-fakeintr(void *arg)
-{
+static struct intrsrc intrs[ICU_LEN] = {
+#define DEFINTR(name) \
+ { EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "uic", name), NULL, 0, 0 }
- return 0;
-}
+ DEFINTR("pin0"), DEFINTR("pin1"), DEFINTR("pin2"),
+ DEFINTR("pin3"), DEFINTR("pin4"), DEFINTR("pin5"),
+ DEFINTR("pin6"), DEFINTR("pin7"), DEFINTR("pin8"),
+ DEFINTR("pin9"), DEFINTR("pin10"), DEFINTR("pin11"),
+ DEFINTR("pin12"), DEFINTR("pin13"), DEFINTR("pin14"),
+ DEFINTR("pin15"), DEFINTR("pin16"), DEFINTR("pin17"),
+ DEFINTR("pin18"),
+
+ /* Reserved intrs, accounted in cpu_info */
+ DEFINTR(NULL), /* unused "pin19", softnet */
+ DEFINTR(NULL), /* unused "pin20", softclock */
+ DEFINTR(NULL), /* unused "pin21", softserial */
+ DEFINTR(NULL), /* unused "pin22", PIT hardclock */
+ DEFINTR(NULL), /* unused "pin23", FIT statclock */
+
+ DEFINTR("pin24"), DEFINTR("pin25"), DEFINTR("pin26"),
+ DEFINTR("pin27"), DEFINTR("pin28"), DEFINTR("pin29"),
+ DEFINTR("pin30"), DEFINTR("pin31")
+
+#undef DEFINTR
+};
+
+
+/* Write External Enable Immediate */
+#define wrteei(en) __asm volatile ("wrteei %0" : : "K"(en))
+
+/* Enforce In Order Execution Of I/O */
+#define eieio() __asm volatile ("eieio")
/*
* Set up interrupt mapping array.
@@ -90,7 +167,33 @@ fakeintr(void *arg)
void
intr_init(void)
{
+ struct cpu_info *ci = curcpu();
+ int i;
+ for (i = 0; i < ICU_LEN; i++)
+ switch (i) {
+ case IRQ_SOFTNET:
+ case IRQ_SOFTCLOCK:
+ case IRQ_SOFTSERIAL:
+ case IRQ_CLOCK:
+ case IRQ_STATCLOCK:
+ continue;
+ default:
+ evcnt_attach_static(&intrs[i].is_evcnt);
+ }
+
+ /* Initialized in powerpc/ibm4xx/cpu.c */
+ evcnt_attach_static(&ci->ci_ev_softclock);
+ evcnt_attach_static(&ci->ci_ev_softnet);
+ evcnt_attach_static(&ci->ci_ev_softserial);
+
+ softintr__init();
+
+ mtdcr(INTR_ENABLE, 0x00000000); /* mask all */
+ mtdcr(INTR_ACK, 0xffffffff); /* acknowledge all */
+#ifdef INTR_MASTER
+ mtdcr(INTR_MASTER, 0xffffffff); /* enable controller */
+#endif
}
/*
@@ -99,48 +202,52 @@ intr_init(void)
void
ext_intr(void)
{
- int i, bits_to_clear;
- int r_imen, msr;
- int pcpl;
- struct intrhand *ih;
- u_long int_state;
+ struct cpu_info *ci = curcpu();
+ struct intrhand *ih;
+ int i, bits_to_clear;
+ int r_imen, msr;
+ int pcpl;
+ u_long int_state;
- pcpl = cpl;
- __asm volatile ("mfmsr %0" : "=r"(msr));
+ pcpl = ci->ci_cpl;
+ msr = mfmsr();
int_state = mfdcr(INTR_STATUS); /* Read non-masked interrupt status */
bits_to_clear = int_state;
while (int_state) {
- i = cntlzw(int_state);
- int_state &= ~IRQ_TO_MASK(i);
+ i = IRQ_OF_MASK(int_state);
r_imen = IRQ_TO_MASK(i);
+ int_state &= ~r_imen;
if ((pcpl & r_imen) != 0) {
- ipending |= r_imen; /* Masked! Mark this as pending */
+ /* Masked! Mark as pending */
+ ci->ci_ipending |= r_imen;
disable_irq(i);
} else {
- splraise(intrmask[i]);
- __asm volatile ("mtmsr %0" :: "r"(msr | PSL_EE));
+ splraise(intrs[i].is_mask);
+ wrteei(1);
+
KERNEL_LOCK(LK_CANRECURSE|LK_EXCLUSIVE);
- ih = intrhand[i];
+ ih = intrs[i].is_head;
while (ih) {
(*ih->ih_fun)(ih->ih_arg);
ih = ih->ih_next;
}
KERNEL_UNLOCK();
- __asm volatile ("mtmsr %0" :: "r"(msr));
- cpl = pcpl;
+
+ mtmsr(msr);
+ ci->ci_cpl = pcpl;
uvmexp.intrs++;
- intrcnt[i]++;
+ intrs[i].is_evcnt.ev_count++;
}
}
mtdcr(INTR_ACK, bits_to_clear); /* Acknowledge all pending interrupts */
- __asm volatile ("mtmsr %0" :: "r"(msr | PSL_EE));
+ wrteei(1);
splx(pcpl);
- __asm volatile ("mtmsr %0" :: "r"(msr));
+ mtmsr(msr);
}
static inline void
@@ -195,60 +302,61 @@ intr_typename(int type)
* Register an interrupt handler.
*/
void *
-intr_establish(int irq, int type, int level, int (*ih_fun)(void *), void *ih_arg)
+intr_establish(int irq, int type, int level, int (*ih_fun)(void *),
+ void *ih_arg)
{
- struct intrhand **p, *q, *ih;
- static struct intrhand fakehand = { fakeintr };
+ struct intrhand *ih;
+ int s;
- /* no point in sleeping unless someone can free memory. */
+ if (! LEGAL_IRQ(irq))
+ panic("intr_establish: bogus irq %d", irq);
+
+ if (type == IST_NONE)
+ panic("intr_establish: bogus type %d for irq %d", type, irq);
+
+ /* No point in sleeping unless someone can free memory. */
ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
if (ih == NULL)
panic("intr_establish: can't malloc handler info");
- if (!LEGAL_IRQ(irq) || type == IST_NONE)
- panic("intr_establish: bogus irq or type");
+ switch (intrs[irq].is_type) {
+ case IST_NONE:
+ intrs[irq].is_type = type;
+ break;
- switch (intrtype[irq]) {
case IST_EDGE:
case IST_LEVEL:
- if (type == intrtype[irq])
+ if (type == intrs[irq].is_type)
break;
+ /* FALLTHROUGH */
+
case IST_PULSE:
if (type != IST_NONE)
panic("intr_establish: can't share %s with %s",
- intr_typename(intrtype[irq]),
+ intr_typename(intrs[irq].is_type),
intr_typename(type));
break;
}
/*
- * Figure out where to put the handler.
- * This is O(N^2), but we want to preserve the order, and N is
- * generally small.
- */
- for (p = &intrhand[irq]; (q = *p) != NULL; p = &q->ih_next)
- ;
-
- /*
- * Actually install a fake handler momentarily, since we might be doing
- * this with interrupts enabled and don't want the real routine called
- * until masking is set up.
+ * We're not on critical paths, so just block intrs for a while.
*/
- fakehand.ih_level = level;
- *p = &fakehand;
-
+ s = splhigh();
intr_calculatemasks();
/*
- * Poke the real handler in now.
+ * Poke the real handler in now. We deliberately don't preserve order,
+ * the user is not allowed to make any assumptions about it anyway.
*/
ih->ih_fun = ih_fun;
ih->ih_arg = ih_arg;
- ih->ih_count = 0;
- ih->ih_next = NULL;
ih->ih_level = level;
- ih->ih_irq = irq;
- *p = ih;
+ ih->ih_next = intrs[irq].is_head;
+ intrs[irq].is_head = ih;
+
+ eieio();
+ splx(s);
+
#ifdef IRQ_DEBUG
printf("***** intr_establish: irq%d h=%p arg=%p\n",irq, ih_fun, ih_arg);
#endif
@@ -261,29 +369,28 @@ intr_establish(int irq, int type, int le
void
intr_disestablish(void *arg)
{
- struct intrhand *ih = arg;
- int irq = ih->ih_irq;
- struct intrhand **p, *q;
-
- if (!LEGAL_IRQ(irq))
- panic("intr_disestablish: bogus irq");
+ struct intrhand *ih = arg;
+ struct intrhand **p;
+ int i, s;
- /*
- * Remove the handler from the chain.
- * This is O(n^2), too.
- */
- for (p = &intrhand[irq]; (q = *p) != NULL && q != ih; p = &q->ih_next)
- ;
- if (q)
- *p = q->ih_next;
- else
+ /* Lookup the handler. This is expensive, but not run often. */
+ for (i = 0; i < ICU_LEN; i++)
+ for (p = &intrs[i].is_head; *p != NULL; p = &(*p)->ih_next)
+ if (*p == ih)
+ goto out;
+ out:
+ if (i == ICU_LEN)
panic("intr_disestablish: handler not registered");
- free((void *)ih, M_DEVBUF);
+ *p = ih->ih_next;
+ free(ih, M_DEVBUF);
+
+ s = splhigh();
intr_calculatemasks();
+ splx(s);
- if (intrhand[irq] == NULL)
- intrtype[irq] = IST_NONE;
+ if (intrs[i].is_head == NULL)
+ intrs[i].is_type = IST_NONE;
}
/*
@@ -301,32 +408,32 @@ intr_calculatemasks(void)
/* First, figure out which levels each IRQ uses. */
for (irq = 0; irq < ICU_LEN; irq++) {
register int levels = 0;
- for (q = intrhand[irq]; q; q = q->ih_next)
+ for (q = intrs[irq].is_head; q; q = q->ih_next)
levels |= 1 << q->ih_level;
- intrlevel[irq] = levels;
+ intrs[irq].is_level = levels;
}
/* Then figure out which IRQs use each level. */
for (level = 0; level < NIPL; level++) {
register int irqs = 0;
for (irq = 0; irq < ICU_LEN; irq++)
- if (intrlevel[irq] & (1 << level))
+ if (intrs[irq].is_level & (1 << level))
irqs |= IRQ_TO_MASK(irq);
- imask[level] = irqs | SINT_MASK;
+ imask[level] = irqs | MASK_SOFTINTR;
}
/*
* IPL_CLOCK should mask clock interrupt even if interrupt handler
* is not registered.
*/
- imask[IPL_CLOCK] |= SPL_CLOCK;
+ imask[IPL_CLOCK] |= MASK_CLOCK;
/*
* Initialize the soft interrupt masks to block themselves.
*/
- imask[IPL_SOFTCLOCK] = SINT_CLOCK;
- imask[IPL_SOFTNET] = SINT_NET;
- imask[IPL_SOFTSERIAL] = SINT_SERIAL;
+ imask[IPL_SOFTCLOCK] = MASK_SOFTCLOCK;
+ imask[IPL_SOFTNET] = MASK_SOFTNET;
+ imask[IPL_SOFTSERIAL] = MASK_SOFTSERIAL;
/*
* IPL_NONE is used for hardware interrupts that are never blocked,
@@ -373,95 +480,170 @@ intr_calculatemasks(void)
/* And eventually calculate the complete masks. */
for (irq = 0; irq < ICU_LEN; irq++) {
register int irqs = IRQ_TO_MASK(irq);
- for (q = intrhand[irq]; q; q = q->ih_next)
+ for (q = intrs[irq].is_head; q; q = q->ih_next)
irqs |= imask[q->ih_level];
- intrmask[irq] = irqs;
+ intrs[irq].is_mask = irqs;
}
for (irq = 0; irq < ICU_LEN; irq++)
- if (intrhand[irq])
+ if (intrs[irq].is_head != NULL)
enable_irq(irq);
else
disable_irq(irq);
}
-void
+static void
do_pending_int(void)
{
- struct intrhand *ih;
- int irq;
- int pcpl;
- int hwpend;
- int emsr, dmsr;
- static int processing;
+ struct cpu_info *ci = curcpu();
+ struct intrhand *ih;
+ int irq;
+ int pcpl;
+ int hwpend;
+ int emsr;
- if (processing)
+ if (ci->ci_iactive)
return;
- processing = 1;
- __asm volatile("mfmsr %0" : "=r"(emsr));
- dmsr = emsr & ~PSL_EE;
- __asm volatile("mtmsr %0" :: "r"(dmsr));
+ ci->ci_iactive = 1;
+ emsr = mfmsr();
+ wrteei(0);
- pcpl = cpl; /* Turn off all */
+ pcpl = ci->ci_cpl; /* Turn off all */
again:
- while ((hwpend = ipending & ~pcpl & HWINT_MASK)) {
- irq = cntlzw(hwpend);
+ while ((hwpend = ci->ci_ipending & ~pcpl & MASK_HARDINTR) != 0) {
+ irq = IRQ_OF_MASK(hwpend);
enable_irq(irq);
- ipending &= ~IRQ_TO_MASK(irq);
+ ci->ci_ipending &= ~IRQ_TO_MASK(irq);
+
+ splraise(intrs[irq].is_mask);
+ mtmsr(emsr);
- splraise(intrmask[irq]);
- __asm volatile("mtmsr %0" :: "r"(emsr));
KERNEL_LOCK(LK_CANRECURSE|LK_EXCLUSIVE);
- ih = intrhand[irq];
+ ih = intrs[irq].is_head;
while(ih) {
(*ih->ih_fun)(ih->ih_arg);
ih = ih->ih_next;
}
KERNEL_UNLOCK();
- __asm volatile("mtmsr %0" :: "r"(dmsr));
- cpl = pcpl;
- intrcnt[irq]++;
+
+ wrteei(0);
+ ci->ci_cpl = pcpl;
+ intrs[irq].is_evcnt.ev_count++;
}
- if ((ipending & ~pcpl) & SINT_SERIAL) {
- ipending &= ~SINT_SERIAL;
+ if ((ci->ci_ipending & ~pcpl) & MASK_SOFTSERIAL) {
+ ci->ci_ipending &= ~MASK_SOFTSERIAL;
splsoftserial();
- __asm volatile("mtmsr %0" :: "r"(emsr));
+ mtmsr(emsr);
+
KERNEL_LOCK(LK_CANRECURSE|LK_EXCLUSIVE);
- softserial();
+ softintr__run(IPL_SOFTSERIAL);
KERNEL_UNLOCK();
- __asm volatile("mtmsr %0" :: "r"(dmsr));
- cpl = pcpl;
- intrcnt[CNT_SINT_SERIAL]++;
+
+ wrteei(0);
+ ci->ci_cpl = pcpl;
+ ci->ci_ev_softserial.ev_count++;
goto again;
}
- if ((ipending & ~pcpl) & SINT_NET) {
- ipending &= ~SINT_NET;
+ if ((ci->ci_ipending & ~pcpl) & MASK_SOFTNET) {
+ ci->ci_ipending &= ~MASK_SOFTNET;
splsoftnet();
- __asm volatile("mtmsr %0" :: "r"(emsr));
+ mtmsr(emsr);
+
KERNEL_LOCK(LK_CANRECURSE|LK_EXCLUSIVE);
- softnet();
+ softintr__run(IPL_SOFTNET);
KERNEL_UNLOCK();
- __asm volatile("mtmsr %0" :: "r"(dmsr));
- cpl = pcpl;
- intrcnt[CNT_SINT_NET]++;
+
+ wrteei(0);
+ ci->ci_cpl = pcpl;
+ ci->ci_ev_softnet.ev_count++;
goto again;
}
- if ((ipending & ~pcpl) & SINT_CLOCK) {
- ipending &= ~SINT_CLOCK;
+ if ((ci->ci_ipending & ~pcpl) & MASK_SOFTCLOCK) {
+ ci->ci_ipending &= ~MASK_SOFTCLOCK;
splsoftclock();
- __asm volatile("mtmsr %0" :: "r"(emsr));
+ mtmsr(emsr);
+
KERNEL_LOCK(LK_CANRECURSE|LK_EXCLUSIVE);
- softclock(NULL);
+ softintr__run(IPL_SOFTCLOCK);
KERNEL_UNLOCK();
- __asm volatile("mtmsr %0" :: "r"(dmsr));
- cpl = pcpl;
- intrcnt[CNT_SINT_CLOCK]++;
+
+ wrteei(0);
+ ci->ci_cpl = pcpl;
+ ci->ci_ev_softclock.ev_count++;
goto again;
}
- cpl = pcpl; /* Don't use splx... we are here already! */
- __asm volatile("mtmsr %0" :: "r"(emsr));
- processing = 0;
+ ci->ci_cpl = pcpl; /* Don't use splx... we are here already! */
+ mtmsr(emsr);
+ ci->ci_iactive = 0;
+}
+
+void
+softintr(int idx)
+{
+ static const int softmap[3] = {
+ MASK_SOFTCLOCK, MASK_SOFTNET, MASK_SOFTSERIAL
+ };
+ struct cpu_info *ci = curcpu();
+ int oldmsr;
+
+ /*
+ * This could be implemented with lwarx/stwcx to avoid the
+ * disable/enable... Note softintr() is only ever called
+ * with constant 0, 1, 2 as argument, no need to check.
+ */
+
+ oldmsr = mfmsr();
+ wrteei(0);
+
+ ci->ci_ipending |= softmap[idx];
+
+ mtmsr(oldmsr);
+}
+
+int
+splraise(int newcpl)
+{
+ struct cpu_info *ci = curcpu();
+ int oldcpl, oldmsr;
+
+ /*
+ * We're about to block some intrs, so make sure they don't
+ * fire while we're busy.
+ */
+
+ oldmsr = mfmsr();
+ wrteei(0);
+
+ oldcpl = ci->ci_cpl;
+ ci->ci_cpl |= newcpl;
+
+ mtmsr(oldmsr);
+ return (oldcpl);
+}
+
+void
+splx(int newcpl)
+{
+ struct cpu_info *ci = curcpu();
+
+ ci->ci_cpl = newcpl;
+ if (ci->ci_ipending & ~newcpl)
+ do_pending_int();
+}
+
+int
+spllower(int newcpl)
+{
+ struct cpu_info *ci = curcpu();
+ int oldcpl;
+
+ oldcpl = ci->ci_cpl;
+ ci->ci_cpl = newcpl;
+ if (ci->ci_ipending & ~newcpl)
+ do_pending_int();
+
+ return (oldcpl);
}
Index: arch/powerpc/ibm4xx/pci/pci_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/ibm4xx/pci/pci_machdep.c,v
retrieving revision 1.4
diff -d -p -u -r1.4 pci_machdep.c
--- arch/powerpc/ibm4xx/pci/pci_machdep.c 29 Mar 2006 17:50:33 -0000 1.4
+++ arch/powerpc/ibm4xx/pci/pci_machdep.c 26 Jun 2006 23:39:02 -0000
@@ -165,8 +165,8 @@ pci_intr_string(pci_chipset_tag_t pc, pc
{
static char irqstr[8]; /* 4 + 2 + NUL + sanity */
- if (ih == 0 || ih >= ICU_LEN)
- panic("pci_intr_string: bogus handle 0x%x", ih);
+ if (ih < 0 || ih > 99)
+ panic("pci_intr_string: handle %#x won't fit two digits", ih);
sprintf(irqstr, "irq %d", ih);
return (irqstr);
@@ -185,10 +185,6 @@ void *
pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level,
int (*func)(void *), void *arg)
{
-
- if (ih == 0 || ih >= ICU_LEN)
- panic("pci_intr_establish: bogus handle 0x%x", ih);
-
return intr_establish(ih, IST_LEVEL, level, func, arg);
}
Index: arch/powerpc/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/include/cpu.h,v
retrieving revision 1.49
diff -d -p -u -r1.49 cpu.h
--- arch/powerpc/include/cpu.h 13 Jun 2006 18:24:37 -0000 1.49
+++ arch/powerpc/include/cpu.h 26 Jun 2006 23:39:03 -0000
@@ -72,9 +72,9 @@ struct cpu_info {
int ci_want_resched;
volatile u_long ci_lasttb;
volatile int ci_tickspending;
- int ci_cpl;
- int ci_iactive;
- int ci_ipending;
+ volatile int ci_cpl;
+ volatile int ci_iactive;
+ volatile int ci_ipending;
int ci_intrdepth;
char *ci_intstk;
#define CPUSAVE_LEN 8
@@ -96,6 +96,7 @@ struct cpu_info {
void (*ci_idlespin)(void);
uint32_t ci_khz;
struct evcnt ci_ev_clock; /* clock intrs */
+ struct evcnt ci_ev_statclock; /* stat clock */
struct evcnt ci_ev_softclock; /* softclock intrs */
struct evcnt ci_ev_softnet; /* softnet intrs */
struct evcnt ci_ev_softserial; /* softserial intrs */
Index: arch/powerpc/include/ibm4xx/ibm4xx_intr.h
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/include/ibm4xx/ibm4xx_intr.h,v
retrieving revision 1.11
diff -d -p -u -r1.11 ibm4xx_intr.h
--- arch/powerpc/include/ibm4xx/ibm4xx_intr.h 31 Dec 2005 14:07:32 -0000 1.11
+++ arch/powerpc/include/ibm4xx/ibm4xx_intr.h 26 Jun 2006 23:39:03 -0000
@@ -36,8 +36,10 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _EVBPPC_INTR_H_
-#define _EVBPPC_INTR_H_
+#ifndef _IBM4XX_INTR_H_
+#define _IBM4XX_INTR_H_
+
+#include <powerpc/softintr.h>
/* Interrupt priority `levels'. */
#define IPL_NONE 9 /* nothing */
@@ -67,134 +69,29 @@
#ifndef _LOCORE
#define CLKF_BASEPRI(frame) ((frame)->pri == 0)
-/*
- * Interrupt handler chains. intr_establish() inserts a handler into
- * the list. The handler is called with its (single) argument.
- */
-struct intrhand {
- int (*ih_fun)(void *);
- void *ih_arg;
- u_long ih_count;
- struct intrhand *ih_next;
- int ih_level;
- int ih_irq;
-};
-void setsoftclock(void);
-void setsoftnet(void);
-
-void do_pending_int(void);
-void ext_intr(void);
-void *intr_establish(int, int, int, int (*)(void *), void *);
-void intr_disestablish(void *);
-void intr_init(void);
-
-static inline int splraise(int);
-static inline int spllower(int);
-static inline void splx(int);
-static inline void set_sint(int);
-
-extern volatile int cpl, ipending, astpending;
-extern u_long imask[];
-extern u_long intrcnt[];
-
-/*
- * Reorder protection in the following inline functions is
- * achived with the "eieio" instruction which the assembler
- * seems to detect and then doesn't move instructions past....
- */
-static inline int
-splraise(newcpl)
- int newcpl;
-{
- int oldcpl;
-
- __asm volatile("sync; eieio\n"); /* don't reorder.... */
- oldcpl = cpl;
- cpl = oldcpl | newcpl;
- __asm volatile("sync; eieio\n"); /* reorder protect */
- return(oldcpl);
-}
-
-static inline void
-splx(newcpl)
- int newcpl;
-{
- __asm volatile("sync; eieio\n"); /* reorder protect */
- cpl = newcpl;
- if (ipending & ~newcpl)
- do_pending_int();
- __asm volatile("sync; eieio\n"); /* reorder protect */
-}
-
-static inline int
-spllower(newcpl)
- int newcpl;
-{
- int oldcpl;
-
- __asm volatile("sync; eieio\n"); /* reorder protect */
- oldcpl = cpl;
- cpl = newcpl;
- if (ipending & ~newcpl)
- do_pending_int();
- __asm volatile("sync; eieio\n"); /* reorder protect */
- return(oldcpl);
-}
-
-/* Following code should be implemented with lwarx/stwcx to avoid
- * the disable/enable. i need to read the manual once more.... */
-static inline void
-set_sint(pending)
- int pending;
-{
- int msrsave;
-
- __asm ("mfmsr %0" : "=r"(msrsave));
- __asm volatile ("mtmsr %0" :: "r"(msrsave & ~PSL_EE));
- ipending |= pending;
- __asm volatile ("mtmsr %0" :: "r"(msrsave));
-}
-
-#define ICU_LEN 32
-#define LEGAL_IRQ(x) ((x) >= 0 && (x) < ICU_LEN)
-#define IRQ_TO_MASK(x) (0x80000000UL >> (x))
-
-/*
- * XXX 405GP specific.
- * Interrupt bits 0-18 and 25-31 are used by hardware. This
- * leaves us bits 19-24 for software.
- */
-#define HWINT_MASK ~0x1fc0
-
-/* Assign these to unused (reserved) interrupt bits: */
-#define CNT_SINT_NET 19
-#define CNT_SINT_CLOCK 20
-#define CNT_SINT_SERIAL 21
-#define CNT_CLOCK 22
-#define CNT_STATCLOCK 23
-
-#define SINT_NET IRQ_TO_MASK(CNT_SINT_NET)
-#define SINT_CLOCK IRQ_TO_MASK(CNT_SINT_CLOCK)
-#define SINT_SERIAL IRQ_TO_MASK(CNT_SINT_SERIAL)
-#define SPL_CLOCK IRQ_TO_MASK(CNT_CLOCK)
-#define SINT_MASK (SINT_CLOCK|SINT_NET|SINT_SERIAL)
+void *intr_establish(int, int, int, int (*)(void *), void *);
+void intr_disestablish(void *);
+void intr_init(void);
+void ext_intr(void); /* for machdep */
+int splraise(int);
+int spllower(int);
+void splx(int);
+void softintr(int);
-#define spllowersoftclock() spllower(imask[IPL_SOFTCLOCK])
+extern volatile u_int imask[NIPL];
+extern const int mask_clock; /* for clock.c */
-#define splraiseipl(x) splraise(imask[x])
+#define spllowersoftclock() spllower(imask[IPL_SOFTCLOCK])
+#define splraiseipl(x) splraise(imask[x])
#include <sys/spl.h>
-#define setsoftclock() set_sint(SINT_CLOCK);
-#define setsoftnet() set_sint(SINT_NET);
-#define setsoftserial() set_sint(SINT_SERIAL);
-
-#define spl0() spllower(0)
+#define setsoftclock() softintr(0);
+#define setsoftnet() softintr(1);
+#define setsoftserial() softintr(2);
-void softnet(void);
-void softserial(void);
+#define spl0() spllower(0)
#endif /* !_LOCORE */
-
-#endif /* !_EVBPPC_INTR_H_ */
+#endif /* !_IBM4XX_INTR_H_ */
Index: arch/powerpc/marvell/marvell_intr.h
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/marvell/marvell_intr.h,v
retrieving revision 1.9
diff -d -p -u -r1.9 marvell_intr.h
--- arch/powerpc/marvell/marvell_intr.h 24 Dec 2005 20:07:28 -0000 1.9
+++ arch/powerpc/marvell/marvell_intr.h 26 Jun 2006 23:39:04 -0000
@@ -463,7 +463,6 @@ struct intrhand;
extern struct intrhand *softnet_handlers[];
#define schednetisr(an_isr) softintr_schedule(softnet_handlers[(an_isr)])
-#define __HAVE_GENERIC_SOFT_INTERRUPTS /* should be in <machine/types.h> */
void *softintr_establish(int level, void (*fun)(void *), void *arg);
void softintr_disestablish(void *cookie);
void softintr_schedule(void *cookie);
Index: arch/evbppc/conf/files.explora
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/conf/files.explora,v
retrieving revision 1.5
diff -d -p -u -r1.5 files.explora
--- arch/evbppc/conf/files.explora 11 Dec 2005 12:17:11 -0000 1.5
+++ arch/evbppc/conf/files.explora 26 Jun 2006 23:39:04 -0000
@@ -18,6 +18,7 @@ file arch/evbppc/explora/autoconf.c
file arch/evbppc/explora/consinit.c
file arch/evbppc/explora/machdep.c
file arch/powerpc/ibm4xx/intr.c
+file arch/powerpc/powerpc/softintr.c
file dev/md_root.c memory_disk_hooks
# Explora local bus
Index: arch/evbppc/conf/files.obs200
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/conf/files.obs200,v
retrieving revision 1.4
diff -d -p -u -r1.4 files.obs200
--- arch/evbppc/conf/files.obs200 15 May 2006 15:56:54 -0000 1.4
+++ arch/evbppc/conf/files.obs200 26 Jun 2006 23:39:04 -0000
@@ -7,6 +7,7 @@ file arch/powerpc/ibm4xx/ibm4xx_autoconf
file arch/powerpc/ibm4xx/ibm40x_machdep.c
file arch/powerpc/ibm4xx/ibm4xx_machdep.c
file arch/powerpc/ibm4xx/intr.c
+file arch/powerpc/powerpc/softintr.c
file arch/evbppc/obs405/dev/century_bios.c
file arch/evbppc/obs405/consinit.c
file arch/evbppc/obs405/obs200_autoconf.c
Index: arch/evbppc/conf/files.obs405
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/conf/files.obs405,v
retrieving revision 1.16
diff -d -p -u -r1.16 files.obs405
--- arch/evbppc/conf/files.obs405 15 May 2006 15:56:54 -0000 1.16
+++ arch/evbppc/conf/files.obs405 26 Jun 2006 23:39:04 -0000
@@ -6,6 +6,7 @@ file arch/powerpc/ibm4xx/ibm4xx_autoconf
file arch/powerpc/ibm4xx/ibm40x_machdep.c
file arch/powerpc/ibm4xx/ibm4xx_machdep.c
file arch/powerpc/ibm4xx/intr.c
+file arch/powerpc/powerpc/softintr.c
file arch/powerpc/ibm4xx/openbios/openbios.c
file arch/evbppc/obs405/consinit.c
file arch/evbppc/obs405/obs266_autoconf.c
Index: arch/evbppc/conf/files.walnut
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/conf/files.walnut,v
retrieving revision 1.9
diff -d -p -u -r1.9 files.walnut
--- arch/evbppc/conf/files.walnut 27 Feb 2006 11:04:31 -0000 1.9
+++ arch/evbppc/conf/files.walnut 26 Jun 2006 23:39:04 -0000
@@ -6,6 +6,7 @@ file arch/evbppc/walnut/autoconf.c
file arch/evbppc/walnut/consinit.c
file arch/evbppc/walnut/machdep.c
file arch/powerpc/ibm4xx/intr.c
+file arch/powerpc/powerpc/softintr.c
file arch/powerpc/ibm4xx/ibm4xx_autoconf.c
# Memory Disk for install kernel
Index: arch/evbppc/explora/explora_start.S
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/explora/explora_start.S,v
retrieving revision 1.3
diff -d -p -u -r1.3 explora_start.S
--- arch/evbppc/explora/explora_start.S 11 Dec 2005 12:17:12 -0000 1.3
+++ arch/evbppc/explora/explora_start.S 26 Jun 2006 23:39:05 -0000
@@ -65,22 +65,6 @@
GLOBAL(proc0paddr)
.long 0 /* proc0 p_addr */
-GLOBAL(intrnames)
- .asciz "irq0", "irq1", "irq2", "irq3"
- .asciz "irq4", "irq5", "irq6", "irq7"
- .asciz "irq8", "irq9", "irq10", "irq11"
- .asciz "irq12", "irq13", "irq14", "irq15"
- .asciz "irq16", "irq17", "irq18", "softnet"
- .asciz "softclock", "softserial", "clock", "statclock"
- .asciz "irq24", "irq25", "irq26", "irq27"
- .asciz "irq28", "irq29", "irq30", "irq31"
-GLOBAL(eintrnames)
- .align 4
-GLOBAL(intrcnt)
- .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-GLOBAL(eintrcnt)
-
/*
* Initially the dram starts at 0x01000000. This is way too high.
* We relocate dram to 0x00000000. We use the video ram at 0xf0000000
Index: arch/evbppc/explora/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/explora/machdep.c,v
retrieving revision 1.11
diff -d -p -u -r1.11 machdep.c
--- arch/evbppc/explora/machdep.c 5 May 2006 18:04:41 -0000 1.11
+++ arch/evbppc/explora/machdep.c 26 Jun 2006 23:39:05 -0000
@@ -401,36 +401,6 @@ lcsplx(int ipl)
}
void
-softnet(void)
-{
- int isr;
-
- isr = netisr;
- netisr = 0;
-
-#define DONETISR(bit, fn) \
- do { \
- if (isr & (1 << bit)) \
- fn(); \
- } while (0)
-
-#include <net/netisr_dispatch.h>
-
-#undef DONETISR
-}
-
-#include "com.h"
-void
-softserial(void)
-{
-#if NCOM > 0
- void comsoft(void); /* XXX from dev/ic/com.c */
-
- comsoft();
-#endif
-}
-
-void
cpu_reboot(int howto, char *what)
{
static int syncing = 0;
Index: arch/evbppc/include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/include/types.h,v
retrieving revision 1.3
diff -d -p -u -r1.3 types.h
--- arch/evbppc/include/types.h 11 Dec 2005 12:17:12 -0000 1.3
+++ arch/evbppc/include/types.h 26 Jun 2006 23:39:07 -0000
@@ -4,3 +4,4 @@
#define __HAVE_NWSCONS
#define __HAVE_DEVICE_REGISTER
+#define __HAVE_GENERIC_SOFT_INTERRUPTS
Index: arch/evbppc/obs405/obs200_locore.S
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/obs405/obs200_locore.S,v
retrieving revision 1.2
diff -d -p -u -r1.2 obs200_locore.S
--- arch/evbppc/obs405/obs200_locore.S 11 Dec 2005 12:17:12 -0000 1.2
+++ arch/evbppc/obs405/obs200_locore.S 26 Jun 2006 23:39:07 -0000
@@ -105,24 +105,6 @@
GLOBAL(proc0paddr)
.long 0 /* proc0 p_addr */
-GLOBAL(intrnames)
- .asciz "clock", "irq1", "irq2", "irq3"
- .asciz "irq4", "irq5", "irq6", "irq7"
- .asciz "irq8", "irq9", "irq10", "irq11"
- .asciz "irq12", "irq13", "irq14", "irq15"
- .asciz "irq16", "irq17", "irq18", "irq19"
- .asciz "irq20", "irq21", "irq22", "irq23"
- .asciz "irq24", "irq25", "irq26", "irq27"
- .asciz "irq28", "softnet", "softclock", "softserial"
- .asciz "statclock"
-GLOBAL(eintrnames)
- .align 4
-GLOBAL(intrcnt)
- .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- .long 0
-GLOBAL(eintrcnt)
-
/*
* This symbol is here for the benefit of kvm_mkdb, and is supposed to
* mark the start of kernel text.
Index: arch/evbppc/obs405/obs405_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/obs405/obs405_machdep.c,v
retrieving revision 1.2
diff -d -p -u -r1.2 obs405_machdep.c
--- arch/evbppc/obs405/obs405_machdep.c 11 Dec 2005 12:17:12 -0000 1.2
+++ arch/evbppc/obs405/obs405_machdep.c 26 Jun 2006 23:39:07 -0000
@@ -54,43 +54,3 @@ struct vm_map *mb_map = NULL;
struct vm_map *phys_map = NULL;
char machine[] = MACHINE; /* from <machine/param.h> */
char machine_arch[] = MACHINE_ARCH; /* from <machine/param.h> */
-
-/*
- * TODO: XXX these functions are machine-dependent ??
- */
-
-/*
- * softnet:
- * Soft networking interrupts.
- */
-void
-softnet(void)
-{
- int isr;
-
- isr = netisr;
- netisr = 0;
-
-#define DONETISR(bit, fn) do { \
- if (isr & (1 << bit)) \
- fn(); \
-} while (0)
-
-#include <net/netisr_dispatch.h>
-#undef DONETISR
-}
-
-/*
- * softserial:
- * Soft tty interrupts.
- */
-#include "com.h"
-void
-softserial(void)
-{
-#if NCOM > 0
- void comsoft(void); /* XXX from dev/ic/com.c */
-
- comsoft();
-#endif
-}
Index: arch/evbppc/walnut/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/walnut/machdep.c,v
retrieving revision 1.27
diff -d -p -u -r1.27 machdep.c
--- arch/evbppc/walnut/machdep.c 5 May 2006 18:04:41 -0000 1.27
+++ arch/evbppc/walnut/machdep.c 26 Jun 2006 23:39:07 -0000
@@ -459,42 +459,6 @@ dumpsys(void)
}
/*
- * Soft networking interrupts.
- */
-void
-softnet(void)
-{
- int isr;
-
- isr = netisr;
- netisr = 0;
-
-#define DONETISR(bit, fn) do { \
- if (isr & (1 << bit)) \
- fn(); \
-} while (0)
-
-#include <net/netisr_dispatch.h>
-
-#undef DONETISR
-
-}
-
-/*
- * Soft tty interrupts.
- */
-#include "com.h"
-void
-softserial(void)
-{
-#if NCOM > 0
- void comsoft(void); /* XXX from dev/ic/com.c */
-
- comsoft();
-#endif
-}
-
-/*
* Halt or reboot the machine after syncing/dumping according to howto.
*/
void
Index: arch/evbppc/walnut/walnut_start.S
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/walnut/walnut_start.S,v
retrieving revision 1.12
diff -d -p -u -r1.12 walnut_start.S
--- arch/evbppc/walnut/walnut_start.S 11 Dec 2005 12:17:13 -0000 1.12
+++ arch/evbppc/walnut/walnut_start.S 26 Jun 2006 23:39:08 -0000
@@ -104,24 +104,6 @@
GLOBAL(proc0paddr)
.long 0 /* proc0 p_addr */
-GLOBAL(intrnames)
- .asciz "clock", "irq1", "irq2", "irq3"
- .asciz "irq4", "irq5", "irq6", "irq7"
- .asciz "irq8", "irq9", "irq10", "irq11"
- .asciz "irq12", "irq13", "irq14", "irq15"
- .asciz "irq16", "irq17", "irq18", "irq19"
- .asciz "irq20", "irq21", "irq22", "irq23"
- .asciz "irq24", "irq25", "irq26", "irq27"
- .asciz "irq28", "softnet", "softclock", "softserial"
- .asciz "statclock"
-GLOBAL(eintrnames)
- .align 4
-GLOBAL(intrcnt)
- .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- .long 0
-GLOBAL(eintrcnt)
-
/*
* This symbol is here for the benefit of kvm_mkdb, and is supposed to
* mark the start of kernel text.
Index: arch/evbppc/walnut/pci/pci_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/walnut/pci/pci_machdep.c,v
retrieving revision 1.6
diff -d -p -u -r1.6 pci_machdep.c
--- arch/evbppc/walnut/pci/pci_machdep.c 10 Feb 2006 20:52:57 -0000 1.6
+++ arch/evbppc/walnut/pci/pci_machdep.c 26 Jun 2006 23:39:08 -0000
@@ -205,8 +205,9 @@ pci_intr_string(pci_chipset_tag_t pc, pc
{
static char irqstr[8]; /* 4 + 2 + NUL + sanity */
- if (ih == 0 || ih >= ICU_LEN)
- panic("pci_intr_string: bogus handle 0x%x", ih);
+ /* Make sure it looks sane, intr_establish does the real check. */
+ if (ih < 0 || ih > 99)
+ panic("pci_intr_string: handle %#x won't fit two digits", ih);
sprintf(irqstr, "irq %d", ih);
return (irqstr);
@@ -225,10 +226,6 @@ void *
pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level,
int (*func)(void *), void *arg)
{
-
- if (ih == 0 || ih >= ICU_LEN)
- panic("pci_intr_establish: bogus handle 0x%x", ih);
-
return intr_establish(ih, IST_LEVEL, level, func, arg);
}