Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 May 1999 10:08:15 +0100 (BST)
From:      Doug Rabson <dfr@nlsystems.com>
To:        John Polstra <jdp@polstra.com>
Cc:        alpha@freebsd.org
Subject:   Re: Clock drift on the alpha
Message-ID:  <Pine.BSF.4.05.9905181007370.509-100000@herring.nlsystems.com>
In-Reply-To: <XFMail.990517184404.jdp@polstra.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 17 May 1999, John Polstra wrote:

> My alpha machine, which I suspect may be haunted, has pretty bad clock
> drift.  I started up xntpd, and the log messages will give you a sense
> of how bad the drift is:

Could you try this patch and see if it keeps better time:

Index: alpha/alpha/clock.c
===================================================================
RCS file: /home/ncvs/src/sys/alpha/alpha/clock.c,v
retrieving revision 1.8
diff -u -r1.8 clock.c
--- clock.c	1999/04/25 10:45:59	1.8
+++ clock.c	1999/05/18 09:01:54
@@ -114,6 +114,7 @@
 static u_int32_t last_time;
 
 static void handleclock(void* arg);
+static u_int32_t calibrate_clocks(u_int32_t firmware_freq);
 
 void
 clockattach(device_t dev)
@@ -150,6 +151,8 @@
 void
 cpu_initclocks()
 {
+	u_int32_t freq;
+
 	if (clockdev == NULL)
 		panic("cpu_initclocks: no clock attached");
 
@@ -175,11 +178,12 @@
 	 * hardclock, which would then fall over because p->p_stats
 	 * isn't set at that time.
 	 */
+	freq = calibrate_clocks(cycles_per_sec);
 	last_time = alpha_rpcc();
-	scaled_ticks_per_cycle = ((u_int64_t)hz << FIX_SHIFT) / cycles_per_sec;
-	max_cycles_per_tick = 2*cycles_per_sec / hz;
+	scaled_ticks_per_cycle = ((u_int64_t)hz << FIX_SHIFT) / freq;
+	max_cycles_per_tick = 2*freq / hz;
 
-	alpha_timecounter.tc_frequency = cycles_per_sec;
+	alpha_timecounter.tc_frequency = freq;
 	init_timecounter(&alpha_timecounter);
 
 	platform.clockintr = (void (*) __P((void *))) handleclock;
@@ -188,6 +192,60 @@
 	 * Get the clock started.
 	 */
 	CLOCK_INIT(clockdev);
+}
+
+static u_int32_t
+calibrate_clocks(u_int32_t firmware_freq)
+{
+	u_int32_t start_pcc, stop_pcc;
+	int sec, start_sec;
+
+	if (bootverbose)
+	        printf("Calibrating clock(s) ... ");
+
+	/* Read the mc146818A seconds counter. */
+	if (CLOCK_GETSECS(clockdev, &sec))
+		goto fail;
+
+	/* Wait for the mC146818A seconds counter to change. */
+	start_sec = sec;
+	for (;;) {
+		if (CLOCK_GETSECS(clockdev, &sec))
+			goto fail;
+		if (sec != start_sec)
+			break;
+	}
+
+	/* Start keeping track of the PCC. */
+	start_pcc = alpha_rpcc();
+
+	/*
+	 * Wait for the mc146818A seconds counter to change.
+	 */
+	start_sec = sec;
+	for (;;) {
+		if (CLOCK_GETSECS(clockdev, &sec))
+			goto fail;
+		if (sec != start_sec)
+			break;
+	}
+
+	/*
+	 * Read the PCC again to work out frequency.
+	 */
+	stop_pcc = alpha_rpcc();
+
+	if (bootverbose) {
+	        printf("PCC clock: %u Hz (firmware %u Hz)\n",
+		       stop_pcc - start_pcc, firmware_freq);
+	}
+	return (stop_pcc - start_pcc);
+
+fail:
+	if (bootverbose)
+	        printf("failed, using firmware default of %u Hz\n",
+		       firmware_freq);
+	return (firmware_freq);
 }
 
 static void
