-/* $OpenBSD: macintr.c,v 1.49 2014/09/06 10:45:29 mpi Exp $ */
+/* $OpenBSD: macintr.c,v 1.50 2015/01/04 13:01:42 mpi Exp $ */
/*-
* Copyright (c) 2008 Dale Rahn <drahn@openbsd.org>
void macintr_calc_mask(void);
void macintr_eoi(int irq);
int macintr_read_irq(void);
-static void macintr_do_pending_int(void);
extern u_int32_t *heathrow_FCR;
int macintr_match(struct device *parent, void *cf, void *aux);
void macintr_attach(struct device *, struct device *, void *);
-void mac_do_pending_int(void);
void mac_ext_intr(void);
void macintr_collect_preconf_intr(void);
void macintr_setipl(int ipl);
u_int8_t *interrupt_reg;
typedef void (void_f) (void);
-extern void_f *pending_int_f;
int macintr_prog_button (void *arg);
intr_establish_t macintr_establish;
macintr_splraise(int newcpl)
{
struct cpu_info *ci = curcpu();
- newcpl = macintr_pri_share[newcpl];
int ocpl = ci->ci_cpl;
+ int s;
+
+ newcpl = macintr_pri_share[newcpl];
if (ocpl > newcpl)
newcpl = ocpl;
+ s = ppc_intr_disable();
macintr_setipl(newcpl);
+ ppc_intr_enable(s);
return ocpl;
}
macintr_splx(int newcpl)
{
struct cpu_info *ci = curcpu();
-
+ int intr, s;
+
+ intr = ppc_intr_disable();
macintr_setipl(newcpl);
- if (ci->ci_ipending & ppc_smask[newcpl])
- macintr_do_pending_int();
+ if ((newcpl < IPL_SOFTTTY && ci->ci_ipending & ppc_smask[newcpl])) {
+ s = splsofttty();
+ dosoftint(newcpl);
+ macintr_setipl(s); /* no-overhead splx */
+ }
+ ppc_intr_enable(intr);
}
void
ppc_smask_init();
install_extint(mac_ext_intr);
- pending_int_f = macintr_do_pending_int;
intr_establish_func = macintr_establish;
intr_disestablish_func = macintr_disestablish;
mac_intr_establish_func = macintr_establish;
return 1;
}
+/* Must be called with interrupt disable. */
void
macintr_setipl(int ipl)
{
struct cpu_info *ci = curcpu();
- int s;
- s = ppc_intr_disable();
+
ci->ci_cpl = ipl;
if (heathrow_FCR)
out32rb(INT_ENABLE_REG1,
macintr_ienable_h[macintr_pri_share[ipl]]);
out32rb(INT_ENABLE_REG0, macintr_ienable_l[macintr_pri_share[ipl]]);
- ppc_intr_enable(s);
}
/*
irq = macintr_read_irq();
}
- ppc_intr_enable(1);
- splx(pcpl); /* Process pendings. */
-}
-
-void
-macintr_do_pending_int()
-{
- struct cpu_info *ci = curcpu();
- int pcpl = ci->ci_cpl; /* XXX */
- int s;
- s = ppc_intr_disable();
- if (ci->ci_flags & CI_FLAGS_PROCESSING_SOFT) {
- ppc_intr_enable(s);
- return;
- }
- atomic_setbits_int(&ci->ci_flags, CI_FLAGS_PROCESSING_SOFT);
-
- do {
- if((ci->ci_ipending & SI_TO_IRQBIT(SI_SOFTCLOCK)) &&
- (pcpl < IPL_SOFTCLOCK)) {
- ci->ci_ipending &= ~SI_TO_IRQBIT(SI_SOFTCLOCK);
- softintr_dispatch(SI_SOFTCLOCK);
- }
- if((ci->ci_ipending & SI_TO_IRQBIT(SI_SOFTNET)) &&
- (pcpl < IPL_SOFTNET)) {
- ci->ci_ipending &= ~SI_TO_IRQBIT(SI_SOFTNET);
- softintr_dispatch(SI_SOFTNET);
- }
- if((ci->ci_ipending & SI_TO_IRQBIT(SI_SOFTTTY)) &&
- (pcpl < IPL_SOFTTTY)) {
- ci->ci_ipending &= ~SI_TO_IRQBIT(SI_SOFTTTY);
- softintr_dispatch(SI_SOFTTTY);
- }
-
- } while (ci->ci_ipending & ppc_smask[pcpl]);
- macintr_setipl(pcpl);
- ppc_intr_enable(s);
-
- atomic_clearbits_int(&ci->ci_flags, CI_FLAGS_PROCESSING_SOFT);
+ macintr_splx(pcpl); /* Process pendings. */
}
void
-/* $OpenBSD: openpic.c,v 1.75 2014/10/08 22:24:26 deraadt Exp $ */
+/* $OpenBSD: openpic.c,v 1.76 2015/01/04 13:01:42 mpi Exp $ */
/*-
* Copyright (c) 2008 Dale Rahn <drahn@openbsd.org>
int openpic_match(struct device *parent, void *cf, void *aux);
void openpic_attach(struct device *, struct device *, void *);
-void openpic_do_pending_int(int pcpl);
-void openpic_do_pending_int_dis(int pcpl, int s);
void openpic_collect_preconf_intr(void);
void openpic_ext_intr(void);
printf("\n");
}
+/* Must be called with interrupt disable. */
static inline void
openpic_setipl(int newcpl)
{
struct cpu_info *ci = curcpu();
- int s;
- /* XXX - try do to this without the disable */
- s = ppc_intr_disable();
+
ci->ci_cpl = newcpl;
openpic_set_priority(ci->ci_cpuid, newcpl);
- ppc_intr_enable(s);
}
int
openpic_splraise(int newcpl)
{
struct cpu_info *ci = curcpu();
- newcpl = openpic_pri_share[newcpl];
int ocpl = ci->ci_cpl;
+ int s;
+
+ newcpl = openpic_pri_share[newcpl];
if (ocpl > newcpl)
newcpl = ocpl;
+ s = ppc_intr_disable();
openpic_setipl(newcpl);
+ ppc_intr_enable(s);
return ocpl;
}
void
openpic_splx(int newcpl)
{
- openpic_do_pending_int(newcpl);
+ struct cpu_info *ci = curcpu();
+ int intr, s;
+
+ intr = ppc_intr_disable();
+ openpic_setipl(newcpl);
+ if (newcpl < IPL_SOFTTTY && (ci->ci_ipending & ppc_smask[newcpl])) {
+ s = splsofttty();
+ dosoftint(newcpl);
+ openpic_setipl(s); /* no-overhead splx */
+ }
+ ppc_intr_enable(intr);
}
void
openpic_set_priority(ci->ci_cpuid, ci->ci_cpl);
}
-void
-openpic_do_pending_int(int pcpl)
-{
- int s;
- s = ppc_intr_disable();
- openpic_do_pending_int_dis(pcpl, s);
- ppc_intr_enable(s);
-
-}
-
-/*
- * This function expect interrupts disabled on entry and exit,
- * the s argument indicates if interrupts may be enabled during
- * the processing of off level interrupts, s 'should' always be 1.
- */
-void
-openpic_do_pending_int_dis(int pcpl, int s)
-{
- struct cpu_info *ci = curcpu();
-
- (void)ppc_intr_disable();
- if (ci->ci_flags & CI_FLAGS_PROCESSING_SOFT) {
- /* soft interrupts are being processed, just set ipl/return */
- openpic_setipl(pcpl);
- ppc_intr_enable(s);
- return;
- }
-
- atomic_setbits_int(&ci->ci_flags, CI_FLAGS_PROCESSING_SOFT);
-
- do {
- if ((ci->ci_ipending & SI_TO_IRQBIT(SI_SOFTCLOCK)) &&
- (pcpl < IPL_SOFTCLOCK)) {
- ci->ci_ipending &= ~SI_TO_IRQBIT(SI_SOFTCLOCK);
- ppc_intr_enable(1);
- KERNEL_LOCK();
- softintr_dispatch(SI_SOFTCLOCK);
- KERNEL_UNLOCK();
- (void)ppc_intr_disable();
- }
- if ((ci->ci_ipending & SI_TO_IRQBIT(SI_SOFTNET)) &&
- (pcpl < IPL_SOFTNET)) {
- ci->ci_ipending &= ~SI_TO_IRQBIT(SI_SOFTNET);
- ppc_intr_enable(1);
- KERNEL_LOCK();
- softintr_dispatch(SI_SOFTNET);
- KERNEL_UNLOCK();
- (void)ppc_intr_disable();
- }
- if ((ci->ci_ipending & SI_TO_IRQBIT(SI_SOFTTTY)) &&
- (pcpl < IPL_SOFTTTY)) {
- ci->ci_ipending &= ~SI_TO_IRQBIT(SI_SOFTTTY);
- ppc_intr_enable(1);
- KERNEL_LOCK();
- softintr_dispatch(SI_SOFTTTY);
- KERNEL_UNLOCK();
- (void)ppc_intr_disable();
- }
- } while (ci->ci_ipending & ppc_smask[pcpl]);
- openpic_setipl(pcpl); /* Don't use splx... we are here already! */
-
- atomic_clearbits_int(&ci->ci_flags, CI_FLAGS_PROCESSING_SOFT);
- ppc_intr_enable(s);
-}
-
void
openpic_enable_irq(int irq, int pri)
{
openpic_read(OPENPIC_CPU_PRIORITY(ci->ci_cpuid)));
if (iq->iq_ipl > maxipl)
maxipl = iq->iq_ipl;
- splraise(iq->iq_ipl);
+ openpic_splraise(iq->iq_ipl);
openpic_eoi(ci->ci_cpuid);
spurious = 1;
irq = openpic_read_irq(ci->ci_cpuid);
}
- /*
- * sending 0 in to openpic_do_pending_int_dis will leave
- * external interrupts disabled, but since we are about
- * to return from interrupt leaving them disabled until then
- * prevents additional recursion.
- */
- openpic_do_pending_int_dis(pcpl, 0);
-
+ openpic_splx(pcpl); /* Process pendings. */
openpic_irqnest[ci->ci_cpuid]--;
}
-/* $OpenBSD: cpu.h,v 1.58 2014/10/10 04:08:11 mpi Exp $ */
+/* $OpenBSD: cpu.h,v 1.59 2015/01/04 13:01:42 mpi Exp $ */
/* $NetBSD: cpu.h,v 1.1 1996/09/30 16:34:21 ws Exp $ */
/*
volatile int ci_ipending;
volatile int ci_flags;
-#define CI_FLAGS_PROCESSING_SOFT 1
#define CI_FLAGS_SLEEPING 2
int ci_intrdepth;
-/* $OpenBSD: intr.h,v 1.49 2013/05/17 19:38:52 kettenis Exp $ */
+/* $OpenBSD: intr.h,v 1.50 2015/01/04 13:01:42 mpi Exp $ */
/*
* Copyright (c) 1997 Per Fogelstrom, Opsycon AB and RTMX Inc, USA.
void do_pending_int(void);
/* SPL asserts */
-#define splassert(wantipl) /* nothing */
-#define splsoftassert(wantipl) /* nothing */
+#ifdef DIAGNOSTIC
+/*
+ * Although this function is implemented in MI code, it must be in this MD
+ * header because we don't want this header to include MI includes.
+ */
+void splassert_fail(int, int, const char *);
+extern int splassert_ctl;
+void splassert_check(int, const char *);
+#define splassert(__wantipl) do { \
+ if (splassert_ctl > 0) { \
+ splassert_check(__wantipl, __func__); \
+ } \
+} while (0)
+#define splsoftassert(wantipl) splassert(wantipl)
+#else
+#define splassert(wantipl) do { /* nada */ } while (0)
+#define splsoftassert(wantipl) do { /* nada */ } while (0)
+#endif
#define set_sint(p) atomic_setbits_int(&curcpu()->ci_ipending, p)
void softintr_init(void);
void softintr_schedule(void *);
+void dosoftint(int);
#define set_sint(p) atomic_setbits_int(&curcpu()->ci_ipending, p)
-/* $OpenBSD: intr.c,v 1.7 2011/08/29 20:21:44 drahn Exp $ */
+/* $OpenBSD: intr.c,v 1.8 2015/01/04 13:01:42 mpi Exp $ */
/*
* Copyright (c) 1997 Per Fogelstrom, Opsycon AB and RTMX Inc, USA.
ci->ci_cpl = newcpl;
if (ci->ci_ipending & ppc_smask[newcpl])
- do_pending_int();
+ dosoftint(newcpl);
}
struct ppc_intr_func ppc_intr_func =
return ("unknown");
}
}
+
+#ifdef DIAGNOSTIC
+void
+splassert_check(int wantipl, const char *func)
+{
+ struct cpu_info *ci = curcpu();
+
+ if (ci->ci_cpl < wantipl)
+ splassert_fail(wantipl, ci->ci_cpl, func);
+
+ if (wantipl == IPL_NONE && ci->ci_intrdepth != -1)
+ splassert_fail(-1, ci->ci_intrdepth, func);
+}
+#endif
-/* $OpenBSD: softintr.c,v 1.6 2014/07/12 18:44:42 tedu Exp $ */
+/* $OpenBSD: softintr.c,v 1.7 2015/01/04 13:01:42 mpi Exp $ */
/* $NetBSD: softintr.c,v 1.2 2003/07/15 00:24:39 lukem Exp $ */
/*
mtx_leave(&siq->siq_mtx);
- KERNEL_LOCK();
(*sih->sih_func)(sih->sih_arg);
- KERNEL_UNLOCK();
}
}
mtx_leave(&siq->siq_mtx);
}
-#if 0
void
-dosoftint(int xcpl)
+dosoftint(int pcpl)
{
struct cpu_info *ci = curcpu();
int sir, q, mask;
- while ((sir = (ci->ci_ipending & SINT_ALLMASK & ~xcpl)) != 0) {
+ ppc_intr_enable(1);
+ KERNEL_LOCK();
+
+ while ((sir = (ci->ci_ipending & ppc_smask[pcpl])) != 0) {
atomic_clearbits_int(&ci->ci_ipending, sir);
for (q = SI_NQUEUES - 1; q >= 0; q--) {
- mask = SINTMASK(q);
+ mask = SI_TO_IRQBIT(q);
if (sir & mask)
softintr_dispatch(q);
}
}
+
+ KERNEL_UNLOCK();
+ (void)ppc_intr_disable();
}
-#endif
-/* $OpenBSD: ipic.c,v 1.16 2014/02/08 10:58:17 kettenis Exp $ */
+/* $OpenBSD: ipic.c,v 1.17 2015/01/04 13:01:42 mpi Exp $ */
/*
* Copyright (c) 2008 Mark Kettenis
*/
s = ppc_intr_disable();
TAILQ_INSERT_TAIL(&iq->iq_list, ih, ih_list);
- ppc_intr_enable(s);
/* Unmask the interrupt. */
if (sc)
ipic_setipl(curcpu()->ci_cpl);
+ ppc_intr_enable(s);
return (ih);
}
{
struct cpu_info *ci = curcpu();
int ocpl = ci->ci_cpl;
+ int s;
if (ocpl > newcpl)
newcpl = ocpl;
+ s = ppc_intr_disable();
ipic_setipl(newcpl);
+ ppc_intr_enable(s);
return (ocpl);
}
ipic_splx(int newcpl)
{
struct cpu_info *ci = curcpu();
+ int intr, s;
+ intr = ppc_intr_disable();
ipic_setipl(newcpl);
- if (ci->ci_ipending & ppc_smask[newcpl])
- do_pending_int();
+ if (newcpl < IPL_SOFTTTY && (ci->ci_ipending & ppc_smask[newcpl])) {
+ s = splsofttty();
+ dosoftint(newcpl);
+ ipic_setipl(s); /* no-overhead splx */
+ }
+ ppc_intr_enable(intr);
}
+/* Must be called with interrupt disable. */
void
ipic_setipl(int ipl)
{
struct cpu_info *ci = curcpu();
struct ipic_softc *sc = ipic_sc;
uint32_t mask;
- int s;
- s = ppc_intr_disable();
ci->ci_cpl = ipl;
mask = sc->sc_simsr_h[IPL_HIGH] & ~sc->sc_simsr_h[ipl];
ipic_write(sc, IPIC_SIMSR_H, mask);
ipic_write(sc, IPIC_SIMSR_L, mask);
mask = sc->sc_semsr[IPL_HIGH] & ~sc->sc_semsr[ipl];
ipic_write(sc, IPIC_SEMSR, mask);
- ppc_intr_enable(s);
}
-/* $OpenBSD: machdep.c,v 1.60 2014/12/10 15:29:53 mikeb Exp $ */
+/* $OpenBSD: machdep.c,v 1.61 2015/01/04 13:01:42 mpi Exp $ */
/* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */
/*
/* NOTREACHED */
}
-void
-do_pending_int(void)
-{
- struct cpu_info *ci = curcpu();
- int pcpl = ci->ci_cpl; /* XXX */
- int s;
- s = ppc_intr_disable();
- if (ci->ci_flags & CI_FLAGS_PROCESSING_SOFT) {
- ppc_intr_enable(s);
- return;
- }
- atomic_setbits_int(&ci->ci_flags, CI_FLAGS_PROCESSING_SOFT);
-
- do {
- if((ci->ci_ipending & SI_TO_IRQBIT(SI_SOFTCLOCK)) &&
- (pcpl < IPL_SOFTCLOCK)) {
- ci->ci_ipending &= ~SI_TO_IRQBIT(SI_SOFTCLOCK);
- softintr_dispatch(SI_SOFTCLOCK);
- }
- if((ci->ci_ipending & SI_TO_IRQBIT(SI_SOFTNET)) &&
- (pcpl < IPL_SOFTNET)) {
- ci->ci_ipending &= ~SI_TO_IRQBIT(SI_SOFTNET);
- softintr_dispatch(SI_SOFTNET);
- }
- if((ci->ci_ipending & SI_TO_IRQBIT(SI_SOFTTTY)) &&
- (pcpl < IPL_SOFTTTY)) {
- ci->ci_ipending &= ~SI_TO_IRQBIT(SI_SOFTTTY);
- softintr_dispatch(SI_SOFTTTY);
- }
-
- } while (ci->ci_ipending & ppc_smask[pcpl]);
- splx(pcpl);
- ppc_intr_enable(s);
-
- atomic_clearbits_int(&ci->ci_flags, CI_FLAGS_PROCESSING_SOFT);
-}
-
/*
* Notify the current process (p) that it has a signal pending,
* process as soon as possible.