summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2002-12-17 21:54:26 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2002-12-17 21:54:26 +0000
commit7f33aa2f59d67ead13e253a82b4241d038e46a5d (patch)
tree0d8e42d725d944bbed37154b421ab258da5a95e6 /sys
parentc86b06b8c90928864da380972228aea593140be3 (diff)
real interrupts/spl framework.
tested on 712/* 715/100, 715/33 which main cpu/bus types. miod@ ok
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/hppa/dev/asp.c58
-rw-r--r--sys/arch/hppa/dev/lasi.c74
-rw-r--r--sys/arch/hppa/gsc/gscbus.c92
-rw-r--r--sys/arch/hppa/gsc/gscbusvar.h12
-rw-r--r--sys/arch/hppa/hppa/autoconf.c8
-rw-r--r--sys/arch/hppa/hppa/intr.c246
-rw-r--r--sys/arch/hppa/hppa/locore.S192
-rw-r--r--sys/arch/hppa/hppa/trap.c76
-rw-r--r--sys/arch/hppa/hppa/vm_machdep.c5
-rw-r--r--sys/arch/hppa/include/autoconf.h9
-rw-r--r--sys/arch/hppa/include/intr.h216
-rw-r--r--sys/arch/hppa/include/trap.h4
12 files changed, 532 insertions, 460 deletions
diff --git a/sys/arch/hppa/dev/asp.c b/sys/arch/hppa/dev/asp.c
index 973fd94ef7c..66ee0028a67 100644
--- a/sys/arch/hppa/dev/asp.c
+++ b/sys/arch/hppa/dev/asp.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: asp.c,v 1.7 2002/04/22 01:48:37 mickey Exp $ */
+/* $OpenBSD: asp.c,v 1.8 2002/12/17 21:54:20 mickey Exp $ */
/*
- * Copyright (c) 1998,1999 Michael Shalayeff
+ * Copyright (c) 1998-2002 Michael Shalayeff
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -138,11 +138,6 @@ struct cfdriver asp_cd = {
NULL, "asp", DV_DULL
};
-void asp_intr_establish(void *v, u_int32_t mask);
-void asp_intr_disestablish(void *v, u_int32_t mask);
-u_int32_t asp_intr_check(void *v);
-void asp_intr_ack(void *v, u_int32_t mask);
-
int
aspmatch(parent, cfdata, aux)
struct device *parent;
@@ -203,10 +198,7 @@ aspattach(parent, self, aux)
sc->sc_ic.gsc_type = gsc_asp;
sc->sc_ic.gsc_dv = sc;
- sc->sc_ic.gsc_intr_establish = asp_intr_establish;
- sc->sc_ic.gsc_intr_disestablish = asp_intr_disestablish;
- sc->sc_ic.gsc_intr_check = asp_intr_check;
- sc->sc_ic.gsc_intr_ack = asp_intr_ack;
+ sc->sc_ic.gsc_base = sc->sc_trs;
ga.ga_ca = *ca; /* clone from us */
ga.ga_hpamask = ASP_IOMASK;
@@ -214,47 +206,3 @@ aspattach(parent, self, aux)
ga.ga_ic = &sc->sc_ic;
config_found(self, &ga, gscprint);
}
-
-void
-asp_intr_establish(v, mask)
- void *v;
- u_int32_t mask;
-{
- register struct asp_softc *sc = v;
-
- sc->sc_trs->asp_imr |= mask;
-}
-
-void
-asp_intr_disestablish(v, mask)
- void *v;
- u_int32_t mask;
-{
- register struct asp_softc *sc = v;
-
- sc->sc_trs->asp_imr &= ~mask;
-}
-
-u_int32_t
-asp_intr_check(v)
- void *v;
-{
- register struct asp_softc *sc = v;
- register u_int32_t irr, imr;
-
- imr = sc->sc_trs->asp_imr;
- irr = sc->sc_trs->asp_irr;
- sc->sc_trs->asp_imr = imr & ~irr;
-
- return irr;
-}
-
-void
-asp_intr_ack(v, mask)
- void *v;
- u_int32_t mask;
-{
- register struct asp_softc *sc = v;
-
- sc->sc_trs->asp_imr |= mask;
-}
diff --git a/sys/arch/hppa/dev/lasi.c b/sys/arch/hppa/dev/lasi.c
index 0b634fc94f0..f0614519c95 100644
--- a/sys/arch/hppa/dev/lasi.c
+++ b/sys/arch/hppa/dev/lasi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lasi.c,v 1.9 2002/04/22 01:48:37 mickey Exp $ */
+/* $OpenBSD: lasi.c,v 1.10 2002/12/17 21:54:20 mickey Exp $ */
/*
* Copyright (c) 1998-2002 Michael Shalayeff
@@ -39,6 +39,7 @@
#include <machine/bus.h>
#include <machine/iomod.h>
+#include <machine/reg.h>
#include <machine/autoconf.h>
#include <hppa/dev/cpudevs.h>
@@ -50,7 +51,7 @@
struct lasi_hwr {
u_int32_t lasi_power;
#define LASI_BLINK 0x01
-#define LASI_ON 0x02
+#define LASI_OFF 0x02
u_int32_t lasi_error;
u_int32_t lasi_version;
u_int32_t lasi_reset;
@@ -86,13 +87,8 @@ struct cfdriver lasi_cd = {
NULL, "lasi", DV_DULL
};
-void lasi_intr_establish(void *v, u_int32_t mask);
-void lasi_intr_disestablish(void *v, u_int32_t mask);
-u_int32_t lasi_intr_check(void *v);
-void lasi_intr_ack(void *v, u_int32_t mask);
void lasi_cold_hook(int on);
-
int
lasimatch(parent, cfdata, aux)
struct device *parent;
@@ -133,8 +129,8 @@ lasiattach(parent, self, aux)
/* XXX should we reset the chip here? */
- printf (": rev %d.%d\n", (sc->sc_hw->lasi_version & 0xf0) >> 4,
- sc->sc_hw->lasi_version & 0xf);
+ printf(": rev %d.%d\n", (sc->sc_hw->lasi_version & 0xf0) >> 4,
+ sc->sc_hw->lasi_version & 0xf);
/* interrupts guts */
s = splhigh();
@@ -147,13 +143,9 @@ lasiattach(parent, self, aux)
sc->sc_ic.gsc_type = gsc_lasi;
sc->sc_ic.gsc_dv = sc;
- sc->sc_ic.gsc_intr_establish = lasi_intr_establish;
- sc->sc_ic.gsc_intr_disestablish = lasi_intr_disestablish;
- sc->sc_ic.gsc_intr_check = lasi_intr_check;
- sc->sc_ic.gsc_intr_ack = lasi_intr_ack;
+ sc->sc_ic.gsc_base = sc->sc_trs;
sc->ga.ga_ca = *ca; /* clone from us */
- sc->ga.ga_hpamask = LASI_IOMASK;
if (sc->sc_dev.dv_unit)
config_defer(self, lasi_gsc_attach);
else {
@@ -171,6 +163,7 @@ lasi_gsc_attach(self)
struct lasi_softc *sc = (struct lasi_softc *)self;
sc->ga.ga_name = "gsc";
+ sc->ga.ga_hpamask = LASI_IOMASK;
sc->ga.ga_ic = &sc->sc_ic;
config_found(self, &sc->ga, gscprint);
}
@@ -192,58 +185,7 @@ lasi_cold_hook(on)
sc->sc_hw->lasi_power = 0;
break;
case HPPA_COLD_OFF:
- sc->sc_hw->lasi_power = LASI_BLINK;
+ sc->sc_hw->lasi_power = LASI_OFF;
break;
}
}
-
-void
-lasi_intr_establish(v, mask)
- void *v;
- u_int32_t mask;
-{
- register struct lasi_softc *sc = v;
-
- sc->sc_trs->lasi_imr |= mask;
-}
-
-void
-lasi_intr_disestablish(v, mask)
- void *v;
- u_int32_t mask;
-{
- register struct lasi_softc *sc = v;
-
- sc->sc_trs->lasi_imr &= ~mask;
-}
-
-u_int32_t
-lasi_intr_check(v)
- void *v;
-{
- register struct lasi_softc *sc = v;
- register u_int32_t irr, imr, ipr;
-
- imr = sc->sc_trs->lasi_imr;
- ipr = sc->sc_trs->lasi_ipr;
- irr = sc->sc_trs->lasi_irr;
- sc->sc_trs->lasi_irr = irr;
-
-#ifdef LASIDEBUG
- printf ("%s: imr=0x%x, irr=0x%x, ipr=0x%x, iar=0x%x, icr=0x%x\n",
- sc->sc_dev.dv_xname, imr, irr, ipr,
- sc->sc_trs->lasi_iar, sc->sc_trs->lasi_icr);
-#endif
-
- return irr;
-}
-
-void
-lasi_intr_ack(v, mask)
- void *v;
- u_int32_t mask;
-{
- register struct lasi_softc *sc = v;
-
- sc->sc_trs->lasi_imr |= mask;
-}
diff --git a/sys/arch/hppa/gsc/gscbus.c b/sys/arch/hppa/gsc/gscbus.c
index 17f05725776..35e42354386 100644
--- a/sys/arch/hppa/gsc/gscbus.c
+++ b/sys/arch/hppa/gsc/gscbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gscbus.c,v 1.19 2002/03/14 01:26:31 millert Exp $ */
+/* $OpenBSD: gscbus.c,v 1.20 2002/12/17 21:54:25 mickey Exp $ */
/*
* Copyright (c) 1998 Michael Shalayeff
@@ -134,13 +134,11 @@ gscattach(parent, self, aux)
struct device *self;
void *aux;
{
- register struct gsc_softc *sc = (struct gsc_softc *)self;
- register struct gsc_attach_args *ga = aux;
+ struct gsc_softc *sc = (struct gsc_softc *)self;
+ struct gsc_attach_args *ga = aux;
sc->sc_iot = ga->ga_iot;
sc->sc_ic = ga->ga_ic;
- sc->sc_intrmask = 0;
- bzero(sc->sc_intrvs, sizeof(sc->sc_intrvs));
#ifdef USELEDS
if (machine_ledaddr)
@@ -148,8 +146,9 @@ gscattach(parent, self, aux)
#endif
printf ("\n");
- sc->sc_ih = cpu_intr_establish(IPL_IO, ga->ga_irq,
- gsc_intr, sc, &sc->sc_dev);
+ sc->sc_ih = cpu_intr_establish(IPL_NESTED, ga->ga_irq,
+ gsc_intr, (void *)sc->sc_ic->gsc_base, &sc->sc_dev);
+
/* DMA guts */
sc->sc_dmatag._cookie = sc;
sc->sc_dmatag._dmamap_create = gsc_dmamap_create;
@@ -183,7 +182,6 @@ gscprint(aux, pnp)
return (UNCONF);
}
-
void *
gsc_intr_establish(sc, pri, irq, handler, arg, dv)
struct gsc_softc *sc;
@@ -193,29 +191,19 @@ gsc_intr_establish(sc, pri, irq, handler, arg, dv)
void *arg;
struct device *dv;
{
- register struct gscbus_intr *iv;
- register u_int32_t mask;
+ volatile u_int32_t *r = sc->sc_ic->gsc_base;
+ void *iv;
- mask = 1 << irq;
- if (sc->sc_intrmask & mask) {
+ if ((iv = cpu_intr_map(sc->sc_ih, pri, irq, handler, arg, dv)))
+ r[1] |= (1 << irq);
+ else {
#ifdef GSCDEBUG
printf("%s: attaching irq %d, already occupied\n",
sc->sc_dev.dv_xname, irq);
#endif
- return NULL;
}
- sc->sc_intrmask |= mask;
- iv = &sc->sc_intrvs[irq];
- iv->pri = pri;
- iv->handler = handler;
- iv->arg = arg;
- evcnt_attach(dv, dv->dv_xname, &iv->evcnt);
- (sc->sc_ic->gsc_intr_establish)(sc->sc_ic->gsc_dv, mask);
-#ifdef GSCDEBUG
- printf("gsc_intr_establish: mask=0x%08x irq=%d iv=%p\n", mask, irq, iv);
-#endif
- return &sc->sc_intrvs[irq];
+ return (iv);
}
void
@@ -223,61 +211,13 @@ gsc_intr_disestablish(sc, v)
struct gsc_softc *sc;
void *v;
{
- register u_int32_t mask;
-
- mask = 1 << (sc->sc_intrvs - (struct gscbus_intr *)v);
- sc->sc_intrmask &= ~mask;
- ((struct gscbus_intr *)v)->handler = NULL;
- /* evcnt_detach(); */
- (sc->sc_ic->gsc_intr_disestablish)(sc->sc_ic->gsc_dv, mask);
-}
-
-int
-gsc_intr(v)
- void *v;
-{
- register struct gsc_softc *sc = v;
- register struct gscbus_ic *ic = sc->sc_ic;
- register u_int32_t mask;
- int ret;
+#if notyet
+ volatile u_int32_t *r = sc->sc_ic->gsc_base;
-#ifdef GSCDEBUG_INTR
- printf("gsc_intr(%p)\n", v);
-#endif
- ret = 0;
- while ((mask = (ic->gsc_intr_check)(ic->gsc_dv))) {
- register int i;
- register struct gscbus_intr *iv;
+ r[1] &= ~(1 << irq);
- i = ffs(mask) - 1;
- iv = &sc->sc_intrvs[i];
-
-#ifdef GSCDEBUG_INTR
- printf("gsc_intr: got mask=0x%08x i=%d iv=%p\n", mask, i, iv);
-#endif
- if (iv->handler) {
- int s;
-#ifdef GSCDEBUG_INTR
- printf("gsc_intr: calling %p for irq %d\n", v, i);
+ cpu_intr_unmap(sc->sc_ih, v);
#endif
- iv->evcnt.ev_count++;
- s = splraise(iv->pri);
- ret = (iv->handler)(iv->arg);
- splx(s);
-#ifdef GSCDEBUG_INTR
- if (!ret)
- printf ("%s: can't handle interrupt\n",
- iv->evcnt.ev_name);
-#endif
- ret = 1;
- } else
- printf("%s: stray interrupt %d\n",
- sc->sc_dev.dv_xname, i);
-
- (ic->gsc_intr_ack)(ic->gsc_dv, 1 << i);
- }
-
- return ret;
}
int
diff --git a/sys/arch/hppa/gsc/gscbusvar.h b/sys/arch/hppa/gsc/gscbusvar.h
index b6721abe5b4..5f7bac54ba2 100644
--- a/sys/arch/hppa/gsc/gscbusvar.h
+++ b/sys/arch/hppa/gsc/gscbusvar.h
@@ -1,7 +1,7 @@
-/* $OpenBSD: gscbusvar.h,v 1.7 2002/03/14 03:15:53 millert Exp $ */
+/* $OpenBSD: gscbusvar.h,v 1.8 2002/12/17 21:54:25 mickey Exp $ */
/*
- * Copyright (c) 1998 Michael Shalayeff
+ * Copyright (c) 1998-2002 Michael Shalayeff
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,11 +33,7 @@
struct gscbus_ic {
enum {gsc_unknown = 0, gsc_lasi, gsc_wax, gsc_asp} gsc_type;
void *gsc_dv;
-
- void (*gsc_intr_establish)(void *v, u_int32_t mask);
- void (*gsc_intr_disestablish)(void *v, u_int32_t mask);
- u_int32_t (*gsc_intr_check)(void *v);
- void (*gsc_intr_ack)(void *v, u_int32_t mask);
+ volatile void *gsc_base;
};
struct gsc_attach_args {
@@ -58,6 +54,8 @@ struct gscbus_intr {
int pri;
int (*handler)(void *);
void *arg;
+ void *softc;
+ void *cpuiv;
struct evcnt evcnt;
};
diff --git a/sys/arch/hppa/hppa/autoconf.c b/sys/arch/hppa/hppa/autoconf.c
index 018ac157c05..dbd29bc52c5 100644
--- a/sys/arch/hppa/hppa/autoconf.c
+++ b/sys/arch/hppa/hppa/autoconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: autoconf.c,v 1.22 2002/10/07 15:32:37 mickey Exp $ */
+/* $OpenBSD: autoconf.c,v 1.23 2002/12/17 21:54:25 mickey Exp $ */
/*
* Copyright (c) 1998-2001 Michael Shalayeff
@@ -69,7 +69,6 @@ int findblkmajor(struct device *dv);
const char *findblkname(int maj);
void (*cold_hook)(int); /* see below */
-register_t kpsw = PSL_Q | PSL_P | PSL_C | PSL_D;
/*
* LED blinking thing
@@ -93,15 +92,12 @@ cpu_configure()
if (config_rootfound("mainbus", "mainbus") == NULL)
panic("no mainbus found");
- /* in spl*() we trust */
- __asm __volatile("ssm %0, %%r0" :: "i" (PSL_I));
- kpsw |= PSL_I;
+ cpu_intr_init();
spl0();
setroot();
swapconf();
dumpconf();
- cold = 0;
if (cold_hook)
(*cold_hook)(HPPA_COLD_HOT);
diff --git a/sys/arch/hppa/hppa/intr.c b/sys/arch/hppa/hppa/intr.c
index 4b4a1282942..c4d847c3e2f 100644
--- a/sys/arch/hppa/hppa/intr.c
+++ b/sys/arch/hppa/hppa/intr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.c,v 1.3 2002/09/23 06:11:47 mickey Exp $ */
+/* $OpenBSD: intr.c,v 1.4 2002/12/17 21:54:25 mickey Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff
@@ -31,102 +31,200 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* #define INTRDEBUG */
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/device.h>
+#include <net/netisr.h>
+
#include <machine/autoconf.h>
+#include <machine/frame.h>
#include <machine/reg.h>
-#ifdef DDB
-#include <machine/db_machdep.h>
-#endif
-
-#ifdef INTRDEBUG
-#include <ddb/db_output.h>
-#endif
+void softnet(void);
+void softtty(void);
-/* all the interrupts, minus cpu clock, which is the last */
-struct cpu_intr_vector {
- struct evcnt evcnt;
- int pri;
+struct hppa_iv {
+ char pri;
+ char bit;
+ char flags;
+#define HPPA_IV_CALL 0x01
+#define HPPA_IV_SOFT 0x02
+ char pad;
int (*handler)(void *);
void *arg;
-} cpu_intr_vectors[CPU_NINTS];
+ struct hppa_iv *next;
+} __attribute__((__packed__));
+
+register_t kpsw = PSL_Q | PSL_P | PSL_C | PSL_D;
+volatile int cpl = IPL_NESTED;
+volatile u_long ipending, imask[NIPL];
+u_long cpu_mask;
+struct hppa_iv *intr_list, intr_store[8*CPU_NINTS], *intr_more = intr_store;
+struct hppa_iv intr_table[CPU_NINTS] = {
+ { IPL_SOFTCLOCK, 0, HPPA_IV_SOFT, 0, (int (*)(void *))&softclock },
+ { IPL_SOFTNET , 0, HPPA_IV_SOFT, 0, (int (*)(void *))&softnet },
+ { 0 }, { 0 },
+ { IPL_SOFTTTY , 0, HPPA_IV_SOFT, 0, (int (*)(void *))&softtty }
+};
+
+#ifdef DIAGNOSTIC
+void
+splassert_check(int wantipl, const char *func)
+{
+ if (cpl < wantipl) {
+ splassert_fail(wantipl, cpl, func);
+ }
+}
+#endif
+
+void
+softnet(void)
+{
+ int ni;
+
+ /* use atomic "load & clear" */
+ __asm __volatile(
+ "ldcws 0(%2), %0": "=&r" (ni), "+m" (netisr): "r" (&netisr));
+#define DONETISR(m,c) if (ni & (1 << (m))) c()
+#include <net/netisr_dispatch.h>
+}
+
+void
+softtty(void)
+{
+
+}
+
+void
+cpu_intr_init()
+{
+ u_long mask = cpu_mask | SOFTINT_MASK;
+ int level;
+
+ /* map the shared ints */
+ while (intr_list) {
+ struct hppa_iv *iv = intr_list;
+ int bit = ffs(imask[(int)iv->pri]);
+ intr_list = iv->next;
+
+ if (!bit--) {
+ bit = ffs(~mask);
+ if (!bit--)
+ panic("cpu_intr_init: out of bits");
+
+ iv->next = NULL;
+ iv->bit = 31 - bit;
+ intr_table[bit] = *iv;
+ mask |= (1 << bit);
+ imask[(int)iv->pri] |= (1 << bit);
+ } else {
+ iv->bit = 31 - bit;
+ iv->next = intr_table[bit].next;
+ intr_table[bit].next = iv;
+ }
+ }
+
+ /* match the init for intr_table */
+ imask[IPL_SOFTCLOCK] = 1 << (IPL_SOFTCLOCK - 1);
+ imask[IPL_SOFTNET ] = 1 << (IPL_SOFTNET - 1);
+ imask[IPL_SOFTTTY ] = 1 << (IPL_SOFTTTY - 1);
+
+ for (level = 0; level < NIPL - 1; level++)
+ imask[level + 1] |= imask[level];
+
+ printf("biomask 0x%x netmask 0x%x ttymask 0x%x\n",
+ imask[IPL_BIO], imask[IPL_NET], imask[IPL_TTY]);
+
+ /* XXX the whacky trick is to prevent hardclock from happenning */
+ mfctl(CR_ITMR, mask);
+ mtctl(mask - 1, CR_ITMR);
+
+ cold = 0;
+
+ /* in spl*() we trust, clock is enabled in initclocks() */
+ mtctl(cpu_mask, CR_EIEM);
+ kpsw |= PSL_I;
+ __asm __volatile("ssm %0, %%r0" :: "i" (PSL_I));
+}
void *
-cpu_intr_establish(pri, irq, handler, arg, dv)
- int pri, irq;
- int (*handler)(void *);
- void *arg;
- struct device *dv;
+cpu_intr_map(void *v, int pri, int irq, int (*handler)(void *), void *arg, struct device *dv)
+{
+ struct hppa_iv *iv, *pv = v, *ivb = pv->next;
+
+ if (irq < 0 || irq >= CPU_NINTS || ivb[irq].handler)
+ return (NULL);
+
+ iv = &ivb[irq];
+ iv->pri = pri;
+ iv->bit = irq;
+ iv->flags = 0;
+ iv->handler = handler;
+ iv->arg = arg;
+ iv->next = intr_list;
+ intr_list = iv;
+
+ return (iv);
+}
+
+void *
+cpu_intr_establish(int pri, int irq, int (*handler)(void *), void *arg, struct device *dv)
{
- register struct cpu_intr_vector *iv;
+ struct hppa_iv *iv;
- if (0 <= irq && irq < CPU_NINTS && cpu_intr_vectors[irq].handler)
- return NULL;
+ if (irq < 0 || irq >= CPU_NINTS || intr_table[irq].handler)
+ return (NULL);
- iv = &cpu_intr_vectors[irq];
+ cpu_mask |= (1 << irq);
+ imask[pri] |= (1 << irq);
+
+ iv = &intr_table[irq];
iv->pri = pri;
+ iv->bit = 31 - irq;
+ iv->flags = 0;
iv->handler = handler;
iv->arg = arg;
- evcnt_attach(dv, dv->dv_xname, &iv->evcnt);
- return iv;
+ if (pri == IPL_NESTED) {
+ iv->flags = HPPA_IV_CALL;
+ iv->next = intr_more;
+ intr_more += CPU_NINTS;
+ } else
+ iv->next = NULL;
+
+ return (iv);
}
void
-cpu_intr(frame)
- struct trapframe *frame;
+cpu_intr(void *v)
{
- u_int32_t eirr = 0, r;
- register struct cpu_intr_vector *iv;
- register int bit;
-
- do {
- mfctl(CR_EIRR, r);
- eirr |= r;
-#ifdef INTRDEBUG
- if (eirr & 0x7fffffff)
- db_printf ("cpu_intr: 0x%08x & 0x%08x\n",
- eirr, frame->tf_eiem);
-#endif
- eirr &= frame->tf_eiem;
- bit = ffs(eirr) - 1;
- if (bit >= 0) {
- mtctl(1 << bit, CR_EIRR);
- eirr &= ~(1 << bit);
- /* ((struct iomod *)cpu_gethpa(0))->io_eir = 0; */
- if (bit != 31) {
-#ifdef INTRDEBUG
- db_printf ("cpu_intr: 0x%08x\n", (1 << bit));
-#endif
- frame->tf_flags |= TFF_INTR;
- } else
- frame->tf_flags &= ~TFF_INTR;
-
- iv = &cpu_intr_vectors[bit];
- if (iv->handler) {
- register int s, r;
-
- iv->evcnt.ev_count++;
- s = splraise(iv->pri);
- /* no arg means pass the frame */
- r = (iv->handler)(iv->arg? iv->arg:frame);
- splx(s);
-#ifdef INTRDEBUG
- if (!r)
- db_printf ("%s: can't handle interrupt\n",
- iv->evcnt.ev_name);
-#endif
- }
-#ifdef INTRDEBUG
- else
- db_printf ("cpu_intr: stray interrupt %d\n", bit);
-#endif
+ struct trapframe *frame = v;
+ u_long mask;
+ int s = cpl;
+
+ while ((mask = ipending & ~imask[s])) {
+ int r, bit = ffs(mask) - 1;
+ struct hppa_iv *iv = &intr_table[bit];
+
+ ipending &= ~(1L << bit);
+ if (iv->flags & HPPA_IV_CALL)
+ continue;
+
+ cpl = iv->pri;
+ mtctl(frame->tf_eiem, CR_EIEM);
+ for (r = iv->flags & HPPA_IV_SOFT;
+ iv && iv->handler; iv = iv->next)
+ /* no arg means pass the frame */
+ r |= (iv->handler)(iv->arg? iv->arg : v) == 1;
+#if 0 /* XXX this does not work, lasi gives us double ints */
+ if (!r) {
+ cpl = 0;
+ printf("stray interrupt %d\n", bit);
}
- } while (eirr);
+ mtctl(0, CR_EIEM);
+#endif
+ }
+ cpl = s;
}
diff --git a/sys/arch/hppa/hppa/locore.S b/sys/arch/hppa/hppa/locore.S
index c51e92eefa0..3d184bfede6 100644
--- a/sys/arch/hppa/hppa/locore.S
+++ b/sys/arch/hppa/hppa/locore.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.98 2002/12/09 18:36:33 mickey Exp $ */
+/* $OpenBSD: locore.S,v 1.99 2002/12/17 21:54:25 mickey Exp $ */
/*
* Copyright (c) 1998-2002 Michael Shalayeff
@@ -66,7 +66,7 @@
* CSL requests users of this software to return to csl-dist@cs.utah.edu any
* improvements that they make and grant CSL redistribution rights.
*
- * Utah $Hdr: locore.s 1.63 95/01/20$
+ * Utah $Hdr: locore.s 1.63 95/01/20$
*/
#include <sys/errno.h>
@@ -77,7 +77,6 @@
#include <machine/trap.h>
#include <machine/iomod.h>
#include <machine/pdc.h>
-#include <machine/intr.h>
#include <machine/frame.h>
#include <machine/reg.h>
#ifdef GPROF
@@ -130,16 +129,19 @@ intrnames
.asciz "lev6"
.asciz "lev7"
.asciz "lev8"
- .asciz "lev9"
+ .asciz "clock"
.asciz "lev10"
.asciz "lev11"
.asciz "lev12"
.asciz "lev13"
.asciz "lev14"
.asciz "lev15"
- .asciz "clock"
eintrnames
- .align NBPG
+ .export netisr, data
+ .align 16
+netisr
+ .word 0
+ .align 16
BSS(pdc_stack, 4) /* temp stack for PDC call */
BSS(emrg_stack, 4) /* stack for HPMC/TOC/PWRF */
@@ -155,14 +157,6 @@ eintrnames
BSS(fpu_enable, 4) /* bits to set in the ccr to enable fpu */
.export hppa_vtop, data
BSS(hppa_vtop, 4) /* a vtop translation table addr (pa=va) */
- .export netisr, data
- .align 16
-netisr
- .word 0
- .export sir, data
- .align 16
-sir
- .word 0
.text
.import $kernel_setup, entry
@@ -301,7 +295,6 @@ $virtual_mode
nop
break HPPA_BREAK_KERNEL, HPPA_BREAK_KGDB
- nop
$noddb
#endif
@@ -350,7 +343,7 @@ LEAF_ENTRY($kernel_setup)
* spl level into eiem, and reset any pending interrupts
*/
ldi -1, r1
- mtctl r0, eiem /* IPL_NONE */
+ mtctl r0, eiem
mtctl r1, eirr
/*
@@ -467,7 +460,6 @@ pdc_call_unmapped1
copy arg0, t4
ldi PSL_Q, arg0 /* (!pdc_flag && args[0] == PDC_PIM)? PSL_M:0) */
break HPPA_BREAK_KERNEL, HPPA_BREAK_SET_PSW
- nop
stw ret0, HPPA_FRAME_ARG(23)(sp)
copy t4, arg0
@@ -503,7 +495,6 @@ pdc_call_unmapped2
copy ret0, t3
ldw HPPA_FRAME_ARG(23)(sp), arg0
break HPPA_BREAK_KERNEL, HPPA_BREAK_SET_PSW
- nop
copy t3, ret0
pdc_call_unmapped3
@@ -746,7 +737,6 @@ $syscall
.entry
$syscall_return
/* t3 == VA trapframe */
- /* check for AST ? XXX */
/* splhigh(), just in case */
mtctl r0, eiem
@@ -977,7 +967,7 @@ hpmc_v
CTRAP(hpmc,T_HPMC,HPMCPRE) /* 1. high priority machine check */
ATRAP(power,T_POWERFAIL) /* 2. power failure */
ATRAP(recnt,T_RECOVERY) /* 3. recovery counter trap */
- ATRAP(intr,T_INTERRUPT) /* 4. external interrupt */
+ CTRAP(intr,T_INTERRUPT,) /* 4. external interrupt */
ATRAP(lpmc,T_LPMC) /* 5. low-priority machine check */
STRAP(itlb,T_ITLBMISS,ITLBPRE) /* 6. instruction TLB miss fault */
ATRAP(iprot,T_IPROT) /* 7. instruction protection trap */
@@ -1897,7 +1887,99 @@ ALTENTRY(hppa_pfr_end)
.word 0
EXIT(hppa_pfr)
- .align 32
+ .export TLABEL(intr), entry
+ .import cpl, data
+ .import ipending, data
+ .import imask, data
+ .import intr_table, data
+ENTRY(TLABEL(intr),0)
+
+ mfctl eirr, r8
+ mtctl r8, eirr /* ack now */
+
+ ldil L%ipending, r17
+ ldw R%ipending(r17), r24
+ ldil L%intr_table, r1
+ ldo R%intr_table(r1), r1
+$intr_ffs
+ addi 16, r1, r1
+ bb,>= r8, 31, $intr_ffs
+ shd r0, r8, 1, r8
+
+ ldb 2-16(r1), r17
+ ldw 4-16(r1), r9
+ subi,<> 1, r17, r0
+ bv,n r0(r9)
+ nop
+
+ mfctl sar, r25
+ ldb 1-16(r1), r9
+ mtsar r9
+ vdepi 1, 1, r24
+ mtsar r25
+
+ ldb 0-16(r1), r9
+ ldil L%intrcnt, r25
+ ldo R%intrcnt(r25), r25
+ sh2add r9, r25, r25
+ ldw 0(r25), r17
+ addi 1, r17, r17
+ stw r17, 0(r25)
+
+$intr_cont
+ comb,<> r0, r8, $intr_ffs
+ nop
+
+ ldil L%ipending, r17
+ stw r24, R%ipending(r17)
+ ldil L%cpl, r17
+ ldw R%cpl(r17), r17
+ ldil L%imask, r9
+ ldo R%imask(r9), r9
+ ldwx,s r17(r9), r16
+ ldi T_INTERRUPT, r1
+ andcm,= r24, r16, r0
+ b TLABEL(all)
+ nop
+
+ rfir
+ nop
+EXIT(TLABEL(intr))
+
+ .export gsc_intr, entry
+ENTRY(gsc_intr,0)
+
+ ldw 8-16(r1), r9 /* arg: ioreg */
+ mtctl r1, tr7
+ ldw 0(r9), r16 /* irr */
+
+ ldw 12-16(r1), r1 /* next: sub-intr_table */
+$gsc_ffs
+ addi 16, r1, r1
+ bb,>= r16, 31, $gsc_ffs
+ shd r0, r16, 1, r16
+
+ mfctl sar, r25
+ ldb 1-16(r1), r17
+ mtsar r17
+ vdepi 1, 1, r24
+ mtsar r25
+
+ ldb 0-16(r1), r17
+ ldil L%intrcnt, r25
+ ldo R%intrcnt(r25), r25
+ sh2add r17, r25, r25
+ ldw 0(r25), r17
+ addi 1, r17, r17
+ stw r17, 0(r25)
+
+ comb,<> r0, r16, $gsc_ffs
+ nop
+
+ b $intr_cont
+ mfctl tr7, r1
+EXIT(gsc_intr)
+
.export TLABEL(ibrk), entry
ENTRY(TLABEL(ibrk),0)
/* If called by a user process then always pass it to trap() */
@@ -1919,6 +2001,7 @@ ENTRY(TLABEL(ibrk),0)
extru r8, 18, 13, r9
comib,=,n HPPA_BREAK_GET_PSW, r9, $ibrk_getpsw
comib,=,n HPPA_BREAK_SET_PSW, r9, $ibrk_setpsw
+ comib,=,n HPPA_BREAK_SPLLOWER, r9, $ibrk_spllower
$ibrk_bad
/* illegal (unimplemented) break entry point */
@@ -1934,10 +2017,28 @@ $ibrk_setpsw
b $ibrk_exit
mtctl arg0, ipsw
-$ibrk_setpsw_tovirt
-
- b $ibrk_exit
- ldw HPPA_FRAME_PSP(sp), sp
+$ibrk_spllower
+ /* skip the break */
+ mtctl r0, pcoq
+ mfctl pcoq, r9
+ mtctl r9, pcoq
+ ldo 4(r9), r9
+ mtctl r9, pcoq
+
+ ldil L%ipending, r8
+ ldw R%ipending(r8), r8
+ ldil L%imask, r9
+ ldo R%imask(r9), r9
+ ldil L%cpl, r17
+ ldw R%cpl(r17), ret0
+ ldwx,s arg0(r9), r16
+ stw arg0, R%cpl(r17)
+ ldi T_INTERRUPT, r1
+ andcm,= r8, r16, r0
+ b TLABEL(all)
+ nop
+ rfir
+ nop
/* insert other fast breaks here */
nop ! nop
@@ -1945,10 +2046,11 @@ $ibrk_setpsw_tovirt
$ibrk_exit
/* skip the break */
mtctl r0, pcoq
- mfctl pcoq, r8
- mtctl r8, pcoq
- ldo 4(r8), r8
- mtctl r8, pcoq
+ mfctl pcoq, r9
+ mtctl r9, pcoq
+ ldo 4(r9), r9
+ mtctl r9, pcoq
+
rfir
nop
EXIT(TLABEL(ibrk))
@@ -2336,7 +2438,7 @@ LEAF_ENTRY(longjmp)
EXIT(longjmp)
- .align NBPG /* let's fit 'em on a single page */
+ .align 32
#define FUSUX(name) \
LEAF_ENTRY(name) ! \
@@ -2385,7 +2487,7 @@ SUX(susword, sth)
SUX(suword, stw)
SUX(suswintr, sth)
- .align 64
+ .align 32
LEAF_ENTRY(copy_on_fault)
mtsp r0, sr1
@@ -2538,6 +2640,10 @@ EXIT(remrunqueue)
*/
.align 32
ENTRY(cpu_switch,128)
+ ldil L%cpl, t1
+ ldw R%cpl(t1), ret0
+ stw ret0, HPPA_FRAME_SL(sp)
+ stw rp, HPPA_FRAME_CRP(sp)
/*
* Clear curproc so that we don't accumulate system time while idle.
@@ -2548,31 +2654,26 @@ ENTRY(cpu_switch,128)
/* remain on the old (curproc)'s stack until we have a better choice */
/*
- * arg3: spl
- * t1: &whichqs
- * t2: old curproc
+ * t1: &whichqs
+ * arg2: old curproc
*
*/
switch_search
- /* arg3 = splhigh() */
- mfctl eiem, arg3
ldil L%whichqs, t1
- ldi -1, t2
-idle_loop
- mtctl r0, eiem
ldw R%whichqs(t1), t3
-
comb,<> r0, t3, gotprocs
nop
- mtctl t2, eiem
+ copy r0, arg0
+ break HPPA_BREAK_KERNEL, HPPA_BREAK_SPLLOWER
/* XXX do idle work here */
nop ! nop ! nop ! nop ! nop ! nop ! nop ! nop
- b idle_loop
- nop
+ ldil L%cpl, arg0
+ b switch_search
+ stw ret0, R%cpl(arg0)
gotprocs
ldi 0, t4
@@ -2655,7 +2756,6 @@ kstack_ok
* arg2: old proc
*/
ldw P_MD_REGS(arg2), t1
- stw rp, HPPA_FRAME_CRP(sp)
ldw TF_R30(t1), t3
copy sp, t2
stw,ma r3, HPPA_FRAME_SIZE+20*4(sp)
@@ -2698,6 +2798,7 @@ switch_exited
ldw HPPA_FRAME_ARG(0)(sp), t3
ldw HPPA_FRAME_ARG(1)(sp), t4 /* in case we're on trampoline */
ldw HPPA_FRAME_ARG(2)(sp), arg0
+ ldw HPPA_FRAME_SL(t2), ret0
ldw HPPA_FRAME_CRP(t2), rp
ldw 0*4(t2), r3
ldw 1*4(t2), r4
@@ -2717,9 +2818,10 @@ switch_exited
ldw 15*4(t2), r18
stw t3, TF_R30(t1)
copy t2, sp
+ ldil L%cpl, t1
+ stw ret0, R%cpl(t1)
switch_return
- mtctl arg3, eiem
ldil L%curproc, t1
bv 0(rp)
stw arg1, R%curproc(t1)
diff --git a/sys/arch/hppa/hppa/trap.c b/sys/arch/hppa/hppa/trap.c
index acb758edb11..c93623d835b 100644
--- a/sys/arch/hppa/hppa/trap.c
+++ b/sys/arch/hppa/hppa/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.53 2002/10/18 19:48:54 mickey Exp $ */
+/* $OpenBSD: trap.c,v 1.54 2002/12/17 21:54:25 mickey Exp $ */
/*
* Copyright (c) 1998-2001 Michael Shalayeff
@@ -91,10 +91,8 @@ int trap_types = sizeof(trap_type)/sizeof(trap_type[0]);
int want_resched, astpending;
-void syscall(struct trapframe *frame);
-
-static __inline void
-userret (struct proc *p, register_t pc, u_quad_t oticks)
+void
+userret(struct proc *p, register_t pc, u_quad_t oticks)
{
int sig;
@@ -103,6 +101,13 @@ userret (struct proc *p, register_t pc, u_quad_t oticks)
postsig(sig);
p->p_priority = p->p_usrpri;
+ if (astpending) {
+ astpending = 0;
+ if (p->p_flag & P_OWEUPC) {
+ p->p_flag &= ~P_OWEUPC;
+ ADDUPROF(p);
+ }
+ }
if (want_resched) {
/*
* We're being preempted.
@@ -129,7 +134,6 @@ trap(type, frame)
int type;
struct trapframe *frame;
{
- extern u_int32_t sir;
struct proc *p = curproc;
vaddr_t va;
struct vm_map *map;
@@ -138,9 +142,12 @@ trap(type, frame)
register pa_space_t space;
union sigval sv;
u_int opcode;
- int ret, s, si, trapnum;
+ int ret, trapnum;
const char *tts;
vm_fault_t fault = VM_FAULT_INVALID;
+#ifdef DIAGNOSTIC
+ int oldcpl = cpl;
+#endif
trapnum = type & ~T_USER;
opcode = frame->tf_iir;
@@ -187,6 +194,9 @@ trap(type, frame)
}
}
#endif
+ if (trapnum != T_INTERRUPT)
+ mtctl(frame->tf_eiem, CR_EIEM);
+
switch (type) {
case T_NONEXIST:
case T_NONEXIST|T_USER:
@@ -434,37 +444,13 @@ if (kdb_trap (type, va, frame))
case T_INTERRUPT:
case T_INTERRUPT|T_USER:
cpu_intr(frame);
-#if 0
-if (kdb_trap (type, va, frame))
-return;
-#endif
- /* FALLTHROUGH */
- case T_LOWERPL:
- __asm __volatile (
- "ldcws 0(%1), %0" : "=&r" (si) : "r" (&sir) : "memory");
- if (si & SIR_CLOCK) {
- s = splsoftclock();
- softclock();
- splx(s);
- }
-
- if (si & SIR_NET) {
- register int ni;
- /* use atomic "load & clear" */
- __asm __volatile (
- "ldcws 0(%1), %0"
- : "=&r" (ni) : "r" (&netisr) : "memory");
- s = splnet();
-#define DONETISR(m,c) if (ni & (1 << (m))) c()
-#include <net/netisr_dispatch.h>
- splx(s);
- }
break;
case T_CONDITION:
panic("trap: divide by zero in the kernel");
break;
+ case T_LOWERPL:
case T_DPROT:
case T_IPROT:
case T_OVERFLOW:
@@ -484,11 +470,20 @@ return;
if (kdb_trap (type, va, frame))
return;
#endif
- panic("trap: unimplemented \'%s\' (%d)", tts, type);
+ panic("trap: unimplemented \'%s\' (%d)", tts, trapnum);
}
+#ifdef DIAGNOSTIC
+ if (cpl != oldcpl)
+ printf("WARNING: SPL (%d) NOT LOWERED ON "
+ "TRAP (%d) EXIT\n", cpl, trapnum);
+#endif
+
+ if (trapnum != T_INTERRUPT)
+ splx(cpl); /* process softints */
+
if (type & T_USER)
- userret(p, p->p_md.md_regs->tf_iioq_head, 0);
+ userret(p, frame->tf_iioq_head, 0);
}
void
@@ -508,13 +503,15 @@ child_return(arg)
* call actual syscall routine
*/
void
-syscall(frame)
- struct trapframe *frame;
+syscall(struct trapframe *frame)
{
register struct proc *p = curproc;
register const struct sysent *callp;
int retq, nsys, code, argsize, argoff, oerror, error;
register_t args[8], rval[2];
+#ifdef DIAGNOSTIC
+ int oldcpl = cpl;
+#endif
uvmexp.syscalls++;
@@ -651,8 +648,15 @@ syscall(frame)
scdebug_ret(p, code, oerror, rval);
#endif
userret(p, frame->tf_iioq_head, 0);
+ splx(cpl); /* process softints */
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSRET))
ktrsysret(p, code, oerror, rval[0]);
#endif
+#ifdef DIAGNOSTIC
+ if (cpl != oldcpl)
+ printf("WARNING: SPL (0x%x) NOT LOWERED ON "
+ "syscall(0x%x, 0x%x, 0x%x, 0x%x...) EXIT, PID %d\n",
+ cpl, code, args[0], args[1], args[2], p->p_pid);
+#endif
}
diff --git a/sys/arch/hppa/hppa/vm_machdep.c b/sys/arch/hppa/hppa/vm_machdep.c
index 807c5d5ec7c..dbecc198291 100644
--- a/sys/arch/hppa/hppa/vm_machdep.c
+++ b/sys/arch/hppa/hppa/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.45 2002/11/08 21:42:12 mickey Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.46 2002/12/17 21:54:25 mickey Exp $ */
/*
* Copyright (c) 1999-2002 Michael Shalayeff
@@ -199,7 +199,7 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
* but just in case.
*/
tf->tf_sr7 = HPPA_SID_KERNEL;
- tf->tf_eiem = ~0;
+ mfctl(CR_EIEM, tf->tf_eiem);
tf->tf_ipsw = PSL_C | PSL_Q | PSL_P | PSL_D | PSL_I /* | PSL_L */;
/*
@@ -226,6 +226,7 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
*(register_t*)(osp) = (sp - HPPA_FRAME_SIZE);
*(register_t*)(sp + HPPA_FRAME_PSP) = osp;
*(register_t*)(osp + HPPA_FRAME_CRP) = (register_t)&switch_trampoline;
+ *(register_t*)(osp + HPPA_FRAME_SL) = 0; /* cpl */
tf->tf_sp = sp;
fdcache(HPPA_SID_KERNEL, (vaddr_t)p2->p_addr, sp - (vaddr_t)p2->p_addr);
}
diff --git a/sys/arch/hppa/include/autoconf.h b/sys/arch/hppa/include/autoconf.h
index dd6f804fd6e..b898d09d293 100644
--- a/sys/arch/hppa/include/autoconf.h
+++ b/sys/arch/hppa/include/autoconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: autoconf.h,v 1.15 2002/03/16 01:13:42 mickey Exp $ */
+/* $OpenBSD: autoconf.h,v 1.16 2002/12/17 21:54:25 mickey Exp $ */
/*
* Copyright (c) 1998 Michael Shalayeff
@@ -69,9 +69,10 @@ const char *hppa_mod_info(int, int);
void pdc_scanbus(struct device *, struct confargs *, int bus, int);
int mbprint(void *, const char *);
int mbsubmatch(struct device *, void *, void *);
-void *cpu_intr_establish(int pri, int, int (*handler)(void *),
- void *arg, struct device *name);
-void cpu_intr(struct trapframe *frame);
+void *cpu_intr_map(void *v, int pri, int irq, int (*handler)(void *),
+ void *arg, struct device *dv);
+void *cpu_intr_establish(int pri, int irq, int (*handler)(void *),
+ void *arg, struct device *dv);
int clock_intr(void *);
void dumpconf(void);
diff --git a/sys/arch/hppa/include/intr.h b/sys/arch/hppa/include/intr.h
index c9502ba5106..7bae5207a8a 100644
--- a/sys/arch/hppa/include/intr.h
+++ b/sys/arch/hppa/include/intr.h
@@ -1,106 +1,148 @@
-/* $OpenBSD: intr.h,v 1.13 2002/04/29 07:35:18 miod Exp $ */
+/* $OpenBSD: intr.h,v 1.14 2002/12/17 21:54:25 mickey Exp $ */
-/*
- * Copyright (c) 1990,1991,1992,1994 The University of Utah and
- * the Computer Systems Laboratory at the University of Utah (CSL).
+/*
+ * Copyright (c) 2002 Michael Shalayeff
* All rights reserved.
*
- * Permission to use, copy, modify and distribute this software is hereby
- * granted provided that (1) source code retains these copyright, permission,
- * and disclaimer notices, and (2) redistributions including binaries
- * reproduce the notices in supporting documentation, and (3) all advertising
- * materials mentioning features or use of this software display the following
- * acknowledgement: ``This product includes software developed by the
- * Computer Systems Laboratory at the University of Utah.''
- *
- * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
- * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
- * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * CSL requests users of this software to return to csl-dist@cs.utah.edu any
- * improvements that they make and grant CSL redistribution rights.
+ * 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 Michael Shalayeff.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
*
- * Utah $Hdr: machspl.h 1.16 94/12/14$
- * Author: Jeff Forys, Bob Wheeler, University of Utah CSL
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 HIS RELATIVES 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 MIND, 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.
*/
-#ifndef _MACHINE_INTR_H_
-#define _MACHINE_INTR_H_
+#ifndef _MACHINE_INTR_H_
+#define _MACHINE_INTR_H_
#include <machine/psl.h>
#define CPU_NINTS 32
-#define CPU_INTITMR (0x80000000)
-
-#define IPL_NONE (0xffffffff)
-#define IPL_BIO (0x80000000)
-#define IPL_NET (0x80000000)
-#define IPL_TTY (0x80000000)
-#define IPL_IO (IPL_BIO|IPL_NET|IPL_TTY)
-#define IPL_CLOCK (0)
-#define IPL_HIGH (0)
+#define CPU_INTITMR 0x80000000
+#define NIPL 16
+
+#define IPL_NONE 0
+#define IPL_SOFTCLOCK 1
+#define IPL_SOFTNET 2
+#define IPL_BIO 3
+#define IPL_NET 4
+#define IPL_SOFTTTY 5
+#define IPL_TTY 6
+#define IPL_VM 7
+#define IPL_IMP IPL_VM
+#define IPL_AUDIO 8
+#define IPL_CLOCK 9
+#define IPL_STATCLOCK 10
+#define IPL_HIGH 10
+#define IPL_NESTED 11 /* pseudo-level for sub-tables */
#define IST_NONE 0
#define IST_PULSE 1
#define IST_EDGE 2
#define IST_LEVEL 3
-#if !defined(_LOCORE)
-
-/* SPL asserts */
-#define splassert(wantipl) /* nothing */
+#if !defined(_LOCORE) && defined(_KERNEL)
-/*
- * Define the machine-independent SPL routines in terms of splx().
- */
-#define splraise(splhval) ({ \
- register u_int _ctl_r; \
- __asm __volatile("mfctl %%cr15,%0\n\t" \
- "mtctl %1,%%cr15" \
- : "=&r" (_ctl_r): "r" (splhval)); \
- _ctl_r; \
-})
-
-#define spllower(spllval) ({ \
- register u_int _ctl_r; \
- __asm __volatile("mfctl %%cr15,%0\n\t" \
- "mtctl %1,%%cr15" \
- : "=&r" (_ctl_r): "r" (spllval)); \
- _ctl_r; \
-})
-
-#define splx(splval) ({ \
- register u_int _ctl_r; \
- __asm __volatile("mfctl %%cr15,%0\n\t" \
- "mtctl %1,%%cr15\n\t" \
- : "=&r" (_ctl_r): "r" (splval)); \
- _ctl_r; \
-})
-
-#define spl0() spllower(IPL_NONE)
-#define splsoft() spllower(IPL_CLOCK)
-#define splsoftnet() splsoft()
-#define spllowersoftclock() splsoft()
-#define splsoftclock() splsoft()
-#define splbio() spllower(IPL_BIO)
-#define splnet() spllower(IPL_NET)
-#define spltty() spllower(IPL_TTY)
-#define splimp() spllower(IPL_CLOCK)
-#define splclock() spllower(IPL_CLOCK)
-#define splstatclock() spllower(IPL_CLOCK)
-#define splvm() spllower(IPL_CLOCK)
-#define splhigh() splraise(IPL_HIGH)
-
-/* software interrupt register */
-extern u_int32_t sir;
+extern volatile int cpl;
+extern volatile u_long ipending, imask[NIPL];
extern int astpending;
-#define SIR_CLOCK 0x01
-#define SIR_NET 0x02
-
-#define setsoftclock() (sir |= SIR_CLOCK)
-#define setsoftnet() (sir |= SIR_NET)
-#define setsoftast() (astpending = 1)
-
-#endif /* !_LOCORE */
-#endif /* _MACHINE_INTR_H_ */
+#ifdef DIAGNOSTIC
+void splassert_fail(int, int, const char *);
+extern int splassert_ctl;
+void splassert_check(int, const char *);
+#define splassert(__wantipl) do { \
+ if (__predict_false(splassert_ctl > 0)) { \
+ splassert_check(__wantipl, __func__); \
+ } \
+} while (0)
+#else
+#define splassert(__wantipl) do { /* nada */ } while (0)
+#endif /* DIAGNOSTIC */
+
+void cpu_intr_init(void);
+void cpu_intr(void *);
+
+static __inline int
+spllower(int ncpl)
+{
+ register int ocpl asm("r28") = ncpl;
+ __asm __volatile("copy %0, %%arg0\n\tbreak %1, %2"
+ : "+r" (ocpl) : "i" (HPPA_BREAK_KERNEL), "i" (HPPA_BREAK_SPLLOWER)
+ : "r26", "memory");
+ return (ocpl);
+}
+
+static __inline int
+splraise(int ncpl)
+{
+ int ocpl = cpl;
+
+ if (ocpl < ncpl)
+ cpl = ncpl;
+ __asm __volatile ("nop" : "+r" (cpl));
+
+ return (ocpl);
+}
+
+static __inline void
+splx(int ncpl)
+{
+ (void)spllower(ncpl);
+}
+
+#define spllowersoftclock() spllower(IPL_SOFTCLOCK)
+#define splsoftclock() splraise(IPL_SOFTCLOCK)
+#define splsoftnet() splraise(IPL_SOFTNET)
+#define splbio() splraise(IPL_BIO)
+#define splnet() splraise(IPL_NET)
+#define splsofttty() splraise(IPL_SOFTTTY)
+#define spltty() splraise(IPL_TTY)
+#define splvm() splimp()
+#define splimp() splraise(IPL_IMP)
+#define splaudio() splraise(IPL_AUDIO)
+#define splclock() splraise(IPL_CLOCK)
+#define splhigh() splraise(IPL_HIGH)
+#define splstatclock() splhigh()
+#define spl0() spllower(IPL_NONE)
+
+static __inline void
+softintr(u_long mask)
+{
+ register_t eiem;
+
+ __asm __volatile("mfctl %%cr15, %0": "=r" (eiem));
+ __asm __volatile("mtctl %r0, %cr15");
+ ipending |= mask;
+ __asm __volatile("mtctl %0, %%cr15":: "r" (eiem));
+}
+
+#define SOFTINT_MASK ((1 << (IPL_SOFTCLOCK - 1)) | \
+ (1 << (IPL_SOFTNET - 1)) | (1 << (IPL_SOFTTTY - 1)))
+
+#define setsoftast() (astpending = 1)
+#define setsoftclock() softintr(1 << (IPL_SOFTCLOCK - 1))
+#define setsoftnet() softintr(1 << (IPL_SOFTNET - 1))
+#define setsofttty() softintr(1 << (IPL_SOFTTTY - 1))
+
+#endif /* !_LOCORE && _KERNEL */
+#endif /* _MACHINE_INTR_H_ */
diff --git a/sys/arch/hppa/include/trap.h b/sys/arch/hppa/include/trap.h
index 06bd1527c51..c61e3126158 100644
--- a/sys/arch/hppa/include/trap.h
+++ b/sys/arch/hppa/include/trap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.h,v 1.8 2000/02/10 20:05:39 mickey Exp $ */
+/* $OpenBSD: trap.h,v 1.9 2002/12/17 21:54:25 mickey Exp $ */
/*
* Copyright (c) 1999 Michael Shalayeff
@@ -100,6 +100,7 @@
#define HPPA_BREAK_KGDB 5
#define HPPA_BREAK_GET_PSW 9
#define HPPA_BREAK_SET_PSW 10
+#define HPPA_BREAK_SPLLOWER 11
/*
* break instruction decoding.
@@ -108,4 +109,3 @@
#define break13(i) (((i) >> 13) & 0x1fff)
#endif /* _MACHINE_TRAP_H_ */
-