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, ®s); 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>