diff options
author | jake <jake@FreeBSD.org> | 2002-03-13 04:38:33 +0000 |
---|---|---|
committer | jake <jake@FreeBSD.org> | 2002-03-13 04:38:33 +0000 |
commit | 2b8f2f82cfdd5f90b36a899f4d0e27b89e241302 (patch) | |
tree | 0a1c28acd8bfd36cb0d01257470780ec2f39ffe7 /sys/sparc64 | |
parent | ddffcffd5c37a6a92ce89163a674951a01c2ea1d (diff) | |
download | FreeBSD-src-2b8f2f82cfdd5f90b36a899f4d0e27b89e241302.zip FreeBSD-src-2b8f2f82cfdd5f90b36a899f4d0e27b89e241302.tar.gz |
Add support for driving the clocks on secondary cpus.
Submitted by: tmm
Diffstat (limited to 'sys/sparc64')
-rw-r--r-- | sys/sparc64/include/tick.h | 3 | ||||
-rw-r--r-- | 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 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) { |