summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormbalmer <mbalmer@openbsd.org>2007-11-24 15:24:54 +0000
committermbalmer <mbalmer@openbsd.org>2007-11-24 15:24:54 +0000
commit219b4331cfd19e6ada4da6731b7b9524263182db (patch)
tree9620655d24048bcd05c16280e62cfd6e06c05e6d
parentcope with incorrect extra arguments; from Rodolfo Gouveia (diff)
downloadwireguard-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
-rw-r--r--sys/arch/macppc/macppc/clock.c40
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 {