From bb536b7d2e12ec90c43c7b6c3be9d35e529b0a7d Mon Sep 17 00:00:00 2001 From: mpi Date: Wed, 24 Jun 2015 11:58:06 +0000 Subject: [PATCH] IPL_MPSAFE bits for macppc with openpic(4). --- sys/arch/macppc/dev/adb.c | 4 +-- sys/arch/macppc/dev/macgpio.c | 4 +-- sys/arch/macppc/dev/macintr.c | 14 ++++---- sys/arch/macppc/dev/openpic.c | 59 +++++++++++++++++++++++++-------- sys/arch/macppc/dev/xlights.c | 4 +-- sys/arch/powerpc/include/intr.h | 17 +++++----- sys/arch/socppc/dev/ipic.c | 10 ++++-- 7 files changed, 76 insertions(+), 36 deletions(-) diff --git a/sys/arch/macppc/dev/adb.c b/sys/arch/macppc/dev/adb.c index 5cc42ed6415..56fd80e36b2 100644 --- a/sys/arch/macppc/dev/adb.c +++ b/sys/arch/macppc/dev/adb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: adb.c,v 1.39 2013/08/10 08:13:32 mpi Exp $ */ +/* $OpenBSD: adb.c,v 1.40 2015/06/24 11:58:06 mpi Exp $ */ /* $NetBSD: adb.c,v 1.6 1999/08/16 06:28:09 tsubai Exp $ */ /* $NetBSD: adb_direct.c,v 1.14 2000/06/08 22:10:45 tsubai Exp $ */ @@ -1626,7 +1626,7 @@ adbattach(struct device *parent, struct device *self, void *aux) } printf("\n"); - mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_HIGH, + mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_TTY, adb_intr, sc, sc->sc_dev.dv_xname); /* init powerpc globals which control RTC functionality */ diff --git a/sys/arch/macppc/dev/macgpio.c b/sys/arch/macppc/dev/macgpio.c index 0c22369ced9..75d31b3e610 100644 --- a/sys/arch/macppc/dev/macgpio.c +++ b/sys/arch/macppc/dev/macgpio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: macgpio.c,v 1.7 2013/06/03 20:10:50 mpi Exp $ */ +/* $OpenBSD: macgpio.c,v 1.8 2015/06/24 11:58:06 mpi Exp $ */ /* $NetBSD: gpio.c,v 1.2 2001/02/27 05:16:33 matt Exp $ */ /*- @@ -161,7 +161,7 @@ macgpio_gpio_attach(struct device *parent, struct device *self, void *aux) sc->sc_port = ((struct gpio_softc *) parent)->sc_port; - mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_HIGH, + mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_TTY, gpio_intr, sc, sc->sc_dev.dv_xname); printf(": irq %d\n", ca->ca_intr[0]); diff --git a/sys/arch/macppc/dev/macintr.c b/sys/arch/macppc/dev/macintr.c index 69318aa64cc..ff8a657f06d 100644 --- a/sys/arch/macppc/dev/macintr.c +++ b/sys/arch/macppc/dev/macintr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: macintr.c,v 1.51 2015/04/02 11:12:24 mpi Exp $ */ +/* $OpenBSD: macintr.c,v 1.52 2015/06/24 11:58:06 mpi Exp $ */ /*- * Copyright (c) 2008 Dale Rahn @@ -280,11 +280,7 @@ macintr_establish(void * lcv, int irq, int type, int level, struct cpu_info *ci = curcpu(); struct intrq *iq; struct intrhand *ih; - int s; - -#if 0 -printf("macintr_establish, hI %d L %d %s", irq, level, ppc_intr_typename(type)); -#endif + int s, flags; if (!LEGAL_IRQ(irq) || type == IST_NONE) { printf("%s: bogus irq %d or type %d", __func__, irq, type); @@ -315,9 +311,15 @@ printf("macintr_establish, hI %d L %d %s", irq, level, ppc_intr_typename(type)); break; } + flags = level & IPL_MPSAFE; + level &= ~IPL_MPSAFE; + + KASSERT(level <= IPL_TTY || level >= IPL_CLOCK || flags & IPL_MPSAFE); + ih->ih_fun = ih_fun; ih->ih_arg = ih_arg; ih->ih_level = level; + ih->ih_flags = flags; ih->ih_irq = irq; evcount_attach(&ih->ih_count, name, &ih->ih_irq); diff --git a/sys/arch/macppc/dev/openpic.c b/sys/arch/macppc/dev/openpic.c index 9ddac5f32cb..f56899d800c 100644 --- a/sys/arch/macppc/dev/openpic.c +++ b/sys/arch/macppc/dev/openpic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: openpic.c,v 1.80 2015/06/02 13:53:43 mpi Exp $ */ +/* $OpenBSD: openpic.c,v 1.81 2015/06/24 11:58:06 mpi Exp $ */ /*- * Copyright (c) 2008 Dale Rahn @@ -99,6 +99,7 @@ void *openpic_intr_establish(void *, int, int, int, int (*)(void *), void *, void openpic_intr_disestablish(void *, void *); void openpic_collect_preconf_intr(void); void openpic_ext_intr(void); +int openpic_ext_intr_handler(struct intrhand *, int, int *); /* Generic IRQ management routines. */ void openpic_gen_acknowledge_irq(int, int); @@ -420,7 +421,7 @@ openpic_intr_establish(void *lcv, int irq, int type, int level, { struct intrhand *ih; struct intrq *iq; - int s; + int s, flags; if (!LEGAL_IRQ(irq) || type == IST_NONE) { printf("%s: bogus irq %d or type %d", __func__, irq, type); @@ -431,8 +432,8 @@ openpic_intr_establish(void *lcv, int irq, int type, int level, ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK); if (ih == NULL) panic("%s: can't malloc handler info", __func__); - iq = &openpic_handler[irq]; + iq = &openpic_handler[irq]; switch (iq->iq_ist) { case IST_NONE: iq->iq_ist = type; @@ -451,9 +452,15 @@ openpic_intr_establish(void *lcv, int irq, int type, int level, break; } + flags = level & IPL_MPSAFE; + level &= ~IPL_MPSAFE; + + KASSERT(level <= IPL_TTY || level >= IPL_CLOCK || flags & IPL_MPSAFE); + ih->ih_fun = ih_fun; ih->ih_arg = ih_arg; ih->ih_level = level; + ih->ih_flags = flags; ih->ih_irq = irq; evcount_attach(&ih->ih_count, name, &ih->ih_irq); @@ -647,10 +654,13 @@ openpic_ext_intr(void) #endif iq = &openpic_handler[irq]; - if (iq->iq_ipl <= ci->ci_cpl) +#ifdef OPENPIC_DEBUG + if (iq->iq_ipl <= pcpl) printf("invalid interrupt %d lvl %d at %d hw %d\n", - irq, iq->iq_ipl, ci->ci_cpl, + irq, iq->iq_ipl, pcpl, openpic_read(OPENPIC_CPU_PRIORITY(ci->ci_cpuid))); +#endif + if (iq->iq_ipl > maxipl) maxipl = iq->iq_ipl; openpic_splraise(iq->iq_ipl); @@ -659,14 +669,7 @@ openpic_ext_intr(void) spurious = 1; TAILQ_FOREACH(ih, &iq->iq_list, ih_list) { ppc_intr_enable(1); - KERNEL_LOCK(); - ret = (*ih->ih_fun)(ih->ih_arg); - if (ret) { - ih->ih_count.ec_count++; - spurious = 0; - } - KERNEL_UNLOCK(); - + ret = openpic_ext_intr_handler(ih, pcpl, &spurious); (void)ppc_intr_disable(); if (intr_shared_edge == 00 && ret == 1) break; @@ -686,6 +689,36 @@ openpic_ext_intr(void) openpic_irqnest[ci->ci_cpuid]--; } +int +openpic_ext_intr_handler(struct intrhand *ih, int pcpl, int *spurious) +{ + int ret; +#ifdef MULTIPROCESSOR + int need_lock; + + if (ih->ih_flags & IPL_MPSAFE) + need_lock = 0; + else + need_lock = pcpl < IPL_SCHED; + + if (need_lock) + KERNEL_LOCK(); +#endif + + ret = (*ih->ih_fun)(ih->ih_arg); + if (ret) { + ih->ih_count.ec_count++; + *spurious = 0; + } + +#ifdef MULTIPROCESSOR + if (need_lock) + KERNEL_UNLOCK(); +#endif + + return (ret); +} + void openpic_acknowledge_irq(int irq, int cpuid) { diff --git a/sys/arch/macppc/dev/xlights.c b/sys/arch/macppc/dev/xlights.c index ef76ac30f3c..ca2a28ee38d 100644 --- a/sys/arch/macppc/dev/xlights.c +++ b/sys/arch/macppc/dev/xlights.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xlights.c,v 1.6 2013/11/18 20:21:51 deraadt Exp $ */ +/* $OpenBSD: xlights.c,v 1.7 2015/06/24 11:58:06 mpi Exp $ */ /* * Copyright (c) 2007 Gordon Willem Klok * @@ -185,7 +185,7 @@ xlights_attach(struct device *parent, struct device *self, void *aux) } mac_intr_establish(parent, sc->sc_intr, intr[3] ? IST_LEVEL : - type, IPL_AUDIO, xlights_intr, sc, sc->sc_dev.dv_xname); + type, IPL_TTY, xlights_intr, sc, sc->sc_dev.dv_xname); out32rb(sc->sc_reg + I2S_FORMAT, CLKSRC_VS); macobio_enable(I2SClockOffset, I2S0CLKEN); diff --git a/sys/arch/powerpc/include/intr.h b/sys/arch/powerpc/include/intr.h index 448e729bf30..fdb0e951fb9 100644 --- a/sys/arch/powerpc/include/intr.h +++ b/sys/arch/powerpc/include/intr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.h,v 1.50 2015/01/04 13:01:42 mpi Exp $ */ +/* $OpenBSD: intr.h,v 1.51 2015/06/24 11:58:06 mpi Exp $ */ /* * Copyright (c) 1997 Per Fogelstrom, Opsycon AB and RTMX Inc, USA. @@ -41,16 +41,16 @@ #define IPL_SOFTNET 3 #define IPL_SOFTTTY 4 #define IPL_BIO 5 -#define IPL_AUDIO IPL_BIO /* XXX - was defined this val in audio_if.h */ #define IPL_NET 6 #define IPL_TTY 7 #define IPL_VM 8 -#define IPL_CLOCK 9 -#define IPL_SCHED 10 -#define IPL_HIGH 11 -#define IPL_NUM 12 +#define IPL_AUDIO 9 +#define IPL_CLOCK 10 +#define IPL_SCHED 11 +#define IPL_HIGH 12 +#define IPL_NUM 13 -#define IPL_MPSAFE 0 /* no "mpsafe" interrupts */ +#define IPL_MPSAFE 0x100 #define IST_NONE 0 #define IST_PULSE 1 @@ -156,8 +156,6 @@ void softintr_init(void); void softintr_schedule(void *); void dosoftint(int); -#define set_sint(p) atomic_setbits_int(&curcpu()->ci_ipending, p) - #define setsoftclock() set_sint(SI_TO_IRQBIT(SI_SOFTCLOCK)) #define setsoftnet() set_sint(SI_TO_IRQBIT(SI_SOFTNET)) #define setsofttty() set_sint(SI_TO_IRQBIT(SI_SOFTTTY)) @@ -176,6 +174,7 @@ struct intrhand { struct evcount ih_count; int ih_type; int ih_level; + int ih_flags; int ih_irq; const char *ih_what; }; diff --git a/sys/arch/socppc/dev/ipic.c b/sys/arch/socppc/dev/ipic.c index 44b4d37f305..669bd3289c5 100644 --- a/sys/arch/socppc/dev/ipic.c +++ b/sys/arch/socppc/dev/ipic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipic.c,v 1.17 2015/01/04 13:01:42 mpi Exp $ */ +/* $OpenBSD: ipic.c,v 1.18 2015/06/24 11:58:06 mpi Exp $ */ /* * Copyright (c) 2008 Mark Kettenis @@ -266,7 +266,7 @@ intr_establish(int ivec, int type, int level, struct ipic_softc *sc = ipic_sc; struct intrhand *ih; struct intrq *iq; - int s; + int s, flags; if (ipic_preinit_done == 0) ipic_preinit(); @@ -286,9 +286,15 @@ intr_establish(int ivec, int type, int level, ipic_calc_masks(); } + flags = level & IPL_MPSAFE; + level &= ~IPL_MPSAFE; + + KASSERT(level <= IPL_TTY || level >= IPL_CLOCK || flags & IPL_MPSAFE); + ih->ih_fun = ih_fun; ih->ih_arg = ih_arg; ih->ih_level = level; + ih->ih_flags = flags; ih->ih_irq = ivec; evcount_attach(&ih->ih_count, name, &ih->ih_irq); -- 2.20.1