Index: alpha/alpha/clock_if.m
===================================================================
RCS file: /home/ncvs/src/sys/alpha/alpha/clock_if.m,v
retrieving revision 1.2
diff -u -r1.2 clock_if.m
--- clock_if.m	1998/11/08 18:35:51	1.2
+++ clock_if.m	1999/05/18 09:01:18
@@ -44,3 +44,8 @@
 	device_t dev;
 	struct clocktime *ct;
 };
+
+METHOD int getsecs {
+	device_t dev;
+	int *secp;
+};
Index: alpha/isa/mcclock_isa.c
===================================================================
RCS file: /home/ncvs/src/sys/alpha/isa/mcclock_isa.c,v
retrieving revision 1.4
diff -u -r1.4 mcclock_isa.c
--- mcclock_isa.c	1999/05/08 21:58:38	1.4
+++ mcclock_isa.c	1999/05/18 08:48:15
@@ -61,6 +61,7 @@
 	DEVMETHOD(clock_init,		mcclock_init),
 	DEVMETHOD(clock_get,		mcclock_get),
 	DEVMETHOD(clock_set,		mcclock_set),
+	DEVMETHOD(clock_getsecs,	mcclock_getsecs),
 
 	{ 0, 0 }
 };
Index: alpha/tlsb/mcclock_tlsb.c
===================================================================
RCS file: /home/ncvs/src/sys/alpha/tlsb/mcclock_tlsb.c,v
retrieving revision 1.4
diff -u -r1.4 mcclock_tlsb.c
--- mcclock_tlsb.c	1999/05/08 21:58:53	1.4
+++ mcclock_tlsb.c	1999/05/18 08:48:52
@@ -74,6 +74,7 @@
 	DEVMETHOD(clock_init,		mcclock_init),
 	DEVMETHOD(clock_get,		mcclock_get),
 	DEVMETHOD(clock_set,		mcclock_set),
+	DEVMETHOD(clock_getsecs,	mcclock_getsecs),
 
 	{ 0, 0 }
 };
Index: dev/dec/mcclock.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/dec/mcclock.c,v
retrieving revision 1.2
diff -u -r1.2 mcclock.c
--- mcclock.c	1998/06/14 13:45:41	1.2
+++ mcclock.c	1999/05/18 09:02:08
@@ -111,3 +111,29 @@
 	MC146818_PUTTOD(dev, &regs);
 	splx(s);
 }
+
+int
+mcclock_getsecs(device_t dev, int *secp)
+{
+	int timeout = 100000000;
+	int sec;
+	int s;
+
+	s = splclock();
+	for (;;) {
+		if (!(MCCLOCK_READ(dev, MC_REGA) & MC_REGA_UIP)) {
+			sec = MCCLOCK_READ(dev, MC_SEC);
+			break;
+		}
+		if (--timeout == 0)
+			goto fail;
+	}
+
+	splx(s);
+	*secp = sec;
+	return 0;
+
+ fail:
+	splx(s);
+	return ETIMEDOUT;
+}
Index: dev/dec/mcclockvar.h
===================================================================
RCS file: /home/ncvs/src/sys/dev/dec/mcclockvar.h,v
retrieving revision 1.2
diff -u -r1.2 mcclockvar.h
--- mcclockvar.h	1998/06/14 13:45:42	1.2
+++ mcclockvar.h	1999/05/18 08:48:32
@@ -33,3 +33,4 @@
 void	mcclock_init(device_t);
 void	mcclock_get(device_t, time_t, struct clocktime *);
 void	mcclock_set(device_t, struct clocktime *);
+int	mcclock_getsecs(device_t dev, int *secp);

--
Doug Rabson				Mail:  dfr@nlsystems.com
Nonlinear Systems Ltd.			Phone: +44 181 442 9037




To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-alpha" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.05.9905181007370.509-100000>