diff options
author | 2007-11-24 15:24:54 +0000 | |
---|---|---|
committer | 2007-11-24 15:24:54 +0000 | |
commit | 219b4331cfd19e6ada4da6731b7b9524263182db (patch) | |
tree | 9620655d24048bcd05c16280e62cfd6e06c05e6d /sys | |
parent | cope with incorrect extra arguments; from Rodolfo Gouveia (diff) | |
download | wireguard-openbsd-219b4331cfd19e6ada4da6731b7b9524263182db.tar.xz wireguard-openbsd-219b4331cfd19e6ada4da6731b7b9524263182db.zip |
Some macppc models (e.g. the 1.5 GHz G4 MacMini) have a large clock drift
which is due to the timecounter running at a different frequency than what
OpenFirmware tells us. On such machines, measure the actual timecounter
frequency (triggered by a table of affected models) and use this measured
value instead. This brings down the drift to values where adjtime()/adjfreq()
triggered by ntpd(8) can tame the clock.
feedback many, ok miod, kettenis
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/macppc/macppc/clock.c | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/sys/arch/macppc/macppc/clock.c b/sys/arch/macppc/macppc/clock.c index cc981575063..98f7a66c4a4 100644 --- a/sys/arch/macppc/macppc/clock.c +++ b/sys/arch/macppc/macppc/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.19 2007/04/13 18:48:38 kettenis Exp $ */ +/* $OpenBSD: clock.c,v 1.20 2007/11/24 15:24:54 mbalmer Exp $ */ /* $NetBSD: clock.c,v 1.1 1996/09/30 16:34:40 ws Exp $ */ /* @@ -60,6 +60,12 @@ static struct timecounter tb_timecounter = { tb_get_timecount, NULL, 0x7fffffff, 0, "tb", 0, NULL }; +/* calibrate the timecounter frequency for the listed models */ +static const char *calibrate_tc_models[] = { + "PowerMac10,1" +}; +extern char *hw_prod; + time_read_t *time_read; time_write_t *time_write; @@ -276,6 +282,37 @@ cpu_initclocks() int r; int minint; u_int64_t nextevent; + u_int32_t first_tb, second_tb; + time_t first_sec, sec; + int calibrate = 0, n; + + /* check if we should calibrate the timecounter frequency */ + for (n = 0; n < sizeof(calibrate_tc_models) / + sizeof(calibrate_tc_models[0]); n++) { + if (!strcmp(calibrate_tc_models[n], hw_prod)) { + calibrate = 1; + break; + } + } + + /* if a RTC is available, calibrate the timecounter frequency */ + if (calibrate && time_read != NULL) { + time_read(&first_sec); + do { + first_tb = ppc_mftbl(); + time_read(&sec); + } while (sec == first_sec); + first_sec = sec; + do { + second_tb = ppc_mftbl(); + time_read(&sec); + } while (sec == first_sec); + ticks_per_sec = second_tb - first_tb; +#ifdef DEBUG + printf("tb: using measured timecounter frequency of %ld Hz\n", + ticks_per_sec); +#endif + } intrstate = ppc_intr_disable(); @@ -292,7 +329,6 @@ cpu_initclocks() statmin = statint - (statvar >> 1); - lasttb = ppc_mftb(); nexttimerevent = lasttb + ticks_per_intr; do { |