diff options
author | benno <benno@FreeBSD.org> | 2002-07-09 11:12:20 +0000 |
---|---|---|
committer | benno <benno@FreeBSD.org> | 2002-07-09 11:12:20 +0000 |
commit | 95feadb0a5cdcda16af56f610de6cb4bd8446dcd (patch) | |
tree | 3b894a10c4d1cb3b0ce62693c0ec0f2b8736842e | |
parent | df20e19b27e4883867e7cebb064c311332f30050 (diff) | |
download | FreeBSD-src-95feadb0a5cdcda16af56f610de6cb4bd8446dcd.zip FreeBSD-src-95feadb0a5cdcda16af56f610de6cb4bd8446dcd.tar.gz |
Add interrupt handling support code.
I've tried to make this fairly platform-independant as some PowerPC platforms
may not have openpic-style interrupt controllers. This may not have the best
performance but it works for now.
-rw-r--r-- | sys/conf/files.powerpc | 2 | ||||
-rw-r--r-- | sys/powerpc/include/intr_machdep.h | 49 | ||||
-rw-r--r-- | sys/powerpc/powerpc/intr_machdep.c | 280 | ||||
-rw-r--r-- | sys/powerpc/powerpc/pic_if.m | 64 |
4 files changed, 395 insertions, 0 deletions
diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc index debb9c9..9812443 100644 --- a/sys/conf/files.powerpc +++ b/sys/conf/files.powerpc @@ -23,10 +23,12 @@ powerpc/powerpc/fpu.c standard powerpc/powerpc/fuswintr.c standard powerpc/powerpc/in_cksum.c optional inet powerpc/powerpc/interrupt.c standard +powerpc/powerpc/intr_machdep.c standard powerpc/powerpc/machdep.c standard powerpc/powerpc/nexus.c standard powerpc/powerpc/ofwmagic.s standard powerpc/powerpc/ofw_machdep.c standard +powerpc/powerpc/pic_if.m standard powerpc/powerpc/pmap.c standard powerpc/powerpc/sigcode.S standard powerpc/powerpc/suswintr.c standard diff --git a/sys/powerpc/include/intr_machdep.h b/sys/powerpc/include/intr_machdep.h new file mode 100644 index 0000000..e01ebce --- /dev/null +++ b/sys/powerpc/include/intr_machdep.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2002 Benno Rice. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT 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. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE_INTR_MACHDEP_H_ +#define _MACHINE_INTR_MACHDEP_H_ + +typedef void ih_func_t(void *); + +struct ithd; + +struct intr_handler { + ih_func_t *ih_func; + void *ih_arg; + struct ithd *ih_ithd; + u_int ih_irq; +}; + +void intr_init(void (*)(void), int, void (*)(int), void (*)(int)); +void intr_setup(u_int, ih_func_t *, void *); +int inthand_add(const char *, u_int, void (*)(void *), void *, int, + void **); +int inthand_remove(u_int, void *); +void intr_handle(u_int); + +#endif /* _MACHINE_INTR_MACHDEP_H_ */ diff --git a/sys/powerpc/powerpc/intr_machdep.c b/sys/powerpc/powerpc/intr_machdep.c new file mode 100644 index 0000000..839bbeb --- /dev/null +++ b/sys/powerpc/powerpc/intr_machdep.c @@ -0,0 +1,280 @@ +/*- + * Copyright (c) 1991 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * 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. + */ +/*- + * Copyright (c) 2002 Benno Rice. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * 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. + * + * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 + * form: src/sys/i386/isa/intr_machdep.c,v 1.57 2001/07/20 + * + * $FreeBSD$ + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/queue.h> +#include <sys/bus.h> +#include <sys/interrupt.h> +#include <sys/lock.h> +#include <sys/malloc.h> +#include <sys/mutex.h> +#include <sys/pcpu.h> +#include <sys/vmmeter.h> + +#include <machine/frame.h> +#include <machine/interruptvar.h> +#include <machine/intr_machdep.h> +#include <machine/trap.h> + +#define MAX_STRAY_LOG 5 + +MALLOC_DEFINE(M_INTR, "intr", "interrupt handler data"); + +static int intr_initialized = 0; + +static u_int intr_nirq; +static struct intr_handler *intr_handlers; +static u_long *intr_stray_count; + +static struct mtx intr_table_lock; + +extern int extint, extsize; +extern u_long extint_call; + +static ih_func_t intr_stray_handler; +static ih_func_t sched_ithd; + +static void (*irq_enable)(int); +static void (*irq_disable)(int); + +void +intr_init(void (*handler)(void), int nirq, void (*irq_e)(int), + void (*irq_d)(int)) +{ + int i; + u_int32_t msr; + u_long offset; + + if (intr_initialized != 0) + panic("intr_init: interrupts intialized twice\n"); + + intr_initialized++; + + intr_nirq = nirq; + intr_handlers = malloc(nirq * sizeof(struct intr_handler), M_INTR, + M_NOWAIT|M_ZERO); + if (intr_handlers == NULL) + panic("intr_init: unable to allocate interrupt handler array"); + intr_stray_count = malloc(nirq * sizeof(u_long), M_INTR, + M_NOWAIT|M_ZERO); + if (intr_stray_count == NULL) + panic("intr_init: unable to allocate interrupt stray array"); + + for (i = 0; i < nirq; i++) { + intr_handlers[i].ih_func = intr_stray_handler; + intr_handlers[i].ih_arg = &intr_handlers[i]; + intr_handlers[i].ih_irq = i; + } + + msr = mfmsr(); + mtmsr(msr & ~PSL_EE); + + ext_intr_install(handler); + + mtmsr(msr); + + irq_enable = irq_e; + irq_disable = irq_d; + + mtx_init(&intr_table_lock, "ithread table lock", NULL, MTX_SPIN); +} + +void +intr_setup(u_int irq, ih_func_t *ihf, void *iha) +{ + u_int32_t msr; + + msr = mfmsr(); + mtmsr(msr & ~PSL_EE); + + intr_handlers[irq].ih_func = ihf; + intr_handlers[irq].ih_arg = iha; + intr_handlers[irq].ih_irq = irq; + + mtmsr(msr); +} + +int +inthand_add(const char *name, u_int irq, void (*handler)(void *), void *arg, + int flags, void **cookiep) +{ + struct intr_handler *ih; + struct ithd *ithd, *orphan; + int error = 0; + int created_ithd = 0; + + /* + * Work around a race where more than one CPU may be registering + * handlers on the same IRQ at the same time. + */ + ih = &intr_handlers[irq]; + mtx_lock_spin(&intr_table_lock); + ithd = ih->ih_ithd; + mtx_unlock_spin(&intr_table_lock); + if (ithd == NULL) { + error = ithread_create(&ithd, irq, 0, irq_disable, + irq_enable, "irq%d:", irq); + if (error) + return (error); + + mtx_lock_spin(&intr_table_lock); + + if (ih->ih_ithd == NULL) { + ih->ih_ithd = ithd; + created_ithd++; + mtx_unlock_spin(&intr_table_lock); + } else { + orphan = ithd; + ithd = ih->ih_ithd; + mtx_unlock_spin(&intr_table_lock); + ithread_destroy(orphan); + } + } + + error = ithread_add_handler(ithd, name, handler, arg, + ithread_priority(flags), flags, cookiep); + + if ((flags & INTR_FAST) == 0 || error) { + intr_setup(irq, sched_ithd, ih); + error = 0; + } + + if (error) + return (error); + + if (flags & INTR_FAST) + intr_setup(irq, handler, arg); + + intr_stray_count[irq] = 0; + + return (0); +} + +int +inthand_remove(u_int irq, void *cookie) +{ + struct intr_handler *ih; + int error; + + error = ithread_remove_handler(cookie); + + if (error == 0) { + ih = &intr_handlers[irq]; + + mtx_lock_spin(&intr_table_lock); + + if (ih->ih_ithd == NULL) { + intr_setup(irq, intr_stray_handler, ih); + } else { + intr_setup(irq, sched_ithd, ih); + } + + mtx_unlock_spin(&intr_table_lock); + } + + return (error); +} + +void +intr_handle(u_int irq) +{ + + intr_handlers[irq].ih_func(intr_handlers[irq].ih_arg); +} + +static void +intr_stray_handler(void *cookie) +{ + struct intr_handler *ih; + + ih = (struct intr_handler *)cookie; + + if (intr_stray_count[ih->ih_irq] < MAX_STRAY_LOG) { + printf("stray irq %d\n", ih->ih_irq); + + atomic_add_long(&intr_stray_count[ih->ih_irq], 1); + + if (intr_stray_count[ih->ih_irq] >= MAX_STRAY_LOG) + printf("got %d stray irq %d's: not logging anymore\n", + MAX_STRAY_LOG, ih->ih_irq); + } +} + +static void +sched_ithd(void *cookie) +{ + struct intr_handler *ih; + int error; + + ih = (struct intr_handler *)cookie; + + error = ithread_schedule(ih->ih_ithd, 0); + + if (error == EINVAL) + intr_stray_handler(ih); +} diff --git a/sys/powerpc/powerpc/pic_if.m b/sys/powerpc/powerpc/pic_if.m new file mode 100644 index 0000000..e855efd --- /dev/null +++ b/sys/powerpc/powerpc/pic_if.m @@ -0,0 +1,64 @@ +# +# Copyright (c) 1998 Doug Rabson +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# 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. +# +# from: src/sys/kern/bus_if.m,v 1.21 2002/04/21 11:16:10 markm Exp +# $FreeBSD$ +# + +#include <sys/bus.h> + +INTERFACE pic; + +METHOD struct resource * allocate_intr { + device_t dev; + device_t child; + int *rid; + u_long intr; + u_int flags; +}; + +METHOD int setup_intr { + device_t dev; + device_t child; + struct resource *res; + int flags; + driver_intr_t *intr; + void *arg; + void **cookiep; +}; + +METHOD int teardown_intr { + device_t dev; + device_t child; + struct resource *res; + void *ih; +}; + +METHOD int release_intr { + device_t dev; + device_t child; + int rid; + struct resource *res; +}; |