summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjake <jake@FreeBSD.org>2002-03-13 04:38:33 +0000
committerjake <jake@FreeBSD.org>2002-03-13 04:38:33 +0000
commit2b8f2f82cfdd5f90b36a899f4d0e27b89e241302 (patch)
tree0a1c28acd8bfd36cb0d01257470780ec2f39ffe7 /sys
parentddffcffd5c37a6a92ce89163a674951a01c2ea1d (diff)
downloadFreeBSD-src-2b8f2f82cfdd5f90b36a899f4d0e27b89e241302.zip
FreeBSD-src-2b8f2f82cfdd5f90b36a899f4d0e27b89e241302.tar.gz
Add support for driving the clocks on secondary cpus.
Submitted by: tmm
Diffstat (limited to 'sys')
-rw-r--r--sys/sparc64/include/tick.h3
-rw-r--r--sys/sparc64/sparc64/tick.c55
2 files changed, 52 insertions, 6 deletions
diff --git a/sys/sparc64/include/tick.h b/sys/sparc64/include/tick.h
index 411aa86..924e586 100644
--- a/sys/sparc64/include/tick.h
+++ b/sys/sparc64/include/tick.h
@@ -32,6 +32,9 @@
typedef void tick_func_t(struct clockframe *);
void tick_start(u_long clock, tick_func_t *func);
+#ifdef SMP
+void tick_start_ap(void);
+#endif
void tick_stop(void);
tick_func_t tick_hardclock;
diff --git a/sys/sparc64/sparc64/tick.c b/sys/sparc64/sparc64/tick.c
index c7c81fa..8c66b18 100644
--- a/sys/sparc64/sparc64/tick.c
+++ b/sys/sparc64/sparc64/tick.c
@@ -32,26 +32,53 @@
#include <sys/bus.h>
#include <sys/interrupt.h>
#include <sys/timetc.h>
+#ifdef SMP
+#include <sys/ktr.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#endif
+#include <machine/clock.h>
#include <machine/frame.h>
#include <machine/intr_machdep.h>
#include <machine/tick.h>
-
-extern u_long tick_increment;
-extern u_long tick_freq;
-extern u_long tick_MHz;
+#ifdef SMP
+#include <machine/cpu.h>
+#endif
int tick_missed; /* statistics */
#define TICK_GRACE 1000
+static __inline void
+tick_process(struct clockframe *cf)
+{
+
+#ifdef SMP
+ if (PCPU_GET(cpuid) == 0)
+ hardclock(cf);
+ else {
+ CTR1(KTR_CLK, "tick_process: AP, cpuid=%d", PCPU_GET(cpuid));
+ mtx_lock_spin_flags(&sched_lock, MTX_QUIET);
+ hardclock_process(curthread, CLKF_USERMODE(cf));
+ statclock_process(curthread->td_kse, CLKF_PC(cf),
+ CLKF_USERMODE(cf));
+ mtx_unlock_spin_flags(&sched_lock, MTX_QUIET);
+ }
+#else
+ hardclock(cf);
+#endif
+}
+
void
tick_hardclock(struct clockframe *cf)
{
int missed;
u_long next;
- hardclock(cf);
+ tick_process(cf);
/*
* Avoid stopping of hardclock in case we missed one tick period by
* ensuring that the the value of the next tick is at least TICK_GRACE
@@ -70,7 +97,7 @@ tick_hardclock(struct clockframe *cf)
wr(asr23, next, 0);
critical_exit();
for (; missed > 0; missed--)
- hardclock(cf);
+ tick_process(cf);
}
void
@@ -84,6 +111,22 @@ tick_start(u_long clock, tick_func_t *func)
wr(asr23, clock / hz, 0);
}
+#ifdef SMP
+void
+tick_start_ap(void)
+{
+ u_long base;
+
+ /*
+ * Try to make the ticks interrupt as synchronously as possible to
+ * avoid inaccuracies for migrating processes. Leave out one tick to
+ * make sure that it is not missed.
+ */
+ base = rd(tick);
+ wr(asr23, roundup(base, tick_increment) + tick_increment, 0);
+}
+#endif
+
void
tick_stop(void)
{
OpenPOWER on IntegriCloud