summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2008-08-07 18:46:05 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2008-08-07 18:46:05 +0000
commit0756250976a96a462bdd652e574aff72dc84f24e (patch)
tree218f9320e76b785dd28a5b369bef76392ae1eb0b
parente078bd48edab304aa7de2287d0abb15a6f835b66 (diff)
Give each CPU its own `struct intrhand' for %tick interrupts. Fixes a
problem where the clock would stop ticking on some CPUs because of lost ticks.
-rw-r--r--sys/arch/sparc64/include/cpu.h3
-rw-r--r--sys/arch/sparc64/sparc64/clock.c9
-rw-r--r--sys/arch/sparc64/sparc64/genassym.cf3
-rw-r--r--sys/arch/sparc64/sparc64/locore.s10
4 files changed, 17 insertions, 8 deletions
diff --git a/sys/arch/sparc64/include/cpu.h b/sys/arch/sparc64/include/cpu.h
index a6251debd25..08a9a48c29f 100644
--- a/sys/arch/sparc64/include/cpu.h
+++ b/sys/arch/sparc64/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.63 2008/07/18 23:43:31 art Exp $ */
+/* $OpenBSD: cpu.h,v 1.64 2008/08/07 18:46:04 kettenis Exp $ */
/* $NetBSD: cpu.h,v 1.28 2001/06/14 22:56:58 thorpej Exp $ */
/*
@@ -125,6 +125,7 @@ struct cpu_info {
int ci_handled_intr_level;
void *ci_intrpending[16][8];
u_int64_t ci_tick;
+ struct intrhand ci_tickintr;
/* DEBUG/DIAGNOSTIC stuff */
u_long ci_spin_locks; /* # of spin locks held */
diff --git a/sys/arch/sparc64/sparc64/clock.c b/sys/arch/sparc64/sparc64/clock.c
index f60899ccba0..a4018979f5d 100644
--- a/sys/arch/sparc64/sparc64/clock.c
+++ b/sys/arch/sparc64/sparc64/clock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clock.c,v 1.44 2008/07/15 22:49:01 kettenis Exp $ */
+/* $OpenBSD: clock.c,v 1.45 2008/08/07 18:46:04 kettenis Exp $ */
/* $NetBSD: clock.c,v 1.41 2001/07/24 19:29:25 eeh Exp $ */
/*
@@ -597,8 +597,11 @@ cpu_initclocks(void)
*/
if (!timerreg_4u.t_timer || !timerreg_4u.t_clrintr) {
+ struct cpu_info *ci;
+
/* We don't have a counter-timer -- use %tick */
level0.ih_clr = 0;
+
/*
* Establish a level 10 interrupt handler
*
@@ -608,6 +611,10 @@ cpu_initclocks(void)
level0.ih_number = 1;
strlcpy(level0.ih_name, "clock", sizeof(level0.ih_name));
intr_establish(10, &level0);
+
+ for (ci = cpus; ci != NULL; ci = ci->ci_next)
+ memcpy(&ci->ci_tickintr, &level0, sizeof(level0));
+
/* We only have one timer so we have no statclock */
stathz = 0;
diff --git a/sys/arch/sparc64/sparc64/genassym.cf b/sys/arch/sparc64/sparc64/genassym.cf
index e44f7bd03fe..563d79ad446 100644
--- a/sys/arch/sparc64/sparc64/genassym.cf
+++ b/sys/arch/sparc64/sparc64/genassym.cf
@@ -1,4 +1,4 @@
-# $OpenBSD: genassym.cf,v 1.32 2008/06/26 05:42:13 ray Exp $
+# $OpenBSD: genassym.cf,v 1.33 2008/08/07 18:46:04 kettenis Exp $
# $NetBSD: genassym.cf,v 1.23 2001/08/08 00:09:30 eeh Exp $
#
@@ -147,6 +147,7 @@ member ci_upaid
member ci_want_resched
member ci_handled_intr_level
member ci_intrpending
+member ci_tickintr
member ci_spinup
member ci_initstack
member ci_paddr
diff --git a/sys/arch/sparc64/sparc64/locore.s b/sys/arch/sparc64/sparc64/locore.s
index bfdc65fbc40..bb5d4dff754 100644
--- a/sys/arch/sparc64/sparc64/locore.s
+++ b/sys/arch/sparc64/sparc64/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.149 2008/07/28 19:08:46 miod Exp $ */
+/* $OpenBSD: locore.s,v 1.150 2008/08/07 18:46:04 kettenis Exp $ */
/* $NetBSD: locore.s,v 1.137 2001/08/13 06:10:10 jdolecek Exp $ */
/*
@@ -4282,12 +4282,12 @@ _C_LABEL(sparc_interrupt):
* If this is a %tick softint, clear it then call interrupt_vector.
*/
rd SOFTINT, %g1
- btst 1, %g1
+ btst TICK_INT, %g1
bz,pt %icc, 0f
- set _C_LABEL(intrlev), %g3
- wr %g0, 1, CLEAR_SOFTINT
+ GET_CPUINFO_VA(%g7)
+ wr %g0, TICK_INT, CLEAR_SOFTINT
ba,pt %icc, setup_sparcintr
- ldx [%g3 + 8], %g5 ! intrlev[1] is reserved for %tick intr.
+ add %g7, CI_TICKINTR, %g5
0:
INTR_SETUP -CC64FSZ-TF_SIZE-8