summaryrefslogtreecommitdiff
path: root/sys/arch/socppc
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2015-01-04 13:01:43 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2015-01-04 13:01:43 +0000
commitb5aa09b33d64540760172d36438ee5864c0b24f4 (patch)
treed4b642b74030caea41fe90cdecbd3e87b8104afb /sys/arch/socppc
parent11e22c6125c49fc01f5752389ca129e42973f458 (diff)
Implement splassert(9) for powerpc.
This changes the logic to prevent a recursion when processing soft interrupts. Previously a per-CPU flag was set before re-enabling interrupts. Now the IPL level is raised to SOFTTTY which makes splsoftassert() happy, greatly inspired by mips64. As a side effect, the ppc_intr_{disable,enable}() dance is now done only once instead of twice per splx(9). While here, make use of dosoftint() instead of having 3 different functions for dispatching soft interrupts. Tested by deraadt@ on G4 smp and by myself G5 smp, G3, G4 and socppc. No objection from the usual (and over busy) suspects.
Diffstat (limited to 'sys/arch/socppc')
-rw-r--r--sys/arch/socppc/dev/ipic.c21
-rw-r--r--sys/arch/socppc/socppc/machdep.c39
2 files changed, 15 insertions, 45 deletions
diff --git a/sys/arch/socppc/dev/ipic.c b/sys/arch/socppc/dev/ipic.c
index b7205e5c490..44b4d37f305 100644
--- a/sys/arch/socppc/dev/ipic.c
+++ b/sys/arch/socppc/dev/ipic.c
@@ -1,4 +1,4 @@
-/* $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
@@ -298,11 +298,11 @@ intr_establish(int ivec, int type, int level,
*/
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);
}
@@ -347,11 +347,14 @@ ipic_splraise(int newcpl)
{
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);
}
@@ -371,21 +374,26 @@ void
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);
@@ -393,5 +401,4 @@ ipic_setipl(int ipl)
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);
}
diff --git a/sys/arch/socppc/socppc/machdep.c b/sys/arch/socppc/socppc/machdep.c
index 2edb7167d7e..2f9d5fc3d1c 100644
--- a/sys/arch/socppc/socppc/machdep.c
+++ b/sys/arch/socppc/socppc/machdep.c
@@ -1,4 +1,4 @@
-/* $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 $ */
/*
@@ -1084,43 +1084,6 @@ haltsys:
/* 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.