summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2001-09-30 13:08:46 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2001-09-30 13:08:46 +0000
commit276b7ad2c1e4c0e220da383c14f3b7b3f103cce2 (patch)
tree83994406d0980124b24ff02635c98ea7f1c6a9af
parentae4a0c6ae45069be7305338b28703dd8afb99ad4 (diff)
Generic soft interrupts from NetBSD plus some minor cleanups.
-rw-r--r--sys/arch/alpha/alpha/autoconf.c4
-rw-r--r--sys/arch/alpha/alpha/interrupt.c263
-rw-r--r--sys/arch/alpha/alpha/locore.s4
-rw-r--r--sys/arch/alpha/alpha/machdep.c101
-rw-r--r--sys/arch/alpha/include/intr.h130
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));