diff options
-rw-r--r-- | sys/arch/alpha/alpha/autoconf.c | 4 | ||||
-rw-r--r-- | sys/arch/alpha/alpha/interrupt.c | 263 | ||||
-rw-r--r-- | sys/arch/alpha/alpha/locore.s | 4 | ||||
-rw-r--r-- | sys/arch/alpha/alpha/machdep.c | 101 | ||||
-rw-r--r-- | sys/arch/alpha/include/intr.h | 130 |
5 files changed, 363 insertions, 139 deletions
diff --git a/sys/arch/alpha/alpha/autoconf.c b/sys/arch/alpha/alpha/autoconf.c index 2e05be637f3..b50cbc30ee1 100644 --- a/sys/arch/alpha/alpha/autoconf.c +++ b/sys/arch/alpha/alpha/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.13 2001/09/19 21:32:13 miod Exp $ */ +/* $OpenBSD: autoconf.c,v 1.14 2001/09/30 13:08:45 art Exp $ */ /* $NetBSD: autoconf.c,v 1.16 1996/11/13 21:13:04 cgd Exp $ */ /* @@ -57,6 +57,7 @@ #include <machine/rpb.h> #include <machine/prom.h> #include <machine/cpuconf.h> +#include <machine/intr.h> #include <dev/cons.h> @@ -88,6 +89,7 @@ void cpu_configure() { parse_prom_bootdev(); + softintr_init(); /* * Disable interrupts during autoconfiguration. splhigh() won't diff --git a/sys/arch/alpha/alpha/interrupt.c b/sys/arch/alpha/alpha/interrupt.c index 2f86abed808..22a0faa482c 100644 --- a/sys/arch/alpha/alpha/interrupt.c +++ b/sys/arch/alpha/alpha/interrupt.c @@ -1,5 +1,41 @@ -/* $OpenBSD: interrupt.c,v 1.11 2001/01/20 20:29:53 art Exp $ */ -/* $NetBSD: interrupt.c,v 1.44 2000/05/23 05:12:53 thorpej Exp $ */ +/* $OpenBSD: interrupt.c,v 1.12 2001/09/30 13:08:45 art Exp $ */ +/* $NetBSD: interrupt.c,v 1.46 2000/06/03 20:47:36 thorpej Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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) 1994, 1995, 1996 Carnegie-Mellon University. @@ -41,6 +77,8 @@ #include <sys/kernel.h> #include <sys/systm.h> #include <sys/device.h> +#include <sys/mbuf.h> +#include <sys/socket.h> #include <vm/vm.h> @@ -59,24 +97,42 @@ #include <sys/device.h> #endif +#include <net/netisr.h> +#include <net/if.h> + +#ifdef INET +#include <netinet/in.h> +#include <netinet/if_ether.h> +#include <netinet/ip_var.h> +#endif + +#ifdef INET6 +#ifndef INET +#include <netinet/in.h> +#endif +#include <netinet/ip6.h> +#include <netinet6/ip6_var.h> +#endif + +#include "ppp.h" +#include "bridge.h" + static u_int schedclk2; +void netintr(void); + void -interrupt(a0, a1, a2, framep) - unsigned long a0, a1, a2; - struct trapframe *framep; +interrupt(unsigned long a0, unsigned long a1, unsigned long a2, + struct trapframe *framep) { struct proc *p; -#if defined(MULTIPROCESSOR) - u_long cpu_id = alpha_pal_whami(); -#endif + struct cpu_info *ci = curcpu(); extern int schedhz; switch (a0) { case ALPHA_INTR_XPROC: /* interprocessor interrupt */ #if defined(MULTIPROCESSOR) { - struct cpu_info *ci = &cpu_info[cpu_id]; u_long pending_ipis, bit; #if 0 @@ -86,7 +142,7 @@ interrupt(a0, a1, a2, framep) #ifdef DIAGNOSTIC if (ci->ci_dev == NULL) { /* XXX panic? */ - printf("WARNING: no device for ID %lu\n", cpu_id); + printf("WARNING: no device for ID %lu\n", ci->ci_cpuid); return; } #endif @@ -100,7 +156,7 @@ interrupt(a0, a1, a2, framep) * Handle inter-console messages if we're the primary * CPU. */ - if (cpu_id == hwrpb->rpb_primary_cpu_id && + if (ci->ci_cpuid == hwrpb->rpb_primary_cpu_id && hwrpb->rpb_txrdy != 0) cpu_iccb_receive(); } @@ -112,16 +168,25 @@ interrupt(a0, a1, a2, framep) case ALPHA_INTR_CLOCK: /* clock interrupt */ #if defined(MULTIPROCESSOR) /* XXX XXX XXX */ - if (cpu_id != hwrpb->rpb_primary_cpu_id) + if (CPU_IS_PRIMARY(ci) == 0) return; #endif uvmexp.intrs++; intrcnt[INTRCNT_CLOCK]++; if (platform.clockintr) { + /* + * Call hardclock(). This will also call + * statclock(). On the primary CPU, it + * will also deal with time-of-day stuff. + */ (*platform.clockintr)((struct clockframe *)framep); - if((++schedclk2 & 0x3f) == 0 - && (p = curproc) != NULL - && schedhz) + + /* + * If it's time to call the scheduler clock, + * do so. + */ + if ((++schedclk2 & 0x3f) == 0 && + (p = ci->ci_curproc) != NULL && schedhz != 0) schedclock(p); } break; @@ -137,7 +202,7 @@ interrupt(a0, a1, a2, framep) case ALPHA_INTR_DEVICE: /* I/O device interrupt */ #if defined(MULTIPROCESSOR) /* XXX XXX XXX */ - if (cpu_id != hwrpb->rpb_primary_cpu_id) + if (CPU_IS_PRIMARY(ci) == 0) return; #endif uvmexp.intrs++; @@ -164,7 +229,7 @@ interrupt(a0, a1, a2, framep) #endif "\n", a0, a1, a2 #if defined(MULTIPROCESSOR) - , cpu_id + , ci->ci_cpuid #endif ); panic("interrupt"); @@ -173,9 +238,9 @@ interrupt(a0, a1, a2, framep) } void -set_iointr(niointr) - void (*niointr) __P((void *, unsigned long)); +set_iointr(void (*niointr)(void *, unsigned long)) { + if (platform.iointr) panic("set iointr twice"); platform.iointr = niointr; @@ -183,10 +248,8 @@ set_iointr(niointr) void -machine_check(mces, framep, vector, param) - unsigned long mces; - struct trapframe *framep; - unsigned long vector, param; +machine_check(unsigned long mces, struct trapframe *framep, + unsigned long vector, unsigned long param) { const char *type; struct mchkinfo *mcp; @@ -242,18 +305,13 @@ fatal: } int -badaddr(addr, size) - void *addr; - size_t size; +badaddr(void *addr, size_t size) { return(badaddr_read(addr, size, NULL)); } int -badaddr_read(addr, size, rptr) - void *addr; - size_t size; - void *rptr; +badaddr_read(void *addr, size_t size, void *rptr) { struct mchkinfo *mcp = &curcpu()->ci_mcinfo; long rcpt; @@ -325,3 +383,148 @@ badaddr_read(addr, size, rptr) /* Return non-zero (i.e. true) if it's a bad address. */ return (rv); } + +void +netintr() +{ + int n, s; + + s = splhigh(); + n = netisr; + netisr = 0; + splx(s); + +#define DONETISR(bit, fn) \ + do { \ + if (n & (1 << (bit))) \ + fn(); \ + } while (0) + +#include <net/netisr_dispatch.h> + +#undef DONETISR +} + +struct alpha_soft_intr alpha_soft_intrs[IPL_NSOFT]; + +/* XXX For legacy software interrupts. */ +struct alpha_soft_intrhand *softnet_intrhand, *softclock_intrhand; + +/* + * softintr_init: + * + * Initialize the software interrupt system. + */ +void +softintr_init() +{ + struct alpha_soft_intr *asi; + int i; + + for (i = 0; i < IPL_NSOFT; i++) { + asi = &alpha_soft_intrs[i]; + LIST_INIT(&asi->softintr_q); + simple_lock_init(&asi->softintr_slock); + asi->softintr_ipl = i; + } + + /* XXX Establish legacy software interrupt handlers. */ + softnet_intrhand = softintr_establish(IPL_SOFTNET, + (void (*)(void *))netintr, NULL); + softclock_intrhand = softintr_establish(IPL_SOFTCLOCK, + (void (*)(void *))softclock, NULL); + + assert(softnet_intrhand != NULL); + assert(softclock_intrhand != NULL); +} + +/* + * softintr_dispatch: + * + * Process pending software interrupts. + */ +void +softintr_dispatch() +{ + struct alpha_soft_intr *asi; + struct alpha_soft_intrhand *sih; + u_int64_t n, i; + + while ((n = atomic_loadlatch_ulong(&ssir, 0)) != 0) { + for (i = 0; i < IPL_NSOFT; i++) { + if ((n & (1 << i)) == 0) + continue; + asi = &alpha_soft_intrs[i]; + + /* Already at splsoft() */ + simple_lock(&asi->softintr_slock); + + for (sih = LIST_FIRST(&asi->softintr_q); + sih != NULL; + sih = LIST_NEXT(sih, sih_q)) { + if (sih->sih_pending) { + uvmexp.softs++; + sih->sih_pending = 0; + (*sih->sih_fn)(sih->sih_arg); + } + } + + simple_unlock(&asi->softintr_slock); + } + } +} + +/* + * softintr_establish: [interface] + * + * Register a software interrupt handler. + */ +void * +softintr_establish(int ipl, void (*func)(void *), void *arg) +{ + struct alpha_soft_intr *asi; + struct alpha_soft_intrhand *sih; + int s; + + if (__predict_false(ipl >= IPL_NSOFT || ipl < 0)) + panic("softintr_establish"); + + asi = &alpha_soft_intrs[ipl]; + + sih = malloc(sizeof(*sih), M_DEVBUF, M_NOWAIT); + if (__predict_true(sih != NULL)) { + sih->sih_intrhead = asi; + sih->sih_fn = func; + sih->sih_arg = arg; + sih->sih_pending = 0; + s = splsoft(); + simple_lock(&asi->softintr_slock); + LIST_INSERT_HEAD(&asi->softintr_q, sih, sih_q); + simple_unlock(&asi->softintr_slock); + splx(s); + } + return (sih); +} + +/* + * softintr_disestablish: [interface] + * + * Unregister a software interrupt handler. + */ +void +softintr_disestablish(void *arg) +{ + struct alpha_soft_intrhand *sih = arg; + struct alpha_soft_intr *asi = sih->sih_intrhead; + int s; + + (void) asi; /* XXX Unused if simple locks are noops. */ + + s = splsoft(); + simple_lock(&asi->softintr_slock); + LIST_REMOVE(sih, sih_q); + simple_unlock(&asi->softintr_slock); + splx(s); + + free(sih, M_DEVBUF); +} diff --git a/sys/arch/alpha/alpha/locore.s b/sys/arch/alpha/alpha/locore.s index 7278aa8981a..8c1d9ddc315 100644 --- a/sys/arch/alpha/alpha/locore.s +++ b/sys/arch/alpha/alpha/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.16 2001/06/11 08:51:20 art Exp $ */ +/* $OpenBSD: locore.s,v 1.17 2001/09/30 13:08:45 art Exp $ */ /* $NetBSD: locore.s,v 1.80 2000/09/04 00:31:59 thorpej Exp $ */ /*- @@ -384,7 +384,7 @@ LEAF(exception_return, 1) /* XXX should be NESTED */ 5: ldiq a0, ALPHA_PSL_IPL_SOFT call_pal PAL_OSF1_swpipl mov v0, s2 /* remember old IPL */ - CALL(do_sir) + CALL(softintr_dispatch) /* SIR handled; restore IPL and check again */ mov s2, a0 diff --git a/sys/arch/alpha/alpha/machdep.c b/sys/arch/alpha/alpha/machdep.c index 6c83730e370..6d62c55932d 100644 --- a/sys/arch/alpha/alpha/machdep.c +++ b/sys/arch/alpha/alpha/machdep.c @@ -1,5 +1,5 @@ -/* $OpenBSD: machdep.c,v 1.54 2001/09/19 20:50:55 mickey Exp $ */ -/* $NetBSD: machdep.c,v 1.206 2000/05/23 05:12:54 thorpej Exp $ */ +/* $OpenBSD: machdep.c,v 1.55 2001/09/30 13:08:45 art Exp $ */ +/* $NetBSD: machdep.c,v 1.210 2000/06/01 17:12:38 thorpej Exp $ */ /*- * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc. @@ -71,6 +71,7 @@ #include <sys/kernel.h> #include <sys/map.h> #include <sys/proc.h> +#include <sys/sched.h> #include <sys/buf.h> #include <sys/reboot.h> #include <sys/device.h> @@ -123,36 +124,14 @@ #include <ddb/db_extern.h> #endif -#include <net/netisr.h> -#include <net/if.h> - -#ifdef INET -#include <netinet/in.h> -#include <netinet/if_ether.h> -#include <netinet/ip_var.h> -#endif - -#ifdef INET6 -# ifndef INET -# include <netinet/in.h> -# endif -#include <netinet/ip6.h> -#include <netinet6/ip6_var.h> -#endif - -#include "ppp.h" -#include "bridge.h" - #include "le_ioasic.h" /* for le_iomem creation */ int cpu_dump __P((void)); int cpu_dumpsize __P((void)); u_long cpu_dump_mempagecnt __P((void)); -void do_sir __P((void)); void dumpsys __P((void)); caddr_t allocsys __P((caddr_t)); void identifycpu __P((void)); -void netintr __P((void)); void regdump __P((struct trapframe *framep)); void printregs __P((struct reg *)); @@ -184,6 +163,8 @@ int unknownmem; /* amount of memory with an unknown use */ int cputype; /* system type, from the RPB */ +int bootdev_debug = 0; /* patchable, or from DDB */ + /* * XXX We need an address to which we can assign things so that they * won't be optimized away because we didn't use the value. @@ -203,11 +184,6 @@ u_int64_t cycles_per_usec; /* number of cpus in the box. really! */ int ncpus; -#if !defined(MULTIPROCESSOR) -/* A single machine check info structure for single CPU configurations. */ -struct mchkinfo mchkinfo_store; -#endif - struct bootinfo_kernel bootinfo; /* For built-in TCDS */ @@ -248,7 +224,7 @@ alpha_init(pfn, ptb, bim, bip, biv) vsize_t size; char *p; caddr_t v; - char *bootinfo_msg; + const char *bootinfo_msg; const struct cpuinit *c; extern caddr_t esym; struct cpu_info *ci; @@ -1855,58 +1831,13 @@ setregs(p, pack, stack, retval) retval[0] = retval[1] = 0; } -void -netintr() -{ - int n, s; - - s = splhigh(); - n = netisr; - netisr = 0; - splx(s); - -#define DONETISR(bit, fn) \ - do { \ - if (n & (1 << (bit))) \ - fn(); \ - } while (0) - -#include <net/netisr_dispatch.h> - -#undef DONETISR -} - -void -do_sir() -{ - u_int64_t n; - - while ((n = atomic_loadlatch_ulong(&ssir, 0)) != 0) { -#define COUNT_SOFT uvmexp.softs++ - -#define DO_SIR(bit, fn) \ - do { \ - if (n & (bit)) { \ - COUNT_SOFT; \ - fn; \ - } \ - } while (0) - - DO_SIR(SIR_NET, netintr()); - DO_SIR(SIR_CLOCK, softclock()); - -#undef COUNT_SOFT -#undef DO_SIR - } -} - int spl0() { if (ssir) { (void) alpha_pal_swpipl(ALPHA_PSL_IPL_SOFT); - do_sir(); + softintr_dispatch(); } return (alpha_pal_swpipl(ALPHA_PSL_IPL_0)); @@ -1927,6 +1858,10 @@ spl0() * Call should be made at splclock(), and p->p_stat should be SRUN. */ +/* XXXART - grmble */ +#define sched_qs qs +#define sched_whichqs whichqs + void setrunqueue(p) struct proc *p; @@ -1938,11 +1873,11 @@ setrunqueue(p) panic("setrunqueue"); bit = p->p_priority >> 2; - whichqs |= (1 << bit); - p->p_forw = (struct proc *)&qs[bit]; - p->p_back = qs[bit].ph_rlink; + sched_whichqs |= (1 << bit); + p->p_forw = (struct proc *)&sched_qs[bit]; + p->p_back = sched_qs[bit].ph_rlink; p->p_back->p_forw = p; - qs[bit].ph_rlink = p; + sched_qs[bit].ph_rlink = p; } /* @@ -1957,15 +1892,15 @@ remrunqueue(p) int bit; bit = p->p_priority >> 2; - if ((whichqs & (1 << bit)) == 0) + if ((sched_whichqs & (1 << bit)) == 0) panic("remrunqueue"); p->p_back->p_forw = p->p_forw; p->p_forw->p_back = p->p_back; p->p_back = NULL; /* for firewall checking. */ - if ((struct proc *)&qs[bit] == qs[bit].ph_link) - whichqs &= ~(1 << bit); + if ((struct proc *)&sched_qs[bit] == sched_qs[bit].ph_link) + sched_whichqs &= ~(1 << bit); } /* diff --git a/sys/arch/alpha/include/intr.h b/sys/arch/alpha/include/intr.h index 6fb510601a2..9c8f150b151 100644 --- a/sys/arch/alpha/include/intr.h +++ b/sys/arch/alpha/include/intr.h @@ -1,5 +1,41 @@ -/* $OpenBSD: intr.h,v 1.11 2001/07/09 18:55:22 millert Exp $ */ -/* $NetBSD: intr.h,v 1.25 2000/05/23 05:12:56 thorpej Exp $ */ +/* $OpenBSD: intr.h,v 1.12 2001/09/30 13:08:45 art Exp $ */ +/* $NetBSD: intr.h,v 1.26 2000/06/03 20:47:41 thorpej Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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) 1997 Christopher G. Demetriou. All rights reserved. @@ -32,16 +68,36 @@ #ifndef _ALPHA_INTR_H_ #define _ALPHA_INTR_H_ +#include <sys/lock.h> #include <sys/queue.h> #include <machine/atomic.h> -#define IPL_NONE 0 /* disable only this interrupt */ +/* + * Alpha interrupts come in at one of 4 levels: + * + * software interrupt level + * i/o level 1 + * i/o level 2 + * clock level + * + * However, since we do not have any way to know which hardware + * level a particular i/o interrupt comes in on, we have to + * whittle it down to 3. + */ + +#define IPL_NONE 1 /* disable only this interrupt */ #define IPL_BIO 1 /* disable block I/O interrupts */ -#define IPL_NET 2 /* disable network interrupts */ -#define IPL_TTY 3 /* disable terminal interrupts */ -#define IPL_CLOCK 4 /* disable clock interrupts */ -#define IPL_HIGH 5 /* disable all interrupts */ -#define IPL_SERIAL 6 /* disable serial interrupts */ +#define IPL_NET 1 /* disable network interrupts */ +#define IPL_TTY 1 /* disable terminal interrupts */ +#define IPL_CLOCK 2 /* disable clock interrupts */ +#define IPL_HIGH 3 /* disable all interrupts */ +#define IPL_SERIAL 1 /* disable serial interrupts */ + +#define IPL_SOFTSERIAL 0 /* serial software interrupts */ +#define IPL_SOFTNET 1 /* network software interrupts */ +#define IPL_SOFTCLOCK 2 /* clock software interrupts */ +#define IPL_SOFT 3 /* other software interrupts */ +#define IPL_NSOFT 4 #define IST_UNUSABLE -1 /* interrupt cannot be used */ #define IST_NONE 0 /* none (dummy) */ @@ -82,21 +138,6 @@ _splraise(s) #define spllpt() spltty() /* - * simulated software interrupt register - */ -extern u_long ssir; - -#define SIR_NET 0x1 -#define SIR_CLOCK 0x2 -#define SIR_SERIAL 0x4 - -#define setsoft(x) atomic_setbits_ulong(&ssir, (x)) - -#define setsoftnet() setsoft(SIR_NET) -#define setsoftclock() setsoft(SIR_CLOCK) -#define setsoftserial() setsoft(SIR_SERIAL) - -/* * Interprocessor interrupts. In order how we want them processed. */ #define ALPHA_IPI_HALT 0x0000000000000001UL @@ -142,6 +183,49 @@ struct alpha_shared_intr { ((asi)[num].intr_maxstrays != 0 && \ (asi)[num].intr_nstrays == (asi)[num].intr_maxstrays) +/* + * simulated software interrupt register + */ +extern unsigned long ssir; + +#define setsoft(x) atomic_setbits_ulong(&ssir, 1 << (x)) + +#define __GENERIC_SOFT_INTERRUPTS +struct alpha_soft_intrhand { + LIST_ENTRY(alpha_soft_intrhand) + sih_q; + struct alpha_soft_intr *sih_intrhead; + void (*sih_fn) __P((void *)); + void *sih_arg; + int sih_pending; +}; + +struct alpha_soft_intr { + LIST_HEAD(, alpha_soft_intrhand) + softintr_q; + struct simplelock softintr_slock; + unsigned long softintr_ipl; +}; + +void *softintr_establish __P((int, void (*)(void *), void *)); +void softintr_disestablish __P((void *)); +void softintr_init __P((void)); +void softintr_dispatch __P((void)); + +#define softintr_schedule(arg) \ +do { \ + struct alpha_soft_intrhand *__sih = (arg); \ + __sih->sih_pending = 1; \ + setsoft(__sih->sih_intrhead->softintr_ipl); \ +} while (0) + +/* XXX For legacy software interrupts. */ +extern struct alpha_soft_intrhand *softnet_intrhand; +extern struct alpha_soft_intrhand *softclock_intrhand; + +#define setsoftnet() softintr_schedule(softnet_intrhand) +#define setsoftclock() softintr_schedule(softclock_intrhand) + struct alpha_shared_intr *alpha_shared_intr_alloc __P((unsigned int)); int alpha_shared_intr_dispatch __P((struct alpha_shared_intr *, unsigned int)); |