kern_ntptime.c revision 62573
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 62573 2000-07-04 11:25:35Z 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> 4358377Sphk#include <sys/timetc.h> 4436941Sphk#include <sys/timepps.h> 452858Swollman#include <sys/sysctl.h> 462858Swollman 472858Swollman/* 4844574Sphk * Single-precision macros for 64-bit machines 4944574Sphk */ 5044574Sphktypedef long long l_fp; 5144574Sphk#define L_ADD(v, u) ((v) += (u)) 5244574Sphk#define L_SUB(v, u) ((v) -= (u)) 5344574Sphk#define L_ADDHI(v, a) ((v) += (long long)(a) << 32) 5444574Sphk#define L_NEG(v) ((v) = -(v)) 5544574Sphk#define L_RSHIFT(v, n) \ 5644574Sphk do { \ 5744574Sphk if ((v) < 0) \ 5844574Sphk (v) = -(-(v) >> (n)); \ 5944574Sphk else \ 6044574Sphk (v) = (v) >> (n); \ 6144574Sphk } while (0) 6244574Sphk#define L_MPY(v, a) ((v) *= (a)) 6344574Sphk#define L_CLR(v) ((v) = 0) 6444574Sphk#define L_ISNEG(v) ((v) < 0) 6544574Sphk#define L_LINT(v, a) ((v) = (long long)(a) << 32) 6644574Sphk#define L_GINT(v) ((v) < 0 ? -(-(v) >> 32) : (v) >> 32) 6744574Sphk 6844574Sphk/* 6944574Sphk * Generic NTP kernel interface 7032513Sphk * 7144574Sphk * These routines constitute the Network Time Protocol (NTP) interfaces 7244574Sphk * for user and daemon application programs. The ntp_gettime() routine 7344574Sphk * provides the time, maximum error (synch distance) and estimated error 7444574Sphk * (dispersion) to client user application programs. The ntp_adjtime() 7544574Sphk * routine is used by the NTP daemon to adjust the system clock to an 7644574Sphk * externally derived time. The time offset and related variables set by 7744574Sphk * this routine are used by other routines in this module to adjust the 7844574Sphk * phase and frequency of the clock discipline loop which controls the 7944574Sphk * system clock. 8032513Sphk * 8145294Sphk * When the kernel time is reckoned directly in nanoseconds (NTP_NANO 8244574Sphk * defined), the time at each tick interrupt is derived directly from 8344574Sphk * the kernel time variable. When the kernel time is reckoned in 8445294Sphk * microseconds, (NTP_NANO undefined), the time is derived from the 8545294Sphk * kernel time variable together with a variable representing the 8645294Sphk * leftover nanoseconds at the last tick interrupt. In either case, the 8745294Sphk * current nanosecond time is reckoned from these values plus an 8845294Sphk * interpolated value derived by the clock routines in another 8945294Sphk * architecture-specific module. The interpolation can use either a 9045294Sphk * dedicated counter or a processor cycle counter (PCC) implemented in 9145294Sphk * some architectures. 9232513Sphk * 9344574Sphk * Note that all routines must run at priority splclock or higher. 9444574Sphk */ 9544574Sphk 9644574Sphk/* 9744574Sphk * Phase/frequency-lock loop (PLL/FLL) definitions 9832513Sphk * 9944574Sphk * The nanosecond clock discipline uses two variable types, time 10044574Sphk * variables and frequency variables. Both types are represented as 64- 10144574Sphk * bit fixed-point quantities with the decimal point between two 32-bit 10244574Sphk * halves. On a 32-bit machine, each half is represented as a single 10344574Sphk * word and mathematical operations are done using multiple-precision 10444574Sphk * arithmetic. On a 64-bit machine, ordinary computer arithmetic is 10544574Sphk * used. 10632513Sphk * 10744574Sphk * A time variable is a signed 64-bit fixed-point number in ns and 10844574Sphk * fraction. It represents the remaining time offset to be amortized 10944574Sphk * over succeeding tick interrupts. The maximum time offset is about 11045294Sphk * 0.5 s and the resolution is about 2.3e-10 ns. 11132513Sphk * 11244574Sphk * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 11344574Sphk * 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 11444574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 11544574Sphk * |s s s| ns | 11644574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 11744574Sphk * | fraction | 11844574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 11932513Sphk * 12044574Sphk * A frequency variable is a signed 64-bit fixed-point number in ns/s 12144574Sphk * and fraction. It represents the ns and fraction to be added to the 12244574Sphk * kernel time variable at each second. The maximum frequency offset is 12345294Sphk * about +-500000 ns/s and the resolution is about 2.3e-10 ns/s. 12432513Sphk * 12544574Sphk * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 12644574Sphk * 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 12744574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 12844574Sphk * |s s s s s s s s s s s s s| ns/s | 12944574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 13044574Sphk * | fraction | 13144574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1322858Swollman */ 13332513Sphk/* 13432513Sphk * The following variables establish the state of the PLL/FLL and the 13544574Sphk * residual time and frequency offset of the local clock. 13632513Sphk */ 13744574Sphk#define SHIFT_PLL 4 /* PLL loop gain (shift) */ 13844574Sphk#define SHIFT_FLL 2 /* FLL loop gain (shift) */ 13932513Sphk 14044574Sphkstatic int time_state = TIME_OK; /* clock state */ 14144574Sphkstatic int time_status = STA_UNSYNC; /* clock status bits */ 14244574Sphkstatic long time_constant; /* poll interval (shift) (s) */ 14344574Sphkstatic long time_precision = 1; /* clock precision (ns) */ 14444574Sphkstatic long time_maxerror = MAXPHASE / 1000; /* maximum error (us) */ 14544574Sphkstatic long time_esterror = MAXPHASE / 1000; /* estimated error (us) */ 14644574Sphkstatic long time_reftime; /* time at last adjustment (s) */ 14744574Sphkstatic long time_tick; /* nanoseconds per tick (ns) */ 14844574Sphkstatic l_fp time_offset; /* time offset (ns) */ 14944574Sphkstatic l_fp time_freq; /* frequency offset (ns/s) */ 15056458Sphkstatic l_fp time_adj; /* resulting adjustment */ 15144574Sphk 1522858Swollman#ifdef PPS_SYNC 1532858Swollman/* 15444574Sphk * The following variables are used when a pulse-per-second (PPS) signal 15544574Sphk * is available and connected via a modem control lead. They establish 15644574Sphk * the engineering parameters of the clock discipline loop when 15744574Sphk * controlled by the PPS signal. 1582858Swollman */ 15944574Sphk#define PPS_FAVG 2 /* min freq avg interval (s) (shift) */ 16050656Sphk#define PPS_FAVGDEF 7 /* default freq avg int (s) (shift) */ 16150656Sphk#define PPS_FAVGMAX 15 /* max freq avg interval (s) (shift) */ 16244574Sphk#define PPS_PAVG 4 /* phase avg interval (s) (shift) */ 16344574Sphk#define PPS_VALID 120 /* PPS signal watchdog max (s) */ 16450656Sphk#define PPS_MAXWANDER 100000 /* max PPS wander (ns/s) */ 16550656Sphk#define PPS_POPCORN 2 /* popcorn spike threshold (shift) */ 16632513Sphk 16750656Sphkstatic struct timespec pps_tf[3]; /* phase median filter */ 16855413Sphkstatic l_fp pps_offset; /* time offset (ns) */ 16944574Sphkstatic l_fp pps_freq; /* scaled frequency offset (ns/s) */ 17045294Sphkstatic long pps_fcount; /* frequency accumulator */ 17150656Sphkstatic long pps_jitter; /* nominal jitter (ns) */ 17250656Sphkstatic long pps_stabil; /* nominal stability (scaled ns/s) */ 17344574Sphkstatic long pps_lastsec; /* time at last calibration (s) */ 17444574Sphkstatic int pps_valid; /* signal watchdog counter */ 17544574Sphkstatic int pps_shift = PPS_FAVG; /* interval duration (s) (shift) */ 17650656Sphkstatic int pps_shiftmax = PPS_FAVGDEF; /* max interval duration (s) (shift) */ 17744574Sphkstatic int pps_intcnt; /* wander counter */ 17856458Sphkstatic int pps_letgo; /* PLL frequency hold-off */ 17944574Sphk 18032513Sphk/* 18132513Sphk * PPS signal quality monitors 18232513Sphk */ 18344574Sphkstatic long pps_calcnt; /* calibration intervals */ 18444574Sphkstatic long pps_jitcnt; /* jitter limit exceeded */ 18544574Sphkstatic long pps_stbcnt; /* stability limit exceeded */ 18644574Sphkstatic long pps_errcnt; /* calibration errors */ 1872858Swollman#endif /* PPS_SYNC */ 18832513Sphk/* 18944574Sphk * End of phase/frequency-lock loop (PLL/FLL) definitions 19032513Sphk */ 19132513Sphk 19244574Sphkstatic void ntp_init(void); 19344574Sphkstatic void hardupdate(long offset); 19432513Sphk 19533690Sphk/* 19644574Sphk * ntp_gettime() - NTP user application interface 19733690Sphk * 19844574Sphk * See the timex.h header file for synopsis and API description. 19933690Sphk */ 20012279Sphkstatic int 20162573Sphkntp_sysctl(SYSCTL_HANDLER_ARGS) 2022858Swollman{ 20344574Sphk struct ntptimeval ntv; /* temporary structure */ 20444574Sphk struct timespec atv; /* nanosecond time */ 2052858Swollman 20644574Sphk nanotime(&atv); 20744574Sphk ntv.time.tv_sec = atv.tv_sec; 20844574Sphk ntv.time.tv_nsec = atv.tv_nsec; 2092858Swollman ntv.maxerror = time_maxerror; 2102858Swollman ntv.esterror = time_esterror; 2112858Swollman ntv.time_state = time_state; 2122858Swollman 2132858Swollman /* 21444574Sphk * Status word error decode. If any of these conditions occur, 21544574Sphk * an error is returned, instead of the status word. Most 21644574Sphk * applications will care only about the fact the system clock 21744574Sphk * may not be trusted, not about the details. 2182858Swollman * 2192858Swollman * Hardware or software error 2202858Swollman */ 22144574Sphk if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) || 2222858Swollman 2232858Swollman /* 22444574Sphk * PPS signal lost when either time or frequency synchronization 22544574Sphk * requested 2262858Swollman */ 22744574Sphk (time_status & (STA_PPSFREQ | STA_PPSTIME) && 22844574Sphk !(time_status & STA_PPSSIGNAL)) || 2292858Swollman 2302858Swollman /* 23144574Sphk * PPS jitter exceeded when time synchronization requested 2322858Swollman */ 23344574Sphk (time_status & STA_PPSTIME && 23444574Sphk time_status & STA_PPSJITTER) || 2352858Swollman 2362858Swollman /* 23744574Sphk * PPS wander exceeded or calibration error when frequency 23844574Sphk * synchronization requested 2392858Swollman */ 24044574Sphk (time_status & STA_PPSFREQ && 24144574Sphk time_status & (STA_PPSWANDER | STA_PPSERROR))) 2422858Swollman ntv.time_state = TIME_ERROR; 24312279Sphk return (sysctl_handle_opaque(oidp, &ntv, sizeof ntv, req)); 2442858Swollman} 2452858Swollman 24644574SphkSYSCTL_NODE(_kern, OID_AUTO, ntp_pll, CTLFLAG_RW, 0, ""); 24744574SphkSYSCTL_PROC(_kern_ntp_pll, OID_AUTO, gettime, CTLTYPE_OPAQUE|CTLFLAG_RD, 24812623Sphk 0, sizeof(struct ntptimeval) , ntp_sysctl, "S,ntptimeval", ""); 24912279Sphk 25050663Sphk#ifdef PPS_SYNC 25150656SphkSYSCTL_INT(_kern_ntp_pll, OID_AUTO, pps_shiftmax, CTLFLAG_RW, &pps_shiftmax, 0, ""); 25255413SphkSYSCTL_INT(_kern_ntp_pll, OID_AUTO, pps_shift, CTLFLAG_RW, &pps_shift, 0, ""); 25356458Sphk 25456458SphkSYSCTL_OPAQUE(_kern_ntp_pll, OID_AUTO, pps_freq, CTLFLAG_RD, &pps_freq, sizeof(pps_freq), "I", ""); 25556458SphkSYSCTL_OPAQUE(_kern_ntp_pll, OID_AUTO, time_freq, CTLFLAG_RD, &time_freq, sizeof(time_freq), "I", ""); 25656458SphkSYSCTL_OPAQUE(_kern_ntp_pll, OID_AUTO, pps_offset, CTLFLAG_RD, &pps_offset, sizeof(pps_offset), "I", ""); 25750663Sphk#endif 2582858Swollman/* 2592858Swollman * ntp_adjtime() - NTP daemon application interface 26044574Sphk * 26144574Sphk * See the timex.h header file for synopsis and API description. 2622858Swollman */ 26312221Sbde#ifndef _SYS_SYSPROTO_H_ 2642858Swollmanstruct ntp_adjtime_args { 26544574Sphk struct timex *tp; 2662858Swollman}; 26712221Sbde#endif 2682858Swollman 2692858Swollmanint 27030994Sphkntp_adjtime(struct proc *p, struct ntp_adjtime_args *uap) 2712858Swollman{ 27244574Sphk struct timex ntv; /* temporary structure */ 27345294Sphk long freq; /* frequency ns/s) */ 27444574Sphk int modes; /* mode bits from structure */ 27544574Sphk int s; /* caller priority */ 2762858Swollman int error; 2772858Swollman 2782858Swollman error = copyin((caddr_t)uap->tp, (caddr_t)&ntv, sizeof(ntv)); 2792858Swollman if (error) 28044574Sphk return(error); 2812858Swollman 2822858Swollman /* 2832858Swollman * Update selected clock variables - only the superuser can 2842858Swollman * change anything. Note that there is no error checking here on 2852858Swollman * the assumption the superuser should know what it is doing. 2862858Swollman */ 2872858Swollman modes = ntv.modes; 28844776Sphk if (modes) 28946112Sphk error = suser(p); 29044574Sphk if (error) 29144574Sphk return (error); 2922858Swollman s = splclock(); 29344574Sphk if (modes & MOD_FREQUENCY) { 29445302Sphk freq = (ntv.freq * 1000LL) >> 16; 29545294Sphk if (freq > MAXFREQ) 29645294Sphk L_LINT(time_freq, MAXFREQ); 29745294Sphk else if (freq < -MAXFREQ) 29845294Sphk L_LINT(time_freq, -MAXFREQ); 29945294Sphk else 30045294Sphk L_LINT(time_freq, freq); 30145294Sphk 3022858Swollman#ifdef PPS_SYNC 30344574Sphk pps_freq = time_freq; 3042858Swollman#endif /* PPS_SYNC */ 30544574Sphk } 3062858Swollman if (modes & MOD_MAXERROR) 3072858Swollman time_maxerror = ntv.maxerror; 3082858Swollman if (modes & MOD_ESTERROR) 3092858Swollman time_esterror = ntv.esterror; 3102858Swollman if (modes & MOD_STATUS) { 3112858Swollman time_status &= STA_RONLY; 3122858Swollman time_status |= ntv.status & ~STA_RONLY; 3132858Swollman } 31445294Sphk if (modes & MOD_TIMECONST) { 31545294Sphk if (ntv.constant < 0) 31645294Sphk time_constant = 0; 31745294Sphk else if (ntv.constant > MAXTC) 31845294Sphk time_constant = MAXTC; 31945294Sphk else 32045294Sphk time_constant = ntv.constant; 32145294Sphk } 32250656Sphk#ifdef PPS_SYNC 32350656Sphk if (modes & MOD_PPSMAX) { 32450656Sphk if (ntv.shift < PPS_FAVG) 32550656Sphk pps_shiftmax = PPS_FAVG; 32650656Sphk else if (ntv.shift > PPS_FAVGMAX) 32750656Sphk pps_shiftmax = PPS_FAVGMAX; 32850656Sphk else 32950656Sphk pps_shiftmax = ntv.shift; 33050656Sphk } 33150656Sphk#endif /* PPS_SYNC */ 33244574Sphk if (modes & MOD_NANO) 33344574Sphk time_status |= STA_NANO; 33444574Sphk if (modes & MOD_MICRO) 33544574Sphk time_status &= ~STA_NANO; 33644574Sphk if (modes & MOD_CLKB) 33744574Sphk time_status |= STA_CLK; 33844574Sphk if (modes & MOD_CLKA) 33944574Sphk time_status &= ~STA_CLK; 34044574Sphk if (modes & MOD_OFFSET) { 34144574Sphk if (time_status & STA_NANO) 34244574Sphk hardupdate(ntv.offset); 34344574Sphk else 34444574Sphk hardupdate(ntv.offset * 1000); 34544574Sphk } 3462858Swollman 3472858Swollman /* 3482858Swollman * Retrieve all clock variables 3492858Swollman */ 35044574Sphk if (time_status & STA_NANO) 35144574Sphk ntv.offset = L_GINT(time_offset); 3522858Swollman else 35344574Sphk ntv.offset = L_GINT(time_offset) / 1000; 35445295Sphk ntv.freq = L_GINT((time_freq / 1000LL) << 16); 3552858Swollman ntv.maxerror = time_maxerror; 3562858Swollman ntv.esterror = time_esterror; 3572858Swollman ntv.status = time_status; 35845294Sphk ntv.constant = time_constant; 35944574Sphk if (time_status & STA_NANO) 36044574Sphk ntv.precision = time_precision; 36144574Sphk else 36244574Sphk ntv.precision = time_precision / 1000; 36344574Sphk ntv.tolerance = MAXFREQ * SCALE_PPM; 3642858Swollman#ifdef PPS_SYNC 3652858Swollman ntv.shift = pps_shift; 36645295Sphk ntv.ppsfreq = L_GINT((pps_freq / 1000LL) << 16); 36744574Sphk if (time_status & STA_NANO) 36844574Sphk ntv.jitter = pps_jitter; 36944574Sphk else 37044574Sphk ntv.jitter = pps_jitter / 1000; 3712858Swollman ntv.stabil = pps_stabil; 3722858Swollman ntv.calcnt = pps_calcnt; 3732858Swollman ntv.errcnt = pps_errcnt; 3742858Swollman ntv.jitcnt = pps_jitcnt; 3752858Swollman ntv.stbcnt = pps_stbcnt; 3762858Swollman#endif /* PPS_SYNC */ 37744574Sphk splx(s); 3782858Swollman 3792858Swollman error = copyout((caddr_t)&ntv, (caddr_t)uap->tp, sizeof(ntv)); 38044574Sphk if (error) 38144574Sphk return (error); 38244574Sphk 38344574Sphk /* 38444574Sphk * Status word error decode. See comments in 38544574Sphk * ntp_gettime() routine. 38644574Sphk */ 38744574Sphk if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) || 38844574Sphk (time_status & (STA_PPSFREQ | STA_PPSTIME) && 38944574Sphk !(time_status & STA_PPSSIGNAL)) || 39044574Sphk (time_status & STA_PPSTIME && 39144574Sphk time_status & STA_PPSJITTER) || 39244574Sphk (time_status & STA_PPSFREQ && 39344574Sphk time_status & (STA_PPSWANDER | STA_PPSERROR))) 39445302Sphk p->p_retval[0] = TIME_ERROR; 39545302Sphk else 39645302Sphk p->p_retval[0] = time_state; 39745302Sphk return (error); 39844574Sphk} 39944574Sphk 40044574Sphk/* 40144574Sphk * second_overflow() - called after ntp_tick_adjust() 40244574Sphk * 40344574Sphk * This routine is ordinarily called immediately following the above 40444574Sphk * routine ntp_tick_adjust(). While these two routines are normally 40544574Sphk * combined, they are separated here only for the purposes of 40644574Sphk * simulation. 40744574Sphk */ 40844574Sphkvoid 40944574Sphkntp_update_second(struct timecounter *tcp) 41044574Sphk{ 41144574Sphk u_int32_t *newsec; 41244574Sphk 41344574Sphk newsec = &tcp->tc_offset_sec; 41450656Sphk /* 41550656Sphk * On rollover of the second both the nanosecond and microsecond 41650656Sphk * clocks are updated and the state machine cranked as 41750656Sphk * necessary. The phase adjustment to be used for the next 41850656Sphk * second is calculated and the maximum error is increased by 41950656Sphk * the tolerance. 42050656Sphk */ 42144574Sphk time_maxerror += MAXFREQ / 1000; 42244574Sphk 42344574Sphk /* 42444574Sphk * Leap second processing. If in leap-insert state at 42544574Sphk * the end of the day, the system clock is set back one 42644574Sphk * second; if in leap-delete state, the system clock is 42744574Sphk * set ahead one second. The nano_time() routine or 42844574Sphk * external clock driver will insure that reported time 42944574Sphk * is always monotonic. 43044574Sphk */ 43144574Sphk switch (time_state) { 43244574Sphk 4332858Swollman /* 43444574Sphk * No warning. 4352858Swollman */ 43644574Sphk case TIME_OK: 43744574Sphk if (time_status & STA_INS) 43844574Sphk time_state = TIME_INS; 43944574Sphk else if (time_status & STA_DEL) 44044574Sphk time_state = TIME_DEL; 44144574Sphk break; 44244574Sphk 44344574Sphk /* 44444574Sphk * Insert second 23:59:60 following second 44544574Sphk * 23:59:59. 44644574Sphk */ 44744574Sphk case TIME_INS: 44844574Sphk if (!(time_status & STA_INS)) 44944574Sphk time_state = TIME_OK; 45044574Sphk else if ((*newsec) % 86400 == 0) { 45144574Sphk (*newsec)--; 45244574Sphk time_state = TIME_OOP; 45344574Sphk } 45444574Sphk break; 45544574Sphk 45644574Sphk /* 45744574Sphk * Delete second 23:59:59. 45844574Sphk */ 45944574Sphk case TIME_DEL: 46044574Sphk if (!(time_status & STA_DEL)) 46144574Sphk time_state = TIME_OK; 46244574Sphk else if (((*newsec) + 1) % 86400 == 0) { 46344574Sphk (*newsec)++; 46444574Sphk time_state = TIME_WAIT; 46544574Sphk } 46644574Sphk break; 46744574Sphk 46844574Sphk /* 46944574Sphk * Insert second in progress. 47044574Sphk */ 47144574Sphk case TIME_OOP: 47244574Sphk time_state = TIME_WAIT; 47344574Sphk break; 47444574Sphk 47544574Sphk /* 47644574Sphk * Wait for status bits to clear. 47744574Sphk */ 47844574Sphk case TIME_WAIT: 47944574Sphk if (!(time_status & (STA_INS | STA_DEL))) 48044574Sphk time_state = TIME_OK; 4812858Swollman } 48244574Sphk 48344574Sphk /* 48450656Sphk * Compute the total time adjustment for the next second 48550656Sphk * in ns. The offset is reduced by a factor depending on 48650656Sphk * whether the PPS signal is operating. Note that the 48750656Sphk * value is in effect scaled by the clock frequency, 48850656Sphk * since the adjustment is added at each tick interrupt. 48944574Sphk */ 49044574Sphk#ifdef PPS_SYNC 49155413Sphk /* XXX even if signal dies we should finish adjustment ? */ 49255219Sphk if (time_status & STA_PPSTIME && time_status & STA_PPSSIGNAL) { 49355413Sphk time_adj = pps_offset; 49455219Sphk L_RSHIFT(time_adj, pps_shift); 49555413Sphk L_SUB(pps_offset, time_adj); 49655219Sphk } else { 49755413Sphk time_adj = time_offset; 49855219Sphk L_RSHIFT(time_adj, SHIFT_PLL + time_constant); 49955219Sphk L_SUB(time_offset, time_adj); 50055219Sphk } 50144574Sphk#else 50255413Sphk time_adj = time_offset; 50355219Sphk L_RSHIFT(time_adj, SHIFT_PLL + time_constant); 50455219Sphk L_SUB(time_offset, time_adj); 50544574Sphk#endif /* PPS_SYNC */ 50644574Sphk L_ADD(time_adj, time_freq); 50744574Sphk tcp->tc_adjustment = time_adj; 50844574Sphk#ifdef PPS_SYNC 50944574Sphk if (pps_valid > 0) 51044574Sphk pps_valid--; 51144574Sphk else 51244574Sphk time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER | 51344574Sphk STA_PPSWANDER | STA_PPSERROR); 51444574Sphk#endif /* PPS_SYNC */ 5152858Swollman} 5162858Swollman 51744574Sphk/* 51844574Sphk * ntp_init() - initialize variables and structures 51944574Sphk * 52044574Sphk * This routine must be called after the kernel variables hz and tick 52144574Sphk * are set or changed and before the next tick interrupt. In this 52244574Sphk * particular implementation, these values are assumed set elsewhere in 52344574Sphk * the kernel. The design allows the clock frequency and tick interval 52444574Sphk * to be changed while the system is running. So, this routine should 52544574Sphk * probably be integrated with the code that does that. 52644574Sphk */ 52744574Sphkstatic void 52844574Sphkntp_init() 52944574Sphk{ 53044574Sphk 53144574Sphk /* 53244574Sphk * The following variable must be initialized any time the 53344574Sphk * kernel variable hz is changed. 53444574Sphk */ 53544574Sphk time_tick = NANOSECOND / hz; 53644574Sphk 53744574Sphk /* 53844574Sphk * The following variables are initialized only at startup. Only 53944574Sphk * those structures not cleared by the compiler need to be 54044574Sphk * initialized, and these only in the simulator. In the actual 54144574Sphk * kernel, any nonzero values here will quickly evaporate. 54244574Sphk */ 54344574Sphk L_CLR(time_offset); 54444574Sphk L_CLR(time_freq); 54532513Sphk#ifdef PPS_SYNC 54650656Sphk pps_tf[0].tv_sec = pps_tf[0].tv_nsec = 0; 54750656Sphk pps_tf[1].tv_sec = pps_tf[1].tv_nsec = 0; 54850656Sphk pps_tf[2].tv_sec = pps_tf[2].tv_nsec = 0; 54944794Sphk pps_fcount = 0; 55044574Sphk L_CLR(pps_freq); 55144574Sphk#endif /* PPS_SYNC */ 55244574Sphk} 5532858Swollman 55444574SphkSYSINIT(ntpclocks, SI_SUB_CLOCKS, SI_ORDER_FIRST, ntp_init, NULL) 55532513Sphk 55644574Sphk/* 55744574Sphk * hardupdate() - local clock update 55844574Sphk * 55944574Sphk * This routine is called by ntp_adjtime() to update the local clock 56044574Sphk * phase and frequency. The implementation is of an adaptive-parameter, 56144574Sphk * hybrid phase/frequency-lock loop (PLL/FLL). The routine computes new 56244574Sphk * time and frequency offset estimates for each call. If the kernel PPS 56344574Sphk * discipline code is configured (PPS_SYNC), the PPS signal itself 56444574Sphk * determines the new time offset, instead of the calling argument. 56544574Sphk * Presumably, calls to ntp_adjtime() occur only when the caller 56644574Sphk * believes the local clock is valid within some bound (+-128 ms with 56744574Sphk * NTP). If the caller's time is far different than the PPS time, an 56844574Sphk * argument will ensue, and it's not clear who will lose. 56944574Sphk * 57044574Sphk * For uncompensated quartz crystal oscillators and nominal update 57144574Sphk * intervals less than 256 s, operation should be in phase-lock mode, 57244574Sphk * where the loop is disciplined to phase. For update intervals greater 57344574Sphk * than 1024 s, operation should be in frequency-lock mode, where the 57444574Sphk * loop is disciplined to frequency. Between 256 s and 1024 s, the mode 57544574Sphk * is selected by the STA_MODE status bit. 57644574Sphk */ 57744574Sphkstatic void 57844574Sphkhardupdate(offset) 57944574Sphk long offset; /* clock offset (ns) */ 58044574Sphk{ 58144574Sphk long ltemp, mtemp; 58244574Sphk l_fp ftemp; 58332513Sphk 58444574Sphk /* 58544574Sphk * Select how the phase is to be controlled and from which 58644574Sphk * source. If the PPS signal is present and enabled to 58744574Sphk * discipline the time, the PPS offset is used; otherwise, the 58844574Sphk * argument offset is used. 58944574Sphk */ 59050656Sphk if (!(time_status & STA_PLL)) 59150656Sphk return; 59244574Sphk ltemp = offset; 59344574Sphk if (ltemp > MAXPHASE) 59444574Sphk ltemp = MAXPHASE; 59544574Sphk else if (ltemp < -MAXPHASE) 59644574Sphk ltemp = -MAXPHASE; 59744574Sphk if (!(time_status & STA_PPSTIME && time_status & STA_PPSSIGNAL)) 59844574Sphk L_LINT(time_offset, ltemp); 59932513Sphk 60044574Sphk /* 60144574Sphk * Select how the frequency is to be controlled and in which 60244574Sphk * mode (PLL or FLL). If the PPS signal is present and enabled 60344574Sphk * to discipline the frequency, the PPS frequency is used; 60444574Sphk * otherwise, the argument offset is used to compute it. 60544574Sphk */ 60644574Sphk if (time_status & STA_PPSFREQ && time_status & STA_PPSSIGNAL) { 60744574Sphk time_reftime = time_second; 60844574Sphk return; 60944574Sphk } 61044574Sphk if (time_status & STA_FREQHOLD || time_reftime == 0) 61144574Sphk time_reftime = time_second; 61244574Sphk mtemp = time_second - time_reftime; 61350656Sphk L_LINT(ftemp, ltemp); 61450656Sphk L_RSHIFT(ftemp, (SHIFT_PLL + 2 + time_constant) << 1); 61550656Sphk L_MPY(ftemp, mtemp); 61650656Sphk L_ADD(time_freq, ftemp); 61750656Sphk time_status &= ~STA_MODE; 61850656Sphk if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) { 61944574Sphk L_LINT(ftemp, (ltemp << 4) / mtemp); 62044574Sphk L_RSHIFT(ftemp, SHIFT_FLL + 4); 62144574Sphk L_ADD(time_freq, ftemp); 62244574Sphk time_status |= STA_MODE; 62344574Sphk } 62444574Sphk time_reftime = time_second; 62544574Sphk if (L_GINT(time_freq) > MAXFREQ) 62644574Sphk L_LINT(time_freq, MAXFREQ); 62744574Sphk else if (L_GINT(time_freq) < -MAXFREQ) 62844574Sphk L_LINT(time_freq, -MAXFREQ); 62944574Sphk} 63044574Sphk 63144574Sphk#ifdef PPS_SYNC 63232513Sphk/* 63332513Sphk * hardpps() - discipline CPU clock oscillator to external PPS signal 63432513Sphk * 63532513Sphk * This routine is called at each PPS interrupt in order to discipline 63632513Sphk * the CPU clock oscillator to the PPS signal. It measures the PPS phase 63732513Sphk * and leaves it in a handy spot for the hardclock() routine. It 63832513Sphk * integrates successive PPS phase differences and calculates the 63932513Sphk * frequency offset. This is used in hardclock() to discipline the CPU 64044574Sphk * clock oscillator so that the intrinsic frequency error is cancelled 64144574Sphk * out. The code requires the caller to capture the time and 64244574Sphk * architecture-dependent hardware counter values in nanoseconds at the 64344574Sphk * on-time PPS signal transition. 64432513Sphk * 64544574Sphk * Note that, on some Unix systems this routine runs at an interrupt 64632513Sphk * priority level higher than the timer interrupt routine hardclock(). 64732513Sphk * Therefore, the variables used are distinct from the hardclock() 64844574Sphk * variables, except for the actual time and frequency variables, which 64944574Sphk * are determined by this routine and updated atomically. 65032513Sphk */ 65132513Sphkvoid 65244574Sphkhardpps(tsp, nsec) 65344574Sphk struct timespec *tsp; /* time at PPS */ 65444574Sphk long nsec; /* hardware counter at PPS */ 65532513Sphk{ 65656458Sphk long u_sec, u_nsec, v_nsec, w_nsec; /* temps */ 65744574Sphk l_fp ftemp; 65832513Sphk 65932513Sphk /* 66044574Sphk * The signal is first processed by a frequency discriminator 66144574Sphk * which rejects noise and input signals with frequencies 66244574Sphk * outside the range 1 +-MAXFREQ PPS. If two hits occur in the 66344574Sphk * same second, we ignore the later hit; if not and a hit occurs 66444574Sphk * outside the range gate, keep the later hit but do not 66544574Sphk * process it. 66632513Sphk */ 66744574Sphk time_status |= STA_PPSSIGNAL | STA_PPSJITTER; 66844574Sphk time_status &= ~(STA_PPSWANDER | STA_PPSERROR); 66944574Sphk pps_valid = PPS_VALID; 67044574Sphk u_sec = tsp->tv_sec; 67144574Sphk u_nsec = tsp->tv_nsec; 67244574Sphk if (u_nsec >= (NANOSECOND >> 1)) { 67344574Sphk u_nsec -= NANOSECOND; 67444574Sphk u_sec++; 67544574Sphk } 67650656Sphk v_nsec = u_nsec - pps_tf[0].tv_nsec; 67750656Sphk if (u_sec == pps_tf[0].tv_sec && v_nsec < -MAXFREQ) { 67844574Sphk return; 67944574Sphk } 68044574Sphk pps_tf[2] = pps_tf[1]; 68144574Sphk pps_tf[1] = pps_tf[0]; 68250656Sphk pps_tf[0].tv_sec = u_sec; 68350656Sphk pps_tf[0].tv_nsec = u_nsec; 68432513Sphk 68532513Sphk /* 68644574Sphk * Compute the difference between the current and previous 68744574Sphk * counter values. If the difference exceeds 0.5 s, assume it 68844574Sphk * has wrapped around, so correct 1.0 s. If the result exceeds 68944574Sphk * the tick interval, the sample point has crossed a tick 69044574Sphk * boundary during the last second, so correct the tick. Very 69144574Sphk * intricate. 69244574Sphk */ 69344666Sphk u_nsec = nsec; 69444574Sphk if (u_nsec > (NANOSECOND >> 1)) 69544574Sphk u_nsec -= NANOSECOND; 69644574Sphk else if (u_nsec < -(NANOSECOND >> 1)) 69744574Sphk u_nsec += NANOSECOND; 69844794Sphk pps_fcount += u_nsec; 69950656Sphk if (v_nsec > MAXFREQ || v_nsec < -MAXFREQ) { 70044574Sphk return; 70144574Sphk } 70244574Sphk time_status &= ~STA_PPSJITTER; 70344574Sphk 70444574Sphk /* 70544574Sphk * A three-stage median filter is used to help denoise the PPS 70632513Sphk * time. The median sample becomes the time offset estimate; the 70732513Sphk * difference between the other two samples becomes the time 70832513Sphk * dispersion (jitter) estimate. 70932513Sphk */ 71050656Sphk if (pps_tf[0].tv_nsec > pps_tf[1].tv_nsec) { 71150656Sphk if (pps_tf[1].tv_nsec > pps_tf[2].tv_nsec) { 71250656Sphk v_nsec = pps_tf[1].tv_nsec; /* 0 1 2 */ 71350656Sphk u_nsec = pps_tf[0].tv_nsec - pps_tf[2].tv_nsec; 71450656Sphk } else if (pps_tf[2].tv_nsec > pps_tf[0].tv_nsec) { 71550656Sphk v_nsec = pps_tf[0].tv_nsec; /* 2 0 1 */ 71650656Sphk u_nsec = pps_tf[2].tv_nsec - pps_tf[1].tv_nsec; 71744574Sphk } else { 71850656Sphk v_nsec = pps_tf[2].tv_nsec; /* 0 2 1 */ 71950656Sphk u_nsec = pps_tf[0].tv_nsec - pps_tf[1].tv_nsec; 72044574Sphk } 72144574Sphk } else { 72250656Sphk if (pps_tf[1].tv_nsec < pps_tf[2].tv_nsec) { 72350656Sphk v_nsec = pps_tf[1].tv_nsec; /* 2 1 0 */ 72450656Sphk u_nsec = pps_tf[2].tv_nsec - pps_tf[0].tv_nsec; 72550656Sphk } else if (pps_tf[2].tv_nsec < pps_tf[0].tv_nsec) { 72650656Sphk v_nsec = pps_tf[0].tv_nsec; /* 1 0 2 */ 72750656Sphk u_nsec = pps_tf[1].tv_nsec - pps_tf[2].tv_nsec; 72844574Sphk } else { 72950656Sphk v_nsec = pps_tf[2].tv_nsec; /* 1 2 0 */ 73050656Sphk u_nsec = pps_tf[1].tv_nsec - pps_tf[0].tv_nsec; 73144574Sphk } 73244574Sphk } 73332513Sphk 73432513Sphk /* 73544574Sphk * Nominal jitter is due to PPS signal noise and interrupt 73650656Sphk * latency. If it exceeds the popcorn threshold, 73750656Sphk * the sample is discarded. otherwise, if so enabled, the time 73850656Sphk * offset is updated. We can tolerate a modest loss of data here 73950656Sphk * without degrading time accuracy. 74032513Sphk */ 74150656Sphk if (u_nsec > (pps_jitter << PPS_POPCORN)) { 74244574Sphk time_status |= STA_PPSJITTER; 74344574Sphk pps_jitcnt++; 74444574Sphk } else if (time_status & STA_PPSTIME) { 74555219Sphk L_LINT(time_offset, -v_nsec); 74655413Sphk L_LINT(pps_offset, -v_nsec); 74756458Sphk 74856458Sphk if (pps_letgo >= 2) { 74956458Sphk L_LINT(ftemp, -v_nsec); 75056458Sphk L_RSHIFT(ftemp, (pps_shift * 2)); 75156458Sphk L_ADD(ftemp, time_freq); 75256458Sphk w_nsec = L_GINT(ftemp); 75356458Sphk if (w_nsec > MAXFREQ) 75456458Sphk L_LINT(ftemp, MAXFREQ); 75556458Sphk else if (w_nsec < -MAXFREQ) 75656458Sphk L_LINT(ftemp, -MAXFREQ); 75756458Sphk time_freq = ftemp; 75856458Sphk } 75956458Sphk 76032513Sphk } 76144574Sphk pps_jitter += (u_nsec - pps_jitter) >> PPS_FAVG; 76250656Sphk u_sec = pps_tf[0].tv_sec - pps_lastsec; 76344574Sphk if (u_sec < (1 << pps_shift)) 76444574Sphk return; 76544574Sphk 76632513Sphk /* 76744574Sphk * At the end of the calibration interval the difference between 76844574Sphk * the first and last counter values becomes the scaled 76944574Sphk * frequency. It will later be divided by the length of the 77044574Sphk * interval to determine the frequency update. If the frequency 77144574Sphk * exceeds a sanity threshold, or if the actual calibration 77244574Sphk * interval is not equal to the expected length, the data are 77344574Sphk * discarded. We can tolerate a modest loss of data here without 77444574Sphk * degrading frequency ccuracy. 77532513Sphk */ 77644574Sphk pps_calcnt++; 77744794Sphk v_nsec = -pps_fcount; 77850656Sphk pps_lastsec = pps_tf[0].tv_sec; 77944794Sphk pps_fcount = 0; 78044574Sphk u_nsec = MAXFREQ << pps_shift; 78144574Sphk if (v_nsec > u_nsec || v_nsec < -u_nsec || u_sec != (1 << 78244574Sphk pps_shift)) { 78344574Sphk time_status |= STA_PPSERROR; 78432513Sphk pps_errcnt++; 78532513Sphk return; 78632513Sphk } 78732513Sphk 78832513Sphk /* 78950656Sphk * Here the raw frequency offset and wander (stability) is 79050656Sphk * calculated. If the wander is less than the wander threshold 79150656Sphk * for four consecutive averaging intervals, the interval is 79250656Sphk * doubled; if it is greater than the threshold for four 79350656Sphk * consecutive intervals, the interval is halved. The scaled 79450656Sphk * frequency offset is converted to frequency offset. The 79550656Sphk * stability metric is calculated as the average of recent 79650656Sphk * frequency changes, but is used only for performance 79744574Sphk * monitoring. 79832513Sphk */ 79944574Sphk L_LINT(ftemp, v_nsec); 80044574Sphk L_RSHIFT(ftemp, pps_shift); 80144574Sphk L_SUB(ftemp, pps_freq); 80244574Sphk u_nsec = L_GINT(ftemp); 80350656Sphk if (u_nsec > PPS_MAXWANDER) { 80450656Sphk L_LINT(ftemp, PPS_MAXWANDER); 80544574Sphk pps_intcnt--; 80644574Sphk time_status |= STA_PPSWANDER; 80732513Sphk pps_stbcnt++; 80850656Sphk } else if (u_nsec < -PPS_MAXWANDER) { 80950656Sphk L_LINT(ftemp, -PPS_MAXWANDER); 81044574Sphk pps_intcnt--; 81132513Sphk time_status |= STA_PPSWANDER; 81244574Sphk pps_stbcnt++; 81344574Sphk } else { 81444574Sphk pps_intcnt++; 81532513Sphk } 81656458Sphk if (!(time_status & STA_PPSFREQ)) { 81756458Sphk pps_intcnt = 0; 81856458Sphk pps_shift = PPS_FAVG; 81956458Sphk } else if (pps_shift > pps_shiftmax) { 82055219Sphk /* If we lowered pps_shiftmax */ 82155219Sphk pps_shift = pps_shiftmax; 82255219Sphk pps_intcnt = 0; 82355219Sphk } else if (pps_intcnt >= 4) { 82444574Sphk pps_intcnt = 4; 82550656Sphk if (pps_shift < pps_shiftmax) { 82644574Sphk pps_shift++; 82744574Sphk pps_intcnt = 0; 82832513Sphk } 82944574Sphk } else if (pps_intcnt <= -4) { 83044574Sphk pps_intcnt = -4; 83144574Sphk if (pps_shift > PPS_FAVG) { 83244574Sphk pps_shift--; 83344574Sphk pps_intcnt = 0; 83444574Sphk } 83532513Sphk } 83644574Sphk if (u_nsec < 0) 83744574Sphk u_nsec = -u_nsec; 83844574Sphk pps_stabil += (u_nsec * SCALE_PPM - pps_stabil) >> PPS_FAVG; 83932513Sphk 84032513Sphk /* 84150656Sphk * The PPS frequency is recalculated and clamped to the maximum 84250656Sphk * MAXFREQ. If enabled, the system clock frequency is updated as 84350656Sphk * well. 84432513Sphk */ 84544574Sphk L_ADD(pps_freq, ftemp); 84644574Sphk u_nsec = L_GINT(pps_freq); 84744574Sphk if (u_nsec > MAXFREQ) 84844574Sphk L_LINT(pps_freq, MAXFREQ); 84944574Sphk else if (u_nsec < -MAXFREQ) 85044574Sphk L_LINT(pps_freq, -MAXFREQ); 85156458Sphk if ((time_status & (STA_PPSFREQ | STA_PPSTIME)) == STA_PPSFREQ) { 85256458Sphk pps_letgo = 0; 85344574Sphk time_freq = pps_freq; 85456458Sphk } else if (time_status & STA_PPSTIME) { 85556458Sphk if (pps_letgo < 2) 85656458Sphk pps_letgo++; 85756458Sphk } 85832513Sphk} 85932513Sphk#endif /* PPS_SYNC */ 860