diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2007-11-11 21:17:36 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2007-11-11 21:17:36 +0000 |
commit | 409c524e085621dfc152aab87b9f6583d4d3809e (patch) | |
tree | 3283eabe6b22b0e4d2a091e478142f08624057f5 /sys | |
parent | efc0d7610d05332988df4e9b265225271ae9b0ad (diff) |
Rework ipi handling to delay acking the maskable ipi interrupt, so that it
gets handled like a real hardware interrupt (which it is supposed to mimic
anyway).
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/mvme88k/mvme88k/m188_machdep.c | 104 |
1 files changed, 47 insertions, 57 deletions
diff --git a/sys/arch/mvme88k/mvme88k/m188_machdep.c b/sys/arch/mvme88k/mvme88k/m188_machdep.c index ba580512ea8..97493f2ecbe 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.35 2007/11/11 13:06:58 miod Exp $ */ +/* $OpenBSD: m188_machdep.c,v 1.36 2007/11/11 21:17:35 miod Exp $ */ /* * Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr. * Copyright (c) 1996 Nivas Madhur @@ -131,13 +131,13 @@ #include <mvme88k/mvme88k/clockvar.h> void m188_reset(void); -u_int safe_level(u_int mask, u_int curlevel); +u_int safe_level(u_int, u_int); void m188_bootstrap(void); void m188_ext_int(u_int, struct trapframe *); u_int m188_getipl(void); void m188_init_clocks(void); -void m188_ipi_handler(struct trapframe *); +void m188_ipi_handler(struct trapframe *, int *); vaddr_t m188_memsize(void); u_int m188_raiseipl(u_int); void m188_send_ipi(int, cpuid_t); @@ -260,6 +260,8 @@ safe_level(u_int mask, u_int curlevel) int i; #ifdef MULTIPROCESSOR + if (mask & CLOCK_IPI_MASK) + curlevel = max(IPL_CLOCK, curlevel); mask &= ~(IPI_MASK | CLOCK_IPI_MASK); #endif for (i = curlevel; i < INT_LEVEL; i++) @@ -363,14 +365,14 @@ m188_send_ipi(int ipi, cpuid_t cpu) * Process inter-processor interrupts. */ void -m188_ipi_handler(struct trapframe *eframe) +m188_ipi_handler(struct trapframe *eframe, int *mask) { struct cpu_info *ci = curcpu(); int ipi = ci->ci_ipi; - int retrig = 0; - int old_spl = eframe->tf_mask; int s; + *mask &= ~IPI_MASK; + if (ipi & CI_IPI_DDB) { #ifdef DDB /* @@ -388,34 +390,24 @@ m188_ipi_handler(struct trapframe *eframe) if (ipi & CI_IPI_NOTIFY) { /* nothing to do */ } - if (ipi & CI_IPI_HARDCLOCK) { - if (old_spl < IPL_CLOCK) { - s = m188_raiseipl(IPL_CLOCK); /* splclock */ - hardclock((struct clockframe *)eframe); - m188_setipl(s); /* splx */ - } else { - ipi &= ~CI_IPI_HARDCLOCK; /* leave it pending */ - retrig |= CI_IPI_HARDCLOCK; - } - } - if (ipi & CI_IPI_STATCLOCK) { - if (old_spl < IPL_STATCLOCK) { - s = m188_raiseipl(IPL_STATCLOCK); /* splclock */ - statclock((struct clockframe *)eframe); - m188_setipl(s); /* splx */ + + if (ipi & (CI_IPI_HARDCLOCK | CI_IPI_STATCLOCK)) { + if (eframe->tf_mask < IPL_CLOCK) { + /* clear clock ipi interrupt */ + *(volatile u_int32_t *)MVME188_CLRSWI = + SWI_CLOCK_IPI_BIT(ci->ci_cpuid); + *mask &= ~CLOCK_IPI_MASK; + + if (ipi & CI_IPI_HARDCLOCK) + hardclock((struct clockframe *)eframe); + if (ipi & CI_IPI_STATCLOCK) + statclock((struct clockframe *)eframe); } else { - ipi &= ~CI_IPI_STATCLOCK; /* leave it pending */ - retrig |= CI_IPI_STATCLOCK; + /* leave them pending */ + ipi &= ~(CI_IPI_HARDCLOCK | CI_IPI_STATCLOCK); } } - /* - * Retrigger the clock ipi if they could not be serviced yet. - */ - if (retrig != 0) - *(volatile u_int32_t *)MVME188_SETSWI = - SWI_CLOCK_IPI_BIT(ci->ci_cpuid); - atomic_clearbits_int(&ci->ci_ipi, ipi); } @@ -472,9 +464,9 @@ m188_ext_int(u_int v, struct trapframe *eframe) { #ifdef MULTIPROCESSOR struct cpu_info *ci = curcpu(); - int cpu = ci->ci_cpuid; + u_int cpu = ci->ci_cpuid; #else - int cpu = cpu_number(); + u_int cpu = cpu_number(); #endif unsigned int cur_mask, ign_mask; unsigned int level, old_spl; @@ -492,11 +484,6 @@ m188_ext_int(u_int v, struct trapframe *eframe) ign_mask = 0; old_spl = eframe->tf_mask; -#ifdef MULTIPROCESSOR - if (old_spl < IPL_SCHED) - __mp_lock(&kernel_lock); -#endif - if (cur_mask == 0) { /* * Spurious interrupts - may be caused by debug output clearing @@ -519,17 +506,19 @@ m188_ext_int(u_int v, struct trapframe *eframe) uvmexp.intrs++; #ifdef MULTIPROCESSOR + if (old_spl < IPL_SCHED) + __mp_lock(&kernel_lock); +#endif + +#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. + * Clear unmaskable IPIs immediately, so that we can reenable + * 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 (cur_mask & (IPI_MASK | CLOCK_IPI_MASK)) { - *(volatile u_int32_t *)MVME188_CLRSWI = - SWI_IPI_BIT(cpu) | SWI_CLOCK_IPI_BIT(cpu); - cur_mask &= ~(IPI_MASK | CLOCK_IPI_MASK); - } + if (cur_mask & IPI_MASK) + *(volatile u_int32_t *)MVME188_CLRSWI = SWI_IPI_BIT(cpu); #endif /* @@ -545,17 +534,18 @@ m188_ext_int(u_int v, struct trapframe *eframe) if (unmasked == 0) { set_psr(get_psr() & ~PSR_IND); unmasked = 1; + } #ifdef MULTIPROCESSOR - /* - * Handle IPIs first. - */ - m188_ipi_handler(eframe); - + /* + * Handle pending IPIs first. + */ + if (cur_mask & (IPI_MASK | CLOCK_IPI_MASK)) { + m188_ipi_handler(eframe, &cur_mask); if (cur_mask == 0) break; -#endif } +#endif /* generate IACK and get the vector */ @@ -662,6 +652,11 @@ m188_ext_int(u_int v, struct trapframe *eframe) problems = 0; #endif +#ifdef MULTIPROCESSOR + if (old_spl < IPL_SCHED) + __mp_unlock(&kernel_lock); +#endif + out: /* * process any remaining data access exceptions before @@ -675,11 +670,6 @@ out: * be restored later. */ set_psr(get_psr() | PSR_IND); - -#ifdef MULTIPROCESSOR - if (old_spl < IPL_SCHED) - __mp_unlock(&kernel_lock); -#endif } /* |