kern_ntptime.c revision 55413
144574Sphk/*********************************************************************** 244574Sphk * * 345294Sphk * Copyright (c) David L. Mills 1993-1999 * 444574Sphk * * 544574Sphk * Permission to use, copy, modify, and distribute this software and * 644574Sphk * its documentation for any purpose and without fee is hereby * 744574Sphk * granted, provided that the above copyright notice appears in all * 844574Sphk * copies and that both the copyright notice and this permission * 944574Sphk * notice appear in supporting documentation, and that the name * 1044574Sphk * University of Delaware not be used in advertising or publicity * 1144574Sphk * pertaining to distribution of the software without specific, * 1244574Sphk * written prior permission. The University of Delaware makes no * 1344574Sphk * representations about the suitability this software for any * 1444574Sphk * purpose. It is provided "as is" without express or implied * 1544574Sphk * warranty. * 1644574Sphk * * 1744574Sphk **********************************************************************/ 182858Swollman 192858Swollman/* 2044574Sphk * Adapted from the original sources for FreeBSD and timecounters by: 2144666Sphk * Poul-Henning Kamp <phk@FreeBSD.org>. 222858Swollman * 2344574Sphk * The 32bit version of the "LP" macros seems a bit past its "sell by" 2444574Sphk * date so I have retained only the 64bit version and included it directly 2544574Sphk * in this file. 2621101Sjhay * 2744574Sphk * Only minor changes done to interface with the timecounters over in 2844574Sphk * sys/kern/kern_clock.c. Some of the comments below may be (even more) 2944574Sphk * confusing and/or plain wrong in that context. 3055219Sphk * 3155219Sphk * $FreeBSD: head/sys/kern/kern_ntptime.c 55413 2000-01-04 12:04:39Z phk $ 322858Swollman */ 3332925Seivind 3444666Sphk#include "opt_ntp.h" 3544666Sphk 362858Swollman#include <sys/param.h> 372858Swollman#include <sys/systm.h> 3812221Sbde#include <sys/sysproto.h> 392858Swollman#include <sys/kernel.h> 402858Swollman#include <sys/proc.h> 4144574Sphk#include <sys/time.h> 422858Swollman#include <sys/timex.h> 4336941Sphk#include <sys/timepps.h> 442858Swollman#include <sys/sysctl.h> 452858Swollman 462858Swollman/* 4744574Sphk * Single-precision macros for 64-bit machines 4844574Sphk */ 4944574Sphktypedef long long l_fp; 5044574Sphk#define L_ADD(v, u) ((v) += (u)) 5144574Sphk#define L_SUB(v, u) ((v) -= (u)) 5244574Sphk#define L_ADDHI(v, a) ((v) += (long long)(a) << 32) 5344574Sphk#define L_NEG(v) ((v) = -(v)) 5444574Sphk#define L_RSHIFT(v, n) \ 5544574Sphk do { \ 5644574Sphk if ((v) < 0) \ 5744574Sphk (v) = -(-(v) >> (n)); \ 5844574Sphk else \ 5944574Sphk (v) = (v) >> (n); \ 6044574Sphk } while (0) 6144574Sphk#define L_MPY(v, a) ((v) *= (a)) 6244574Sphk#define L_CLR(v) ((v) = 0) 6344574Sphk#define L_ISNEG(v) ((v) < 0) 6444574Sphk#define L_LINT(v, a) ((v) = (long long)(a) << 32) 6544574Sphk#define L_GINT(v) ((v) < 0 ? -(-(v) >> 32) : (v) >> 32) 6644574Sphk 6744574Sphk/* 6844574Sphk * Generic NTP kernel interface 6932513Sphk * 7044574Sphk * These routines constitute the Network Time Protocol (NTP) interfaces 7144574Sphk * for user and daemon application programs. The ntp_gettime() routine 7244574Sphk * provides the time, maximum error (synch distance) and estimated error 7344574Sphk * (dispersion) to client user application programs. The ntp_adjtime() 7444574Sphk * routine is used by the NTP daemon to adjust the system clock to an 7544574Sphk * externally derived time. The time offset and related variables set by 7644574Sphk * this routine are used by other routines in this module to adjust the 7744574Sphk * phase and frequency of the clock discipline loop which controls the 7844574Sphk * system clock. 7932513Sphk * 8045294Sphk * When the kernel time is reckoned directly in nanoseconds (NTP_NANO 8144574Sphk * defined), the time at each tick interrupt is derived directly from 8244574Sphk * the kernel time variable. When the kernel time is reckoned in 8345294Sphk * microseconds, (NTP_NANO undefined), the time is derived from the 8445294Sphk * kernel time variable together with a variable representing the 8545294Sphk * leftover nanoseconds at the last tick interrupt. In either case, the 8645294Sphk * current nanosecond time is reckoned from these values plus an 8745294Sphk * interpolated value derived by the clock routines in another 8845294Sphk * architecture-specific module. The interpolation can use either a 8945294Sphk * dedicated counter or a processor cycle counter (PCC) implemented in 9045294Sphk * some architectures. 9132513Sphk * 9244574Sphk * Note that all routines must run at priority splclock or higher. 9344574Sphk */ 9444574Sphk 9544574Sphk/* 9644574Sphk * Phase/frequency-lock loop (PLL/FLL) definitions 9732513Sphk * 9844574Sphk * The nanosecond clock discipline uses two variable types, time 9944574Sphk * variables and frequency variables. Both types are represented as 64- 10044574Sphk * bit fixed-point quantities with the decimal point between two 32-bit 10144574Sphk * halves. On a 32-bit machine, each half is represented as a single 10244574Sphk * word and mathematical operations are done using multiple-precision 10344574Sphk * arithmetic. On a 64-bit machine, ordinary computer arithmetic is 10444574Sphk * used. 10532513Sphk * 10644574Sphk * A time variable is a signed 64-bit fixed-point number in ns and 10744574Sphk * fraction. It represents the remaining time offset to be amortized 10844574Sphk * over succeeding tick interrupts. The maximum time offset is about 10945294Sphk * 0.5 s and the resolution is about 2.3e-10 ns. 11032513Sphk * 11144574Sphk * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 11244574Sphk * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 11344574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 11444574Sphk * |s s s| ns | 11544574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 11644574Sphk * | fraction | 11744574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 11832513Sphk * 11944574Sphk * A frequency variable is a signed 64-bit fixed-point number in ns/s 12044574Sphk * and fraction. It represents the ns and fraction to be added to the 12144574Sphk * kernel time variable at each second. The maximum frequency offset is 12245294Sphk * about +-500000 ns/s and the resolution is about 2.3e-10 ns/s. 12332513Sphk * 12444574Sphk * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 12544574Sphk * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 12644574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 12744574Sphk * |s s s s s s s s s s s s s| ns/s | 12844574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 12944574Sphk * | fraction | 13044574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1312858Swollman */ 13232513Sphk/* 13332513Sphk * The following variables establish the state of the PLL/FLL and the 13444574Sphk * residual time and frequency offset of the local clock. 13532513Sphk */ 13644574Sphk#define SHIFT_PLL 4 /* PLL loop gain (shift) */ 13744574Sphk#define SHIFT_FLL 2 /* FLL loop gain (shift) */ 13832513Sphk 13944574Sphkstatic int time_state = TIME_OK; /* clock state */ 14044574Sphkstatic int time_status = STA_UNSYNC; /* clock status bits */ 14144574Sphkstatic long time_constant; /* poll interval (shift) (s) */ 14244574Sphkstatic long time_precision = 1; /* clock precision (ns) */ 14344574Sphkstatic long time_maxerror = MAXPHASE / 1000; /* maximum error (us) */ 14444574Sphkstatic long time_esterror = MAXPHASE / 1000; /* estimated error (us) */ 14544574Sphkstatic long time_reftime; /* time at last adjustment (s) */ 14644574Sphkstatic long time_tick; /* nanoseconds per tick (ns) */ 14744574Sphkstatic l_fp time_offset; /* time offset (ns) */ 14844574Sphkstatic l_fp time_freq; /* frequency offset (ns/s) */ 14944574Sphk 1502858Swollman#ifdef PPS_SYNC 1512858Swollman/* 15244574Sphk * The following variables are used when a pulse-per-second (PPS) signal 15344574Sphk * is available and connected via a modem control lead. They establish 15444574Sphk * the engineering parameters of the clock discipline loop when 15544574Sphk * controlled by the PPS signal. 1562858Swollman */ 15744574Sphk#define PPS_FAVG 2 /* min freq avg interval (s) (shift) */ 15850656Sphk#define PPS_FAVGDEF 7 /* default freq avg int (s) (shift) */ 15950656Sphk#define PPS_FAVGMAX 15 /* max freq avg interval (s) (shift) */ 16044574Sphk#define PPS_PAVG 4 /* phase avg interval (s) (shift) */ 16144574Sphk#define PPS_VALID 120 /* PPS signal watchdog max (s) */ 16250656Sphk#define PPS_MAXWANDER 100000 /* max PPS wander (ns/s) */ 16350656Sphk#define PPS_POPCORN 2 /* popcorn spike threshold (shift) */ 16432513Sphk 16550656Sphkstatic struct timespec pps_tf[3]; /* phase median filter */ 16655413Sphkstatic l_fp pps_offset; /* time offset (ns) */ 16744574Sphkstatic l_fp pps_freq; /* scaled frequency offset (ns/s) */ 16845294Sphkstatic long pps_fcount; /* frequency accumulator */ 16950656Sphkstatic long pps_jitter; /* nominal jitter (ns) */ 17050656Sphkstatic long pps_stabil; /* nominal stability (scaled ns/s) */ 17144574Sphkstatic long pps_lastsec; /* time at last calibration (s) */ 17244574Sphkstatic int pps_valid; /* signal watchdog counter */ 17344574Sphkstatic int pps_shift = PPS_FAVG; /* interval duration (s) (shift) */ 17450656Sphkstatic int pps_shiftmax = PPS_FAVGDEF; /* max interval duration (s) (shift) */ 17544574Sphkstatic int pps_intcnt; /* wander counter */ 17644574Sphk 17732513Sphk/* 17832513Sphk * PPS signal quality monitors 17932513Sphk */ 18044574Sphkstatic long pps_calcnt; /* calibration intervals */ 18144574Sphkstatic long pps_jitcnt; /* jitter limit exceeded */ 18244574Sphkstatic long pps_stbcnt; /* stability limit exceeded */ 18344574Sphkstatic long pps_errcnt; /* calibration errors */ 1842858Swollman#endif /* PPS_SYNC */ 18532513Sphk/* 18644574Sphk * End of phase/frequency-lock loop (PLL/FLL) definitions 18732513Sphk */ 18832513Sphk 18944574Sphkstatic void ntp_init(void); 19044574Sphkstatic void hardupdate(long offset); 19132513Sphk 19233690Sphk/* 19344574Sphk * ntp_gettime() - NTP user application interface 19433690Sphk * 19544574Sphk * See the timex.h header file for synopsis and API description. 19633690Sphk */ 19712279Sphkstatic int 19812279Sphkntp_sysctl SYSCTL_HANDLER_ARGS 1992858Swollman{ 20044574Sphk struct ntptimeval ntv; /* temporary structure */ 20144574Sphk struct timespec atv; /* nanosecond time */ 2022858Swollman 20344574Sphk nanotime(&atv); 20444574Sphk ntv.time.tv_sec = atv.tv_sec; 20544574Sphk ntv.time.tv_nsec = atv.tv_nsec; 2062858Swollman ntv.maxerror = time_maxerror; 2072858Swollman ntv.esterror = time_esterror; 2082858Swollman ntv.time_state = time_state; 2092858Swollman 2102858Swollman /* 21144574Sphk * Status word error decode. If any of these conditions occur, 21244574Sphk * an error is returned, instead of the status word. Most 21344574Sphk * applications will care only about the fact the system clock 21444574Sphk * may not be trusted, not about the details. 2152858Swollman * 2162858Swollman * Hardware or software error 2172858Swollman */ 21844574Sphk if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) || 2192858Swollman 2202858Swollman /* 22144574Sphk * PPS signal lost when either time or frequency synchronization 22244574Sphk * requested 2232858Swollman */ 22444574Sphk (time_status & (STA_PPSFREQ | STA_PPSTIME) && 22544574Sphk !(time_status & STA_PPSSIGNAL)) || 2262858Swollman 2272858Swollman /* 22844574Sphk * PPS jitter exceeded when time synchronization requested 2292858Swollman */ 23044574Sphk (time_status & STA_PPSTIME && 23144574Sphk time_status & STA_PPSJITTER) || 2322858Swollman 2332858Swollman /* 23444574Sphk * PPS wander exceeded or calibration error when frequency 23544574Sphk * synchronization requested 2362858Swollman */ 23744574Sphk (time_status & STA_PPSFREQ && 23844574Sphk time_status & (STA_PPSWANDER | STA_PPSERROR))) 2392858Swollman ntv.time_state = TIME_ERROR; 24012279Sphk return (sysctl_handle_opaque(oidp, &ntv, sizeof ntv, req)); 2412858Swollman} 2422858Swollman 24344574SphkSYSCTL_NODE(_kern, OID_AUTO, ntp_pll, CTLFLAG_RW, 0, ""); 24444574SphkSYSCTL_PROC(_kern_ntp_pll, OID_AUTO, gettime, CTLTYPE_OPAQUE|CTLFLAG_RD, 24512623Sphk 0, sizeof(struct ntptimeval) , ntp_sysctl, "S,ntptimeval", ""); 24612279Sphk 24750663Sphk#ifdef PPS_SYNC 24850656SphkSYSCTL_INT(_kern_ntp_pll, OID_AUTO, pps_shiftmax, CTLFLAG_RW, &pps_shiftmax, 0, ""); 24955413SphkSYSCTL_INT(_kern_ntp_pll, OID_AUTO, pps_shift, CTLFLAG_RW, &pps_shift, 0, ""); 25050663Sphk#endif 2512858Swollman/* 2522858Swollman * ntp_adjtime() - NTP daemon application interface 25344574Sphk * 25444574Sphk * See the timex.h header file for synopsis and API description. 2552858Swollman */ 25612221Sbde#ifndef _SYS_SYSPROTO_H_ 2572858Swollmanstruct ntp_adjtime_args { 25844574Sphk struct timex *tp; 2592858Swollman}; 26012221Sbde#endif 2612858Swollman 2622858Swollmanint 26330994Sphkntp_adjtime(struct proc *p, struct ntp_adjtime_args *uap) 2642858Swollman{ 26544574Sphk struct timex ntv; /* temporary structure */ 26645294Sphk long freq; /* frequency ns/s) */ 26744574Sphk int modes; /* mode bits from structure */ 26844574Sphk int s; /* caller priority */ 2692858Swollman int error; 2702858Swollman 2712858Swollman error = copyin((caddr_t)uap->tp, (caddr_t)&ntv, sizeof(ntv)); 2722858Swollman if (error) 27344574Sphk return(error); 2742858Swollman 2752858Swollman /* 2762858Swollman * Update selected clock variables - only the superuser can 2772858Swollman * change anything. Note that there is no error checking here on 2782858Swollman * the assumption the superuser should know what it is doing. 2792858Swollman */ 2802858Swollman modes = ntv.modes; 28144776Sphk if (modes) 28246112Sphk error = suser(p); 28344574Sphk if (error) 28444574Sphk return (error); 2852858Swollman s = splclock(); 28644574Sphk if (modes & MOD_FREQUENCY) { 28745302Sphk freq = (ntv.freq * 1000LL) >> 16; 28845294Sphk if (freq > MAXFREQ) 28945294Sphk L_LINT(time_freq, MAXFREQ); 29045294Sphk else if (freq < -MAXFREQ) 29145294Sphk L_LINT(time_freq, -MAXFREQ); 29245294Sphk else 29345294Sphk L_LINT(time_freq, freq); 29445294Sphk 2952858Swollman#ifdef PPS_SYNC 29644574Sphk pps_freq = time_freq; 2972858Swollman#endif /* PPS_SYNC */ 29844574Sphk } 2992858Swollman if (modes & MOD_MAXERROR) 3002858Swollman time_maxerror = ntv.maxerror; 3012858Swollman if (modes & MOD_ESTERROR) 3022858Swollman time_esterror = ntv.esterror; 3032858Swollman if (modes & MOD_STATUS) { 3042858Swollman time_status &= STA_RONLY; 3052858Swollman time_status |= ntv.status & ~STA_RONLY; 3062858Swollman } 30745294Sphk if (modes & MOD_TIMECONST) { 30845294Sphk if (ntv.constant < 0) 30945294Sphk time_constant = 0; 31045294Sphk else if (ntv.constant > MAXTC) 31145294Sphk time_constant = MAXTC; 31245294Sphk else 31345294Sphk time_constant = ntv.constant; 31445294Sphk } 31550656Sphk#ifdef PPS_SYNC 31650656Sphk if (modes & MOD_PPSMAX) { 31750656Sphk if (ntv.shift < PPS_FAVG) 31850656Sphk pps_shiftmax = PPS_FAVG; 31950656Sphk else if (ntv.shift > PPS_FAVGMAX) 32050656Sphk pps_shiftmax = PPS_FAVGMAX; 32150656Sphk else 32250656Sphk pps_shiftmax = ntv.shift; 32350656Sphk } 32450656Sphk#endif /* PPS_SYNC */ 32544574Sphk if (modes & MOD_NANO) 32644574Sphk time_status |= STA_NANO; 32744574Sphk if (modes & MOD_MICRO) 32844574Sphk time_status &= ~STA_NANO; 32944574Sphk if (modes & MOD_CLKB) 33044574Sphk time_status |= STA_CLK; 33144574Sphk if (modes & MOD_CLKA) 33244574Sphk time_status &= ~STA_CLK; 33344574Sphk if (modes & MOD_OFFSET) { 33444574Sphk if (time_status & STA_NANO) 33544574Sphk hardupdate(ntv.offset); 33644574Sphk else 33744574Sphk hardupdate(ntv.offset * 1000); 33844574Sphk } 3392858Swollman 3402858Swollman /* 3412858Swollman * Retrieve all clock variables 3422858Swollman */ 34344574Sphk if (time_status & STA_NANO) 34444574Sphk ntv.offset = L_GINT(time_offset); 3452858Swollman else 34644574Sphk ntv.offset = L_GINT(time_offset) / 1000; 34745295Sphk ntv.freq = L_GINT((time_freq / 1000LL) << 16); 3482858Swollman ntv.maxerror = time_maxerror; 3492858Swollman ntv.esterror = time_esterror; 3502858Swollman ntv.status = time_status; 35145294Sphk ntv.constant = time_constant; 35244574Sphk if (time_status & STA_NANO) 35344574Sphk ntv.precision = time_precision; 35444574Sphk else 35544574Sphk ntv.precision = time_precision / 1000; 35644574Sphk ntv.tolerance = MAXFREQ * SCALE_PPM; 3572858Swollman#ifdef PPS_SYNC 3582858Swollman ntv.shift = pps_shift; 35945295Sphk ntv.ppsfreq = L_GINT((pps_freq / 1000LL) << 16); 36044574Sphk if (time_status & STA_NANO) 36144574Sphk ntv.jitter = pps_jitter; 36244574Sphk else 36344574Sphk ntv.jitter = pps_jitter / 1000; 3642858Swollman ntv.stabil = pps_stabil; 3652858Swollman ntv.calcnt = pps_calcnt; 3662858Swollman ntv.errcnt = pps_errcnt; 3672858Swollman ntv.jitcnt = pps_jitcnt; 3682858Swollman ntv.stbcnt = pps_stbcnt; 3692858Swollman#endif /* PPS_SYNC */ 37044574Sphk splx(s); 3712858Swollman 3722858Swollman error = copyout((caddr_t)&ntv, (caddr_t)uap->tp, sizeof(ntv)); 37344574Sphk if (error) 37444574Sphk return (error); 37544574Sphk 37644574Sphk /* 37744574Sphk * Status word error decode. See comments in 37844574Sphk * ntp_gettime() routine. 37944574Sphk */ 38044574Sphk if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) || 38144574Sphk (time_status & (STA_PPSFREQ | STA_PPSTIME) && 38244574Sphk !(time_status & STA_PPSSIGNAL)) || 38344574Sphk (time_status & STA_PPSTIME && 38444574Sphk time_status & STA_PPSJITTER) || 38544574Sphk (time_status & STA_PPSFREQ && 38644574Sphk time_status & (STA_PPSWANDER | STA_PPSERROR))) 38745302Sphk p->p_retval[0] = TIME_ERROR; 38845302Sphk else 38945302Sphk p->p_retval[0] = time_state; 39045302Sphk return (error); 39144574Sphk} 39244574Sphk 39344574Sphk/* 39444574Sphk * second_overflow() - called after ntp_tick_adjust() 39544574Sphk * 39644574Sphk * This routine is ordinarily called immediately following the above 39744574Sphk * routine ntp_tick_adjust(). While these two routines are normally 39844574Sphk * combined, they are separated here only for the purposes of 39944574Sphk * simulation. 40044574Sphk */ 40144574Sphkvoid 40244574Sphkntp_update_second(struct timecounter *tcp) 40344574Sphk{ 40444574Sphk u_int32_t *newsec; 40555219Sphk l_fp time_adj; /* 32/64-bit temporaries */ 40644574Sphk 40744574Sphk newsec = &tcp->tc_offset_sec; 40850656Sphk /* 40950656Sphk * On rollover of the second both the nanosecond and microsecond 41050656Sphk * clocks are updated and the state machine cranked as 41150656Sphk * necessary. The phase adjustment to be used for the next 41250656Sphk * second is calculated and the maximum error is increased by 41350656Sphk * the tolerance. 41450656Sphk */ 41544574Sphk time_maxerror += MAXFREQ / 1000; 41644574Sphk 41744574Sphk /* 41844574Sphk * Leap second processing. If in leap-insert state at 41944574Sphk * the end of the day, the system clock is set back one 42044574Sphk * second; if in leap-delete state, the system clock is 42144574Sphk * set ahead one second. The nano_time() routine or 42244574Sphk * external clock driver will insure that reported time 42344574Sphk * is always monotonic. 42444574Sphk */ 42544574Sphk switch (time_state) { 42644574Sphk 4272858Swollman /* 42844574Sphk * No warning. 4292858Swollman */ 43044574Sphk case TIME_OK: 43144574Sphk if (time_status & STA_INS) 43244574Sphk time_state = TIME_INS; 43344574Sphk else if (time_status & STA_DEL) 43444574Sphk time_state = TIME_DEL; 43544574Sphk break; 43644574Sphk 43744574Sphk /* 43844574Sphk * Insert second 23:59:60 following second 43944574Sphk * 23:59:59. 44044574Sphk */ 44144574Sphk case TIME_INS: 44244574Sphk if (!(time_status & STA_INS)) 44344574Sphk time_state = TIME_OK; 44444574Sphk else if ((*newsec) % 86400 == 0) { 44544574Sphk (*newsec)--; 44644574Sphk time_state = TIME_OOP; 44744574Sphk } 44844574Sphk break; 44944574Sphk 45044574Sphk /* 45144574Sphk * Delete second 23:59:59. 45244574Sphk */ 45344574Sphk case TIME_DEL: 45444574Sphk if (!(time_status & STA_DEL)) 45544574Sphk time_state = TIME_OK; 45644574Sphk else if (((*newsec) + 1) % 86400 == 0) { 45744574Sphk (*newsec)++; 45844574Sphk time_state = TIME_WAIT; 45944574Sphk } 46044574Sphk break; 46144574Sphk 46244574Sphk /* 46344574Sphk * Insert second in progress. 46444574Sphk */ 46544574Sphk case TIME_OOP: 46644574Sphk time_state = TIME_WAIT; 46744574Sphk break; 46844574Sphk 46944574Sphk /* 47044574Sphk * Wait for status bits to clear. 47144574Sphk */ 47244574Sphk case TIME_WAIT: 47344574Sphk if (!(time_status & (STA_INS | STA_DEL))) 47444574Sphk time_state = TIME_OK; 4752858Swollman } 47644574Sphk 47744574Sphk /* 47850656Sphk * Compute the total time adjustment for the next second 47950656Sphk * in ns. The offset is reduced by a factor depending on 48050656Sphk * whether the PPS signal is operating. Note that the 48150656Sphk * value is in effect scaled by the clock frequency, 48250656Sphk * since the adjustment is added at each tick interrupt. 48344574Sphk */ 48444574Sphk#ifdef PPS_SYNC 48555413Sphk /* XXX even if signal dies we should finish adjustment ? */ 48655219Sphk if (time_status & STA_PPSTIME && time_status & STA_PPSSIGNAL) { 48755413Sphk time_adj = pps_offset; 48855219Sphk L_RSHIFT(time_adj, pps_shift); 48955413Sphk L_SUB(pps_offset, time_adj); 49055219Sphk } else { 49155413Sphk time_adj = time_offset; 49255219Sphk L_RSHIFT(time_adj, SHIFT_PLL + time_constant); 49355219Sphk L_SUB(time_offset, time_adj); 49455219Sphk } 49544574Sphk#else 49655413Sphk time_adj = time_offset; 49755219Sphk L_RSHIFT(time_adj, SHIFT_PLL + time_constant); 49855219Sphk L_SUB(time_offset, time_adj); 49944574Sphk#endif /* PPS_SYNC */ 50044574Sphk L_ADD(time_adj, time_freq); 50144574Sphk tcp->tc_adjustment = time_adj; 50244574Sphk#ifdef PPS_SYNC 50344574Sphk if (pps_valid > 0) 50444574Sphk pps_valid--; 50544574Sphk else 50644574Sphk time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER | 50744574Sphk STA_PPSWANDER | STA_PPSERROR); 50844574Sphk#endif /* PPS_SYNC */ 5092858Swollman} 5102858Swollman 51144574Sphk/* 51244574Sphk * ntp_init() - initialize variables and structures 51344574Sphk * 51444574Sphk * This routine must be called after the kernel variables hz and tick 51544574Sphk * are set or changed and before the next tick interrupt. In this 51644574Sphk * particular implementation, these values are assumed set elsewhere in 51744574Sphk * the kernel. The design allows the clock frequency and tick interval 51844574Sphk * to be changed while the system is running. So, this routine should 51944574Sphk * probably be integrated with the code that does that. 52044574Sphk */ 52144574Sphkstatic void 52244574Sphkntp_init() 52344574Sphk{ 52444574Sphk 52544574Sphk /* 52644574Sphk * The following variable must be initialized any time the 52744574Sphk * kernel variable hz is changed. 52844574Sphk */ 52944574Sphk time_tick = NANOSECOND / hz; 53044574Sphk 53144574Sphk /* 53244574Sphk * The following variables are initialized only at startup. Only 53344574Sphk * those structures not cleared by the compiler need to be 53444574Sphk * initialized, and these only in the simulator. In the actual 53544574Sphk * kernel, any nonzero values here will quickly evaporate. 53644574Sphk */ 53744574Sphk L_CLR(time_offset); 53844574Sphk L_CLR(time_freq); 53932513Sphk#ifdef PPS_SYNC 54050656Sphk pps_tf[0].tv_sec = pps_tf[0].tv_nsec = 0; 54150656Sphk pps_tf[1].tv_sec = pps_tf[1].tv_nsec = 0; 54250656Sphk pps_tf[2].tv_sec = pps_tf[2].tv_nsec = 0; 54344794Sphk pps_fcount = 0; 54444574Sphk L_CLR(pps_freq); 54544574Sphk#endif /* PPS_SYNC */ 54644574Sphk} 5472858Swollman 54844574SphkSYSINIT(ntpclocks, SI_SUB_CLOCKS, SI_ORDER_FIRST, ntp_init, NULL) 54932513Sphk 55044574Sphk/* 55144574Sphk * hardupdate() - local clock update 55244574Sphk * 55344574Sphk * This routine is called by ntp_adjtime() to update the local clock 55444574Sphk * phase and frequency. The implementation is of an adaptive-parameter, 55544574Sphk * hybrid phase/frequency-lock loop (PLL/FLL). The routine computes new 55644574Sphk * time and frequency offset estimates for each call. If the kernel PPS 55744574Sphk * discipline code is configured (PPS_SYNC), the PPS signal itself 55844574Sphk * determines the new time offset, instead of the calling argument. 55944574Sphk * Presumably, calls to ntp_adjtime() occur only when the caller 56044574Sphk * believes the local clock is valid within some bound (+-128 ms with 56144574Sphk * NTP). If the caller's time is far different than the PPS time, an 56244574Sphk * argument will ensue, and it's not clear who will lose. 56344574Sphk * 56444574Sphk * For uncompensated quartz crystal oscillators and nominal update 56544574Sphk * intervals less than 256 s, operation should be in phase-lock mode, 56644574Sphk * where the loop is disciplined to phase. For update intervals greater 56744574Sphk * than 1024 s, operation should be in frequency-lock mode, where the 56844574Sphk * loop is disciplined to frequency. Between 256 s and 1024 s, the mode 56944574Sphk * is selected by the STA_MODE status bit. 57044574Sphk */ 57144574Sphkstatic void 57244574Sphkhardupdate(offset) 57344574Sphk long offset; /* clock offset (ns) */ 57444574Sphk{ 57544574Sphk long ltemp, mtemp; 57644574Sphk l_fp ftemp; 57732513Sphk 57844574Sphk /* 57944574Sphk * Select how the phase is to be controlled and from which 58044574Sphk * source. If the PPS signal is present and enabled to 58144574Sphk * discipline the time, the PPS offset is used; otherwise, the 58244574Sphk * argument offset is used. 58344574Sphk */ 58450656Sphk if (!(time_status & STA_PLL)) 58550656Sphk return; 58644574Sphk ltemp = offset; 58744574Sphk if (ltemp > MAXPHASE) 58844574Sphk ltemp = MAXPHASE; 58944574Sphk else if (ltemp < -MAXPHASE) 59044574Sphk ltemp = -MAXPHASE; 59144574Sphk if (!(time_status & STA_PPSTIME && time_status & STA_PPSSIGNAL)) 59244574Sphk L_LINT(time_offset, ltemp); 59332513Sphk 59444574Sphk /* 59544574Sphk * Select how the frequency is to be controlled and in which 59644574Sphk * mode (PLL or FLL). If the PPS signal is present and enabled 59744574Sphk * to discipline the frequency, the PPS frequency is used; 59844574Sphk * otherwise, the argument offset is used to compute it. 59944574Sphk */ 60044574Sphk if (time_status & STA_PPSFREQ && time_status & STA_PPSSIGNAL) { 60144574Sphk time_reftime = time_second; 60244574Sphk return; 60344574Sphk } 60444574Sphk if (time_status & STA_FREQHOLD || time_reftime == 0) 60544574Sphk time_reftime = time_second; 60644574Sphk mtemp = time_second - time_reftime; 60750656Sphk L_LINT(ftemp, ltemp); 60850656Sphk L_RSHIFT(ftemp, (SHIFT_PLL + 2 + time_constant) << 1); 60950656Sphk L_MPY(ftemp, mtemp); 61050656Sphk L_ADD(time_freq, ftemp); 61150656Sphk time_status &= ~STA_MODE; 61250656Sphk if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) { 61344574Sphk L_LINT(ftemp, (ltemp << 4) / mtemp); 61444574Sphk L_RSHIFT(ftemp, SHIFT_FLL + 4); 61544574Sphk L_ADD(time_freq, ftemp); 61644574Sphk time_status |= STA_MODE; 61744574Sphk } 61844574Sphk time_reftime = time_second; 61944574Sphk if (L_GINT(time_freq) > MAXFREQ) 62044574Sphk L_LINT(time_freq, MAXFREQ); 62144574Sphk else if (L_GINT(time_freq) < -MAXFREQ) 62244574Sphk L_LINT(time_freq, -MAXFREQ); 62344574Sphk} 62444574Sphk 62544574Sphk#ifdef PPS_SYNC 62632513Sphk/* 62732513Sphk * hardpps() - discipline CPU clock oscillator to external PPS signal 62832513Sphk * 62932513Sphk * This routine is called at each PPS interrupt in order to discipline 63032513Sphk * the CPU clock oscillator to the PPS signal. It measures the PPS phase 63132513Sphk * and leaves it in a handy spot for the hardclock() routine. It 63232513Sphk * integrates successive PPS phase differences and calculates the 63332513Sphk * frequency offset. This is used in hardclock() to discipline the CPU 63444574Sphk * clock oscillator so that the intrinsic frequency error is cancelled 63544574Sphk * out. The code requires the caller to capture the time and 63644574Sphk * architecture-dependent hardware counter values in nanoseconds at the 63744574Sphk * on-time PPS signal transition. 63832513Sphk * 63944574Sphk * Note that, on some Unix systems this routine runs at an interrupt 64032513Sphk * priority level higher than the timer interrupt routine hardclock(). 64132513Sphk * Therefore, the variables used are distinct from the hardclock() 64244574Sphk * variables, except for the actual time and frequency variables, which 64344574Sphk * are determined by this routine and updated atomically. 64432513Sphk */ 64532513Sphkvoid 64644574Sphkhardpps(tsp, nsec) 64744574Sphk struct timespec *tsp; /* time at PPS */ 64844574Sphk long nsec; /* hardware counter at PPS */ 64932513Sphk{ 65044574Sphk long u_sec, u_nsec, v_nsec; /* temps */ 65144574Sphk l_fp ftemp; 65232513Sphk 65332513Sphk /* 65444574Sphk * The signal is first processed by a frequency discriminator 65544574Sphk * which rejects noise and input signals with frequencies 65644574Sphk * outside the range 1 +-MAXFREQ PPS. If two hits occur in the 65744574Sphk * same second, we ignore the later hit; if not and a hit occurs 65844574Sphk * outside the range gate, keep the later hit but do not 65944574Sphk * process it. 66032513Sphk */ 66144574Sphk time_status |= STA_PPSSIGNAL | STA_PPSJITTER; 66244574Sphk time_status &= ~(STA_PPSWANDER | STA_PPSERROR); 66344574Sphk pps_valid = PPS_VALID; 66444574Sphk u_sec = tsp->tv_sec; 66544574Sphk u_nsec = tsp->tv_nsec; 66644574Sphk if (u_nsec >= (NANOSECOND >> 1)) { 66744574Sphk u_nsec -= NANOSECOND; 66844574Sphk u_sec++; 66944574Sphk } 67050656Sphk v_nsec = u_nsec - pps_tf[0].tv_nsec; 67150656Sphk if (u_sec == pps_tf[0].tv_sec && v_nsec < -MAXFREQ) { 67244574Sphk return; 67344574Sphk } 67444574Sphk pps_tf[2] = pps_tf[1]; 67544574Sphk pps_tf[1] = pps_tf[0]; 67650656Sphk pps_tf[0].tv_sec = u_sec; 67750656Sphk pps_tf[0].tv_nsec = u_nsec; 67832513Sphk 67932513Sphk /* 68044574Sphk * Compute the difference between the current and previous 68144574Sphk * counter values. If the difference exceeds 0.5 s, assume it 68244574Sphk * has wrapped around, so correct 1.0 s. If the result exceeds 68344574Sphk * the tick interval, the sample point has crossed a tick 68444574Sphk * boundary during the last second, so correct the tick. Very 68544574Sphk * intricate. 68644574Sphk */ 68744666Sphk u_nsec = nsec; 68844574Sphk if (u_nsec > (NANOSECOND >> 1)) 68944574Sphk u_nsec -= NANOSECOND; 69044574Sphk else if (u_nsec < -(NANOSECOND >> 1)) 69144574Sphk u_nsec += NANOSECOND; 69244794Sphk pps_fcount += u_nsec; 69350656Sphk if (v_nsec > MAXFREQ || v_nsec < -MAXFREQ) { 69444574Sphk return; 69544574Sphk } 69644574Sphk time_status &= ~STA_PPSJITTER; 69744574Sphk 69844574Sphk /* 69944574Sphk * A three-stage median filter is used to help denoise the PPS 70032513Sphk * time. The median sample becomes the time offset estimate; the 70132513Sphk * difference between the other two samples becomes the time 70232513Sphk * dispersion (jitter) estimate. 70332513Sphk */ 70450656Sphk if (pps_tf[0].tv_nsec > pps_tf[1].tv_nsec) { 70550656Sphk if (pps_tf[1].tv_nsec > pps_tf[2].tv_nsec) { 70650656Sphk v_nsec = pps_tf[1].tv_nsec; /* 0 1 2 */ 70750656Sphk u_nsec = pps_tf[0].tv_nsec - pps_tf[2].tv_nsec; 70850656Sphk } else if (pps_tf[2].tv_nsec > pps_tf[0].tv_nsec) { 70950656Sphk v_nsec = pps_tf[0].tv_nsec; /* 2 0 1 */ 71050656Sphk u_nsec = pps_tf[2].tv_nsec - pps_tf[1].tv_nsec; 71144574Sphk } else { 71250656Sphk v_nsec = pps_tf[2].tv_nsec; /* 0 2 1 */ 71350656Sphk u_nsec = pps_tf[0].tv_nsec - pps_tf[1].tv_nsec; 71444574Sphk } 71544574Sphk } else { 71650656Sphk if (pps_tf[1].tv_nsec < pps_tf[2].tv_nsec) { 71750656Sphk v_nsec = pps_tf[1].tv_nsec; /* 2 1 0 */ 71850656Sphk u_nsec = pps_tf[2].tv_nsec - pps_tf[0].tv_nsec; 71950656Sphk } else if (pps_tf[2].tv_nsec < pps_tf[0].tv_nsec) { 72050656Sphk v_nsec = pps_tf[0].tv_nsec; /* 1 0 2 */ 72150656Sphk u_nsec = pps_tf[1].tv_nsec - pps_tf[2].tv_nsec; 72244574Sphk } else { 72350656Sphk v_nsec = pps_tf[2].tv_nsec; /* 1 2 0 */ 72450656Sphk u_nsec = pps_tf[1].tv_nsec - pps_tf[0].tv_nsec; 72544574Sphk } 72644574Sphk } 72732513Sphk 72832513Sphk /* 72944574Sphk * Nominal jitter is due to PPS signal noise and interrupt 73050656Sphk * latency. If it exceeds the popcorn threshold, 73150656Sphk * the sample is discarded. otherwise, if so enabled, the time 73250656Sphk * offset is updated. We can tolerate a modest loss of data here 73350656Sphk * without degrading time accuracy. 73432513Sphk */ 73550656Sphk if (u_nsec > (pps_jitter << PPS_POPCORN)) { 73644574Sphk time_status |= STA_PPSJITTER; 73744574Sphk pps_jitcnt++; 73844574Sphk } else if (time_status & STA_PPSTIME) { 73955219Sphk L_LINT(time_offset, -v_nsec); 74055413Sphk L_LINT(pps_offset, -v_nsec); 74132513Sphk } 74244574Sphk pps_jitter += (u_nsec - pps_jitter) >> PPS_FAVG; 74350656Sphk u_sec = pps_tf[0].tv_sec - pps_lastsec; 74444574Sphk if (u_sec < (1 << pps_shift)) 74544574Sphk return; 74644574Sphk 74732513Sphk /* 74844574Sphk * At the end of the calibration interval the difference between 74944574Sphk * the first and last counter values becomes the scaled 75044574Sphk * frequency. It will later be divided by the length of the 75144574Sphk * interval to determine the frequency update. If the frequency 75244574Sphk * exceeds a sanity threshold, or if the actual calibration 75344574Sphk * interval is not equal to the expected length, the data are 75444574Sphk * discarded. We can tolerate a modest loss of data here without 75544574Sphk * degrading frequency ccuracy. 75632513Sphk */ 75744574Sphk pps_calcnt++; 75844794Sphk v_nsec = -pps_fcount; 75950656Sphk pps_lastsec = pps_tf[0].tv_sec; 76044794Sphk pps_fcount = 0; 76144574Sphk u_nsec = MAXFREQ << pps_shift; 76244574Sphk if (v_nsec > u_nsec || v_nsec < -u_nsec || u_sec != (1 << 76344574Sphk pps_shift)) { 76444574Sphk time_status |= STA_PPSERROR; 76532513Sphk pps_errcnt++; 76632513Sphk return; 76732513Sphk } 76832513Sphk 76932513Sphk /* 77050656Sphk * Here the raw frequency offset and wander (stability) is 77150656Sphk * calculated. If the wander is less than the wander threshold 77250656Sphk * for four consecutive averaging intervals, the interval is 77350656Sphk * doubled; if it is greater than the threshold for four 77450656Sphk * consecutive intervals, the interval is halved. The scaled 77550656Sphk * frequency offset is converted to frequency offset. The 77650656Sphk * stability metric is calculated as the average of recent 77750656Sphk * frequency changes, but is used only for performance 77844574Sphk * monitoring. 77932513Sphk */ 78044574Sphk L_LINT(ftemp, v_nsec); 78144574Sphk L_RSHIFT(ftemp, pps_shift); 78244574Sphk L_SUB(ftemp, pps_freq); 78344574Sphk u_nsec = L_GINT(ftemp); 78450656Sphk if (u_nsec > PPS_MAXWANDER) { 78550656Sphk L_LINT(ftemp, PPS_MAXWANDER); 78644574Sphk pps_intcnt--; 78744574Sphk time_status |= STA_PPSWANDER; 78832513Sphk pps_stbcnt++; 78950656Sphk } else if (u_nsec < -PPS_MAXWANDER) { 79050656Sphk L_LINT(ftemp, -PPS_MAXWANDER); 79144574Sphk pps_intcnt--; 79232513Sphk time_status |= STA_PPSWANDER; 79344574Sphk pps_stbcnt++; 79444574Sphk } else { 79544574Sphk pps_intcnt++; 79632513Sphk } 79755219Sphk if (pps_shift > pps_shiftmax) { 79855219Sphk /* If we lowered pps_shiftmax */ 79955219Sphk pps_shift = pps_shiftmax; 80055219Sphk pps_intcnt = 0; 80155219Sphk } else if (pps_intcnt >= 4) { 80244574Sphk pps_intcnt = 4; 80350656Sphk if (pps_shift < pps_shiftmax) { 80444574Sphk pps_shift++; 80544574Sphk pps_intcnt = 0; 80632513Sphk } 80744574Sphk } else if (pps_intcnt <= -4) { 80844574Sphk pps_intcnt = -4; 80944574Sphk if (pps_shift > PPS_FAVG) { 81044574Sphk pps_shift--; 81144574Sphk pps_intcnt = 0; 81244574Sphk } 81332513Sphk } 81444574Sphk if (u_nsec < 0) 81544574Sphk u_nsec = -u_nsec; 81644574Sphk pps_stabil += (u_nsec * SCALE_PPM - pps_stabil) >> PPS_FAVG; 81732513Sphk 81832513Sphk /* 81950656Sphk * The PPS frequency is recalculated and clamped to the maximum 82050656Sphk * MAXFREQ. If enabled, the system clock frequency is updated as 82150656Sphk * well. 82232513Sphk */ 82344574Sphk L_ADD(pps_freq, ftemp); 82444574Sphk u_nsec = L_GINT(pps_freq); 82544574Sphk if (u_nsec > MAXFREQ) 82644574Sphk L_LINT(pps_freq, MAXFREQ); 82744574Sphk else if (u_nsec < -MAXFREQ) 82844574Sphk L_LINT(pps_freq, -MAXFREQ); 82944574Sphk if (time_status & STA_PPSFREQ) 83044574Sphk time_freq = pps_freq; 83132513Sphk} 83232513Sphk#endif /* PPS_SYNC */ 833