summaryrefslogtreecommitdiff
path: root/sys/arch/mvme88k
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2007-05-18 16:38:30 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2007-05-18 16:38:30 +0000
commitee9ca20562cae47f9fdb624ec029236b322bf19f (patch)
treeb9f69b3981b1760e4749c467c35ea87b7de0a0e0 /sys/arch/mvme88k
parente140551c25ab01c007c9e96a9ddb318babd78481 (diff)
More work in IPI processing: actual processing is now done with interrupts
enabled, and is delayed if the current spl is not high enough; setipl() and raiseipl() will retrigger an IPI interrupt if there are any pending IPIs.
Diffstat (limited to 'sys/arch/mvme88k')
-rw-r--r--sys/arch/mvme88k/mvme88k/m188_machdep.c135
1 files changed, 82 insertions, 53 deletions
diff --git a/sys/arch/mvme88k/mvme88k/m188_machdep.c b/sys/arch/mvme88k/mvme88k/m188_machdep.c
index 7e9d07cafb5..fb57f24eda4 100644
--- a/sys/arch/mvme88k/mvme88k/m188_machdep.c
+++ b/sys/arch/mvme88k/mvme88k/m188_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: m188_machdep.c,v 1.28 2007/05/14 17:00:40 miod Exp $ */
+/* $OpenBSD: m188_machdep.c,v 1.29 2007/05/18 16:38:29 miod Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -284,7 +284,12 @@ u_int
m188_setipl(u_int level)
{
u_int mask, curspl;
+#ifdef MULTIPROCESSOR
+ struct cpu_info *ci = curcpu();
+ int cpu = ci->ci_cpuid;
+#else
int cpu = cpu_number();
+#endif
curspl = m188_curspl[cpu];
@@ -298,6 +303,12 @@ m188_setipl(u_int level)
*int_mask_reg[cpu] = mask;
m188_curspl[cpu] = level;
+#ifdef MULTIPROCESSOR
+ /* need to resend myself the pending ipis */
+ if (ci->ci_ipi != 0)
+ *(volatile u_int32_t *)MVME188_SETSWI = IPI_BIT(cpu);
+#endif
+
return curspl;
}
@@ -305,7 +316,12 @@ u_int
m188_raiseipl(u_int level)
{
u_int mask, curspl;
+#ifdef MULTIPROCESSOR
+ struct cpu_info *ci = curcpu();
+ int cpu = ci->ci_cpuid;
+#else
int cpu = cpu_number();
+#endif
curspl = m188_curspl[cpu];
if (curspl < level) {
@@ -318,6 +334,12 @@ m188_raiseipl(u_int level)
*int_mask_reg[cpu] = mask;
m188_curspl[cpu] = level;
+
+#ifdef MULTIPROCESSOR
+ /* need to resend myself the pending ipis */
+ if (ci->ci_ipi != 0)
+ *(volatile u_int32_t *)MVME188_SETSWI = IPI_BIT(cpu);
+#endif
}
return curspl;
}
@@ -341,19 +363,30 @@ void
m188_ipi_handler(struct trapframe *eframe)
{
struct cpu_info *ci = curcpu();
+ int ipi = ci->ci_ipi;
+ int spl = m188_curspl[ci->ci_cpuid];
- if (ci->ci_ipi & CI_IPI_NOTIFY) {
- atomic_clearbits_int(&ci->ci_ipi, CI_IPI_NOTIFY);
+ if (ipi & CI_IPI_NOTIFY) {
/* nothing to do */
}
- if (ci->ci_ipi & CI_IPI_HARDCLOCK) {
- atomic_clearbits_int(&ci->ci_ipi, CI_IPI_HARDCLOCK);
- hardclock((struct clockframe *)eframe);
+ if (ipi & CI_IPI_HARDCLOCK) {
+ if (spl < IPL_CLOCK) {
+ m188_setipl(IPL_CLOCK);
+ hardclock((struct clockframe *)eframe);
+ m188_setipl(spl);
+ } else
+ ipi &= ~CI_IPI_HARDCLOCK; /* leave it pending */
}
- if (ci->ci_ipi & CI_IPI_STATCLOCK) {
- atomic_clearbits_int(&ci->ci_ipi, CI_IPI_STATCLOCK);
- statclock((struct clockframe *)eframe);
+ if (ipi & CI_IPI_STATCLOCK) {
+ if (spl < IPL_STATCLOCK) {
+ m188_setipl(IPL_STATCLOCK);
+ statclock((struct clockframe *)eframe);
+ m188_setipl(spl);
+ } else
+ ipi &= ~CI_IPI_STATCLOCK; /* leave it pending */
}
+
+ atomic_clearbits_int(&ci->ci_ipi, ipi);
}
#endif
@@ -438,6 +471,17 @@ m188_ext_int(u_int v, struct trapframe *eframe)
goto out;
}
+#ifdef MULTIPROCESSOR
+ /*
+ * Clear IPIs immediately, so that we can re enable interrupts
+ * before further processing. We rely on the interrupt mask to
+ * make sure that if we get an IPI, it's really for us and
+ * no other processor.
+ */
+ if (IPI_MASK & cur_mask) {
+ *(volatile u_int32_t *)MVME188_CLRSWI = cur_mask & IPI_MASK;
+ }
+#endif
uvmexp.intrs++;
/*
@@ -447,15 +491,18 @@ m188_ext_int(u_int v, struct trapframe *eframe)
* priority.
*/
do {
+ level = safe_level(cur_mask & ~IPI_MASK, old_spl);
+ m188_setipl(level);
+ if (unmasked == 0) {
+ set_psr(get_psr() & ~PSR_IND);
+ unmasked = 1;
+ }
+
#ifdef MULTIPROCESSOR
/*
- * Check for IPIs first. We rely on the interrupt mask to
- * make sure that if we get an IPI, it's really for us and
- * no other processor.
+ * Handle IPIs first.
*/
if (IPI_MASK & cur_mask) {
- *(volatile u_int32_t *)MVME188_CLRSWI =
- cur_mask & IPI_MASK;
cur_mask &= ~IPI_MASK;
m188_ipi_handler(eframe);
@@ -464,20 +511,6 @@ m188_ext_int(u_int v, struct trapframe *eframe)
break;
}
#endif
- level = safe_level(cur_mask, old_spl);
- m188_setipl(level);
-
- /*
- * Do not enable interrupts yet if we know, from cur_mask,
- * that we have not cleared enough conditions yet.
- * For now, only the timer interrupt requires its condition
- * to be cleared before interrupts are enabled.
- */
- if (unmasked == 0 && (cur_mask & IRQ_DTI) == 0) {
- set_psr(get_psr() & ~PSR_IND);
- unmasked = 1;
- }
-
/* generate IACK and get the vector */
/*
@@ -776,34 +809,30 @@ m188_statintr(void *eframe)
statclock((struct clockframe *)eframe);
-#ifdef MULTIPROCESSOR
- if (CPU_IS_PRIMARY(curcpu())) {
- /*
- * Send an IPI to all other processors as well.
- */
- m88k_broadcast_ipi(CI_IPI_STATCLOCK);
-#endif
-
- /*
- * Compute new randomized interval. The intervals are
- * uniformly distributed on
- * [statint - statvar / 2, statint + statvar / 2],
- * and therefore have mean statint, giving a stathz
- * frequency clock.
- */
- var = statvar;
- do {
- r = random() & (var - 1);
- } while (r == 0);
- newint = statmin + r;
+ /*
+ * Compute new randomized interval. The intervals are
+ * uniformly distributed on
+ * [statint - statvar / 2, statint + statvar / 2],
+ * and therefore have mean statint, giving a stathz
+ * frequency clock.
+ */
+ var = statvar;
+ do {
+ r = random() & (var - 1);
+ } while (r == 0);
+ newint = statmin + r;
- /* setup new value and restart counter */
- *(volatile u_int8_t *)DART_CTUR = (newint >> 8);
- *(volatile u_int8_t *)DART_CTLR = (newint & 0xff);
- tmp = *(volatile u_int8_t *)DART_STARTC;
+ /* setup new value and restart counter */
+ *(volatile u_int8_t *)DART_CTUR = (newint >> 8);
+ *(volatile u_int8_t *)DART_CTLR = (newint & 0xff);
+ tmp = *(volatile u_int8_t *)DART_STARTC;
#ifdef MULTIPROCESSOR
- }
+ /*
+ * Send an IPI to all other processors as well.
+ */
+ if (CPU_IS_PRIMARY(curcpu()))
+ m88k_broadcast_ipi(CI_IPI_STATCLOCK);
#endif
return (1);