Add support for driving the clocks on secondary cpus.

Submitted by:	tmm
This commit is contained in:
Jake Burkholder 2002-03-13 04:38:33 +00:00
parent 8f5eafcdd1
commit 4968137eb9
2 changed files with 52 additions and 6 deletions

View File

@ -32,6 +32,9 @@
typedef void tick_func_t(struct clockframe *); typedef void tick_func_t(struct clockframe *);
void tick_start(u_long clock, tick_func_t *func); void tick_start(u_long clock, tick_func_t *func);
#ifdef SMP
void tick_start_ap(void);
#endif
void tick_stop(void); void tick_stop(void);
tick_func_t tick_hardclock; tick_func_t tick_hardclock;

View File

@ -32,26 +32,53 @@
#include <sys/bus.h> #include <sys/bus.h>
#include <sys/interrupt.h> #include <sys/interrupt.h>
#include <sys/timetc.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/frame.h>
#include <machine/intr_machdep.h> #include <machine/intr_machdep.h>
#include <machine/tick.h> #include <machine/tick.h>
#ifdef SMP
extern u_long tick_increment; #include <machine/cpu.h>
extern u_long tick_freq; #endif
extern u_long tick_MHz;
int tick_missed; /* statistics */ int tick_missed; /* statistics */
#define TICK_GRACE 1000 #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 void
tick_hardclock(struct clockframe *cf) tick_hardclock(struct clockframe *cf)
{ {
int missed; int missed;
u_long next; u_long next;
hardclock(cf); tick_process(cf);
/* /*
* Avoid stopping of hardclock in case we missed one tick period by * 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 * 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); wr(asr23, next, 0);
critical_exit(); critical_exit();
for (; missed > 0; missed--) for (; missed > 0; missed--)
hardclock(cf); tick_process(cf);
} }
void void
@ -84,6 +111,22 @@ tick_start(u_long clock, tick_func_t *func)
wr(asr23, clock / hz, 0); 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 void
tick_stop(void) tick_stop(void)
{ {