From 4968137eb9cb14bbe0736135234265dcd0569c4c Mon Sep 17 00:00:00 2001 From: Jake Burkholder Date: Wed, 13 Mar 2002 04:38:33 +0000 Subject: [PATCH] Add support for driving the clocks on secondary cpus. Submitted by: tmm --- sys/sparc64/include/tick.h | 3 +++ sys/sparc64/sparc64/tick.c | 55 +++++++++++++++++++++++++++++++++----- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/sys/sparc64/include/tick.h b/sys/sparc64/include/tick.h index 411aa86c76e1..924e58695a42 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 c7c81fabc3af..8c66b18ebeab 100644 --- a/sys/sparc64/sparc64/tick.c +++ b/sys/sparc64/sparc64/tick.c @@ -32,26 +32,53 @@ #include #include #include +#ifdef SMP +#include +#include +#include +#include +#include +#endif +#include #include #include #include - -extern u_long tick_increment; -extern u_long tick_freq; -extern u_long tick_MHz; +#ifdef SMP +#include +#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) {