PERFORCE change 117957 for review
Oleksandr Tymoshenko
gonzo at FreeBSD.org
Thu Apr 12 12:28:04 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=117957
Change 117957 by gonzo at gonzo_jeeves on 2007/04/12 12:27:08
o Migrate on new inetrrupt filtering API.
o Replace "magic numbers" with named constants and export them
through genassym.c.
Affected files ...
.. //depot/projects/mips2/src/sys/mips/include/intr_machdep.h#3 edit
.. //depot/projects/mips2/src/sys/mips/mips/cpu.c#18 edit
.. //depot/projects/mips2/src/sys/mips/mips/genassym.c#7 edit
.. //depot/projects/mips2/src/sys/mips/mips/intr_machdep.c#3 edit
.. //depot/projects/mips2/src/sys/mips/mips/nexus.c#4 edit
.. //depot/projects/mips2/src/sys/mips/mips/tick.c#5 edit
.. //depot/projects/mips2/src/sys/mips/mips4k/malta/gt_pci.c#5 edit
Differences ...
==== //depot/projects/mips2/src/sys/mips/include/intr_machdep.h#3 (text+ko) ====
@@ -23,26 +23,21 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $P4: //depot/projects/mips2/src/sys/mips/include/intr_machdep.h#2 $
+ * $P4: //depot/projects/mips2/src/sys/mips/include/intr_machdep.h#3 $
*/
#ifndef _MACHINE_INTR_H_
#define _MACHINE_INTR_H_
+#define NHARD_IRQS 6
+#define NSOFT_IRQS 2
+
struct trapframe;
-/*
- * Include the platform-specific MD interrupt header.
- */
-/*
- * XXXMIPS: We don't have this file.
- */
-#if 0
-#include <platform/intr.h>
-#endif
-
-void cpu_establish_hardintr(int, void (*)(void *), void *);
-void cpu_establish_softintr(int, void (*)(void *), void *);
+void cpu_establish_hardintr(const char *, int (*)(void*), void (*)(void*),
+ void *, int, int, void **);
+void cpu_establish_softintr(const char *, int (*)(void*), void (*)(void*),
+ void *, int, int, void **);
void cpu_intr(struct trapframe *);
#endif /* !_MACHINE_INTR_H_ */
==== //depot/projects/mips2/src/sys/mips/mips/cpu.c#18 (text+ko) ====
@@ -83,6 +83,9 @@
size_t len, max;
max = 0x80;
+ if(bootverbose)
+ printf("Installing exception vector:\n\t[%p..%p] <- [%p..%p]\n",
+ (void *)addr, (void *)(addr+max), begin, end);
len = end - begin;
if (len > max)
panic("exception code too big for vector %jx", (intmax_t) addr);
@@ -263,7 +266,8 @@
static struct resource *cpu_alloc_resource(device_t, device_t, int, int *,
u_long, u_long, u_long, u_int);
static int cpu_setup_intr(device_t, device_t, struct resource *, int,
- driver_intr_t *, void *, void **);
+ driver_filter_t *f, driver_intr_t *, void *,
+ void **);
static device_method_t cpu_methods[] = {
/* Device interface */
@@ -345,7 +349,8 @@
static int
cpu_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
- driver_intr_t *handler, void *arg, void **cookiep)
+ driver_filter_t *filt, driver_intr_t *handler, void *arg,
+ void **cookiep)
{
int error;
int intr;
@@ -358,7 +363,8 @@
intr = rman_get_start(res);
- cpu_establish_hardintr(intr, handler, arg);
+ cpu_establish_hardintr(device_get_nameunit(child), filt, handler, arg,
+ intr, flags, cookiep);
device_printf(child, "established CPU interrupt %d\n", intr);
return (0);
}
==== //depot/projects/mips2/src/sys/mips/mips/genassym.c#7 (text+ko) ====
@@ -60,6 +60,7 @@
#include <net/if.h>
#include <netinet/in.h>
+#include <machine/intr_machdep.h>
#include <machine/locore.h>
#include <machine/pcb.h>
#include <machine/reg.h>
@@ -67,6 +68,7 @@
ASSYM(MIPS_KSEG0_START, MIPS_KSEG0_START);
ASSYM(MIPS_KSSEG_START, MIPS_KSSEG_START);
ASSYM(MIPS_PG_G, PG_G);
+
ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace));
ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
@@ -76,7 +78,6 @@
ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED);
ASSYM(TD_FLAGS, offsetof(struct thread, td_flags));
-
ASSYM(TD_FRAME, offsetof(struct thread, td_frame));
ASSYM(TD_KSTACK, offsetof(struct thread, td_kstack));
ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
@@ -191,3 +192,6 @@
ASSYM(VM_MIN_KERNEL_ADDRESS, VM_MIN_KERNEL_ADDRESS);
ASSYM(VM_MAX_KERNEL_ADDRESS, VM_MAX_KERNEL_ADDRESS);
+ASSYM(NHARD_IRQS, NHARD_IRQS);
+ASSYM(NSOFT_IRQS, NSOFT_IRQS);
+ASSYM(MAXCOMLEN, MAXCOMLEN);
==== //depot/projects/mips2/src/sys/mips/mips/intr_machdep.c#3 (text+ko) ====
@@ -32,6 +32,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
+#include <sys/interrupt.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
@@ -42,53 +43,87 @@
#include <machine/md_var.h>
#include <machine/trap.h>
-struct intrhand {
- void (*handler)(void *);
- void *arg;
-};
-static struct intrhand intrhard[6];
-static struct intrhand intrsoft[2];
+static struct intr_event *hardintr_events[NHARD_IRQS];
+static struct intr_event *softintr_events[NSOFT_IRQS];
+
+#ifdef notyet
+static int intrcnt_tab[NHARD_IRQS + NSOFT_IRQS];
+static int intrcnt_index = 0;
+static int last_printed = 0;
+#endif
void
-cpu_establish_hardintr(int intr, void (*handler)(void *), void *arg)
+cpu_establish_hardintr(const char *name, driver_filter_t *filt,
+ void (*handler)(void*), void *arg, int irq, int flags,
+ void **cookiep)
{
- struct intrhand *ih;
+ struct intr_event *event;
+ int error;
+
+ if (irq < 0 || irq > NHARD_IRQS)
+ panic("%s called for unknown hard intr %d", __func__, irq);
+
+ event = hardintr_events[irq];
+ if (event == NULL) {
+ error = intr_event_create(&event, (void *)irq, 0,
+ (void (*)(void *))NULL, "hard intr%d:", irq);
+ if (error)
+ return;
+ hardintr_events[irq] = event;
+#ifdef notyet
+ last_printed +=
+ snprintf(intrnames + last_printed,
+ MAXCOMLEN + 1,
+ "hard irq%d: %s", irq, name);
+ last_printed++;
+ intrcnt_tab[irq] = intrcnt_index;
+ intrcnt_index++;
+#endif
+
+ }
- if (intr < 0 || intr > 5)
- panic("%s called for unknown hard intr %d", __func__, intr);
- ih = &intrhard[intr];
- if (ih->handler != NULL && ih->handler != handler)
- panic("%s cannot share hard intr %d", __func__, intr);
- ih->handler = handler;
- ih->arg = arg;
+ intr_event_add_handler(event, name, filt, handler, arg,
+ intr_priority(flags), flags, cookiep);
- mips_wr_status(mips_rd_status() | (((1<< intr) << 8) << 2));
+ mips_wr_status(mips_rd_status() | (((1<< irq) << 8) << 2));
}
void
-cpu_establish_softintr(int intr, void (*handler)(void *), void *arg)
+cpu_establish_softintr(const char *name, driver_filter_t *filt,
+ void (*handler)(void*), void *arg, int irq, int flags,
+ void **cookiep)
{
- struct intrhand *ih;
+ struct intr_event *event;
+ int error;
+
+ if (irq < 0 || irq > NSOFT_IRQS)
+ panic("%s called for unknown hard intr %d", __func__, irq);
+
+ event = softintr_events[irq];
+ if (event == NULL) {
+ error = intr_event_create(&event, (void *)irq, 0,
+ (void (*)(void *))NULL, "intr%d:", irq);
+ if (error)
+ return;
+ softintr_events[irq] = event;
+ }
- if (intr < 0 || intr > 1)
- panic("%s called for unknown soft intr %d", __func__, intr);
- ih = &intrsoft[intr];
- if (ih->handler != NULL && ih->handler != handler)
- panic("%s cannot share soft intr %d", __func__, intr);
- ih->handler = handler;
- ih->arg = arg;
+ intr_event_add_handler(event, name, filt, handler, arg,
+ intr_priority(flags), flags, cookiep);
- mips_wr_status(mips_rd_status() | ((1 << intr) << 8));
+ mips_wr_status(mips_rd_status() | (((1<< irq) << 8)));
}
void
cpu_intr(struct trapframe *tf)
{
- struct intrhand *ih;
+ struct intr_handler *ih;
+ struct intr_event *event;
register_t cause;
int hard;
int intr;
int i;
+ int thread;
critical_enter();
@@ -104,25 +139,39 @@
/* Software interrupt. */
i--; /* Get a 0-offset interrupt. */
hard = 0;
- ih = &intrsoft[i];
+ event = softintr_events[i];
break;
default:
/* Hardware interrupt. */
i -= 2; /* Trim software interrupt bits. */
i--; /* Get a 0-offset interrupt. */
hard = 1;
- ih = &intrhard[i];
+ event = hardintr_events[i];
break;
}
- if (ih->handler != NULL) {
- if (ih->arg == NULL)
- (*ih->handler)(tf);
+
+ if (!event || TAILQ_EMPTY(&event->ie_handlers))
+ {
+ printf("stray %s interrupt %d\n",
+ hard ? "hard" : "soft", i);
+ continue;
+ }
+
+ /* Execute fast handlers. */
+ thread = 0;
+ TAILQ_FOREACH(ih, &event->ie_handlers, ih_next) {
+ if (ih->ih_filter == NULL)
+ thread = 1;
else
- (*ih->handler)(ih->arg);
- } else
- printf("stray %s interrupt %d\n",
- hard ? "hard" : "soft", i);
+ ih->ih_filter(ih->ih_argument ?
+ ih->ih_argument : tf);
+ }
+
+ /* Schedule thread if needed. */
+ if (thread)
+ intr_event_schedule_thread(event);
}
+
KASSERT(i == 0, ("all interrupts handled"));
critical_exit();
==== //depot/projects/mips2/src/sys/mips/mips/nexus.c#4 (text+ko) ====
@@ -80,7 +80,7 @@
struct resource *);
static int
nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
- driver_intr_t *intr, void *arg, void **cookiep);
+ driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep);
static int
nexus_teardown_intr(device_t, device_t, struct resource *, void *);
@@ -124,7 +124,7 @@
static int
nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
- driver_intr_t *intr, void *arg, void **cookiep)
+ driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep)
{
int irq;
@@ -132,7 +132,9 @@
irq = rman_get_start(res);
if(irq > 5)
return(0);
- cpu_establish_hardintr(irq, intr, arg);
+
+ cpu_establish_hardintr(device_get_nameunit(child), filt, intr, arg,
+ irq, flags, cookiep);
intr_restore(sr);
return (0);
}
==== //depot/projects/mips2/src/sys/mips/mips/tick.c#5 (text+ko) ====
@@ -203,7 +203,6 @@
/*
* Set next clock edge.
*/
-
mips_wr_compare(mips_rd_count() + counter_freq / hz);
/*
@@ -218,7 +217,7 @@
hardclock(usermode, pc);
}
- return (FILTER_HANDLED);
+ return FILTER_HANDLED;
}
static int
@@ -250,9 +249,10 @@
device_printf(dev, "failed to allocate irq\n");
return (ENXIO);
}
- error = bus_setup_intr(dev, irq,
- INTR_TYPE_CLK | INTR_MPSAFE | INTR_FAST,
- clock_intr, NULL, NULL, NULL);
+
+ error = bus_setup_intr(dev, irq, INTR_TYPE_CLK, clock_intr, NULL,
+ NULL, NULL);
+
if (error != 0) {
device_printf(dev, "bus_setup_intr returned %d\n", error);
return (error);
==== //depot/projects/mips2/src/sys/mips/mips4k/malta/gt_pci.c#5 (text+ko) ====
@@ -46,6 +46,7 @@
#include <sys/systm.h>
#include <sys/bus.h>
+#include <sys/interrupt.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/module.h>
@@ -90,17 +91,6 @@
#define OCW3_POLL_IRQ(x) ((x) & 0x7f)
#define OCW3_POLL_PENDING (1U << 7)
-struct intrhand {
- LIST_ENTRY(intrhand) ih_list;
- driver_intr_t *ih_func;
- void *ih_arg;
- int ih_irq;
-};
-
-struct pci_intrhead {
- LIST_HEAD(, intrhand) intr_list;
-};
-
struct gt_pci_softc {
device_t sc_dev;
bus_space_tag_t sc_st;
@@ -118,7 +108,7 @@
uint32_t sc_io;
struct resource *sc_irq;
- struct pci_intrhead sc_intrtab[ICU_LEN];
+ struct intr_event *sc_eventstab[ICU_LEN];
uint16_t sc_imask;
uint16_t sc_elcr;
@@ -151,8 +141,9 @@
gt_pci_intr(void *v)
{
struct gt_pci_softc *sc = v;
- struct intrhand *ih;
- int irq;
+ struct intr_event *event;
+ struct intr_handler *ih;
+ int irq, thread;
for (;;) {
bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, PIC_OCW3,
@@ -176,8 +167,23 @@
irq = 2;
}
- LIST_FOREACH(ih, &sc->sc_intrtab[irq].intr_list, ih_list)
- (*ih->ih_func)(ih->ih_arg);
+ event = sc->sc_eventstab[irq];
+ thread = 0;
+
+ if (event && !TAILQ_EMPTY(&event->ie_handlers))
+ {
+ /* Execute fast handlers. */
+ TAILQ_FOREACH(ih, &event->ie_handlers, ih_next) {
+ if (ih->ih_filter == NULL)
+ thread = 1;
+ else
+ ih->ih_filter(ih->ih_argument);
+ }
+ }
+
+ /* Schedule thread if needed. */
+ if (thread)
+ intr_event_schedule_thread(event);
/* Send a specific EOI to the 8259. */
if (irq > 7) {
@@ -192,8 +198,6 @@
}
}
-
-
static int
gt_pci_probe(device_t dev)
{
@@ -205,9 +209,9 @@
gt_pci_attach(device_t dev)
{
- uint32_t busno;
+ uint32_t busno;
struct gt_pci_softc *sc = device_get_softc(dev);
- int rid, i;
+ int rid;
busno = 0;
sc->sc_dev = dev;
@@ -270,7 +274,7 @@
ICW1_RESET | ICW1_IC4);
/*
* XXX: values from NetBSD's <dev/ic/i8259reg.h>
- */
+ */
bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1,
0/*XXX*/);
bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1,
@@ -338,30 +342,20 @@
(1U << 14) | /* IDE primary */
(1U << 15); /* IDE secondary */
- /* Initialize our interrupt table. */
- for (i = 0; i < ICU_LEN; i++) {
- LIST_INIT(&sc->sc_intrtab[i].intr_list);
- }
-
/* Hook up our interrupt handler. */
- if ((sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
+ if ((sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
MALTA_SOUTHBRIDGE_INTR, MALTA_SOUTHBRIDGE_INTR, 1,
RF_SHAREABLE | RF_ACTIVE)) == NULL) {
device_printf(dev, "unable to allocate IRQ resource\n");
return ENXIO;
- }
+ }
- if ((bus_setup_intr(dev, sc->sc_irq, INTR_FAST | INTR_MPSAFE,
- NULL, gt_pci_intr, sc, &sc->sc_ih))) {
+ if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC,
+ NULL, gt_pci_intr, sc, &sc->sc_ih))) {
device_printf(dev,
"WARNING: unable to register interrupt handler\n");
return ENXIO;
- }
-
- if (sc->sc_ih == NULL)
-
-
-
+ }
/* Initialize memory and i/o rmans. */
device_add_child(dev, "pci", busno);
@@ -392,8 +386,8 @@
uint32_t addr;
uint32_t shift, mask;
- if (gt_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr))
- return (uint32_t)(-1);
+ if (gt_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr))
+ return (uint32_t)(-1);
/* Clear cause register bits. */
GT_REGVAL(GT_INTR_CAUSE) = 0;
@@ -644,37 +638,36 @@
}
static int
-gt_pci_setup_intr(device_t dev, device_t child,
- struct resource *ires, int flags, driver_intr_t *intr, void *arg,
- void **cookiep)
+gt_pci_setup_intr(device_t dev, device_t child, struct resource *ires,
+ int flags, driver_filter_t *filt, driver_intr_t *handler,
+ void *arg, void **cookiep)
{
struct gt_pci_softc *sc = device_get_softc(dev);
- struct intrhand *ih;
- int irq;
+ struct intr_event *event;
+ int irq, error;
irq = rman_get_start(ires);
if (irq >= ICU_LEN || irq == 2)
panic("%s: bad irq or type", __func__);
- ih = malloc(sizeof(*ih), M_DEVBUF, M_NOWAIT);
- if (ih == NULL)
- return ENOMEM;
+ event = sc->sc_eventstab[irq];
+ if (event == NULL) {
+ error = intr_event_create(&event, (void *)irq, 0,
+ (void (*)(void *))NULL, "gt_pci intr%d:", irq);
+ if (error)
+ return 0;
+ sc->sc_eventstab[irq] = event;
+ }
- ih->ih_func = intr;
- ih->ih_arg = arg;
- ih->ih_irq = irq;
+ intr_event_add_handler(event, device_get_nameunit(child), filt,
+ handler, arg, intr_priority(flags), flags, cookiep);
- /* Insert the handler into the table. */
- LIST_INSERT_HEAD(&sc->sc_intrtab[irq].intr_list, ih, ih_list);
-
/* Enable it, set trigger mode. */
sc->sc_imask &= ~(1 << irq);
sc->sc_elcr &= ~(1 << irq);
gt_pci_set_icus(sc);
- *cookiep = (void *)ih;
-
return 0;
}
@@ -682,19 +675,7 @@
gt_pci_teardown_intr(device_t dev, device_t child, struct resource *res,
void *cookie)
{
- struct gt_pci_softc *sc = device_get_softc(dev);
- struct intrhand *ih = cookie;
- LIST_REMOVE(ih, ih_list);
-
- /* If there are no more handlers on this IRQ, disable it. */
- if (LIST_FIRST(&sc->sc_intrtab[ih->ih_irq].intr_list) == NULL) {
- sc->sc_imask |= (1 << ih->ih_irq);
- gt_pci_set_icus(sc);
- }
-
- free(ih, M_DEVBUF);
-
- return 0;
+ return (intr_event_remove_handler(cookie));
}
static device_method_t gt_pci_methods[] = {
More information about the p4-projects
mailing list