diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2002-12-17 21:54:26 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2002-12-17 21:54:26 +0000 |
commit | 7f33aa2f59d67ead13e253a82b4241d038e46a5d (patch) | |
tree | 0d8e42d725d944bbed37154b421ab258da5a95e6 /sys | |
parent | c86b06b8c90928864da380972228aea593140be3 (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.c | 58 | ||||
-rw-r--r-- | sys/arch/hppa/dev/lasi.c | 74 | ||||
-rw-r--r-- | sys/arch/hppa/gsc/gscbus.c | 92 | ||||
-rw-r--r-- | sys/arch/hppa/gsc/gscbusvar.h | 12 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/autoconf.c | 8 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/intr.c | 246 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/locore.S | 192 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/trap.c | 76 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/vm_machdep.c | 5 | ||||
-rw-r--r-- | sys/arch/hppa/include/autoconf.h | 9 | ||||
-rw-r--r-- | sys/arch/hppa/include/intr.h | 216 | ||||
-rw-r--r-- | sys/arch/hppa/include/trap.h | 4 |
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_ */ - |