kern_ntptime.c revision 165969
1139804Simp/*- 2139804Simp *********************************************************************** 344574Sphk * * 475540Sjhay * Copyright (c) David L. Mills 1993-2001 * 544574Sphk * * 644574Sphk * Permission to use, copy, modify, and distribute this software and * 744574Sphk * its documentation for any purpose and without fee is hereby * 844574Sphk * granted, provided that the above copyright notice appears in all * 944574Sphk * copies and that both the copyright notice and this permission * 1044574Sphk * notice appear in supporting documentation, and that the name * 1144574Sphk * University of Delaware not be used in advertising or publicity * 1244574Sphk * pertaining to distribution of the software without specific, * 1344574Sphk * written prior permission. The University of Delaware makes no * 1444574Sphk * representations about the suitability this software for any * 1544574Sphk * purpose. It is provided "as is" without express or implied * 1644574Sphk * warranty. * 1744574Sphk * * 1844574Sphk **********************************************************************/ 192858Swollman 202858Swollman/* 2144574Sphk * Adapted from the original sources for FreeBSD and timecounters by: 2244666Sphk * Poul-Henning Kamp <phk@FreeBSD.org>. 232858Swollman * 2444574Sphk * The 32bit version of the "LP" macros seems a bit past its "sell by" 2544574Sphk * date so I have retained only the 64bit version and included it directly 2644574Sphk * in this file. 2721101Sjhay * 2844574Sphk * Only minor changes done to interface with the timecounters over in 2944574Sphk * sys/kern/kern_clock.c. Some of the comments below may be (even more) 3044574Sphk * confusing and/or plain wrong in that context. 312858Swollman */ 3232925Seivind 33116182Sobrien#include <sys/cdefs.h> 34116182Sobrien__FBSDID("$FreeBSD: head/sys/kern/kern_ntptime.c 165969 2007-01-12 07:40:30Z imp $"); 35116182Sobrien 3644666Sphk#include "opt_ntp.h" 3744666Sphk 382858Swollman#include <sys/param.h> 392858Swollman#include <sys/systm.h> 4012221Sbde#include <sys/sysproto.h> 412858Swollman#include <sys/kernel.h> 42164033Srwatson#include <sys/priv.h> 432858Swollman#include <sys/proc.h> 4482717Sdillon#include <sys/lock.h> 4582717Sdillon#include <sys/mutex.h> 4644574Sphk#include <sys/time.h> 472858Swollman#include <sys/timex.h> 4858377Sphk#include <sys/timetc.h> 4936941Sphk#include <sys/timepps.h> 50144445Sjhb#include <sys/syscallsubr.h> 512858Swollman#include <sys/sysctl.h> 522858Swollman 532858Swollman/* 5444574Sphk * Single-precision macros for 64-bit machines 5544574Sphk */ 56126974Sphktypedef int64_t l_fp; 5744574Sphk#define L_ADD(v, u) ((v) += (u)) 5844574Sphk#define L_SUB(v, u) ((v) -= (u)) 59126974Sphk#define L_ADDHI(v, a) ((v) += (int64_t)(a) << 32) 6044574Sphk#define L_NEG(v) ((v) = -(v)) 6144574Sphk#define L_RSHIFT(v, n) \ 6244574Sphk do { \ 6344574Sphk if ((v) < 0) \ 6444574Sphk (v) = -(-(v) >> (n)); \ 6544574Sphk else \ 6644574Sphk (v) = (v) >> (n); \ 6744574Sphk } while (0) 6844574Sphk#define L_MPY(v, a) ((v) *= (a)) 6944574Sphk#define L_CLR(v) ((v) = 0) 7044574Sphk#define L_ISNEG(v) ((v) < 0) 71126974Sphk#define L_LINT(v, a) ((v) = (int64_t)(a) << 32) 7244574Sphk#define L_GINT(v) ((v) < 0 ? -(-(v) >> 32) : (v) >> 32) 7344574Sphk 7444574Sphk/* 7544574Sphk * Generic NTP kernel interface 7632513Sphk * 7744574Sphk * These routines constitute the Network Time Protocol (NTP) interfaces 7844574Sphk * for user and daemon application programs. The ntp_gettime() routine 7944574Sphk * provides the time, maximum error (synch distance) and estimated error 8044574Sphk * (dispersion) to client user application programs. The ntp_adjtime() 8144574Sphk * routine is used by the NTP daemon to adjust the system clock to an 8244574Sphk * externally derived time. The time offset and related variables set by 8344574Sphk * this routine are used by other routines in this module to adjust the 8444574Sphk * phase and frequency of the clock discipline loop which controls the 8544574Sphk * system clock. 8632513Sphk * 8745294Sphk * When the kernel time is reckoned directly in nanoseconds (NTP_NANO 8844574Sphk * defined), the time at each tick interrupt is derived directly from 8944574Sphk * the kernel time variable. When the kernel time is reckoned in 9045294Sphk * microseconds, (NTP_NANO undefined), the time is derived from the 9145294Sphk * kernel time variable together with a variable representing the 9245294Sphk * leftover nanoseconds at the last tick interrupt. In either case, the 9345294Sphk * current nanosecond time is reckoned from these values plus an 9445294Sphk * interpolated value derived by the clock routines in another 9545294Sphk * architecture-specific module. The interpolation can use either a 9645294Sphk * dedicated counter or a processor cycle counter (PCC) implemented in 9745294Sphk * some architectures. 9832513Sphk * 9944574Sphk * Note that all routines must run at priority splclock or higher. 10044574Sphk */ 10144574Sphk/* 10244574Sphk * Phase/frequency-lock loop (PLL/FLL) definitions 10332513Sphk * 10444574Sphk * The nanosecond clock discipline uses two variable types, time 10544574Sphk * variables and frequency variables. Both types are represented as 64- 10644574Sphk * bit fixed-point quantities with the decimal point between two 32-bit 10744574Sphk * halves. On a 32-bit machine, each half is represented as a single 10844574Sphk * word and mathematical operations are done using multiple-precision 10944574Sphk * arithmetic. On a 64-bit machine, ordinary computer arithmetic is 11044574Sphk * used. 11132513Sphk * 11244574Sphk * A time variable is a signed 64-bit fixed-point number in ns and 11344574Sphk * fraction. It represents the remaining time offset to be amortized 11444574Sphk * over succeeding tick interrupts. The maximum time offset is about 11545294Sphk * 0.5 s and the resolution is about 2.3e-10 ns. 11632513Sphk * 11744574Sphk * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 11844574Sphk * 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 11944574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 12044574Sphk * |s s s| ns | 12144574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 12244574Sphk * | fraction | 12344574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 12432513Sphk * 12544574Sphk * A frequency variable is a signed 64-bit fixed-point number in ns/s 12644574Sphk * and fraction. It represents the ns and fraction to be added to the 12744574Sphk * kernel time variable at each second. The maximum frequency offset is 12845294Sphk * about +-500000 ns/s and the resolution is about 2.3e-10 ns/s. 12932513Sphk * 13044574Sphk * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 13144574Sphk * 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 13244574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 13344574Sphk * |s s s s s s s s s s s s s| ns/s | 13444574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 13544574Sphk * | fraction | 13644574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1372858Swollman */ 13832513Sphk/* 13932513Sphk * The following variables establish the state of the PLL/FLL and the 14044574Sphk * residual time and frequency offset of the local clock. 14132513Sphk */ 14244574Sphk#define SHIFT_PLL 4 /* PLL loop gain (shift) */ 14344574Sphk#define SHIFT_FLL 2 /* FLL loop gain (shift) */ 14432513Sphk 14544574Sphkstatic int time_state = TIME_OK; /* clock state */ 14644574Sphkstatic int time_status = STA_UNSYNC; /* clock status bits */ 14765432Sphkstatic long time_tai; /* TAI offset (s) */ 14865432Sphkstatic long time_monitor; /* last time offset scaled (ns) */ 14944574Sphkstatic long time_constant; /* poll interval (shift) (s) */ 15044574Sphkstatic long time_precision = 1; /* clock precision (ns) */ 15144574Sphkstatic long time_maxerror = MAXPHASE / 1000; /* maximum error (us) */ 15244574Sphkstatic long time_esterror = MAXPHASE / 1000; /* estimated error (us) */ 15344574Sphkstatic long time_reftime; /* time at last adjustment (s) */ 15444574Sphkstatic l_fp time_offset; /* time offset (ns) */ 15544574Sphkstatic l_fp time_freq; /* frequency offset (ns/s) */ 15665432Sphkstatic l_fp time_adj; /* tick adjust (ns/s) */ 15744574Sphk 15894754Sphkstatic int64_t time_adjtime; /* correction from adjtime(2) (usec) */ 15994754Sphk 1602858Swollman#ifdef PPS_SYNC 1612858Swollman/* 16244574Sphk * The following variables are used when a pulse-per-second (PPS) signal 16344574Sphk * is available and connected via a modem control lead. They establish 16444574Sphk * the engineering parameters of the clock discipline loop when 16544574Sphk * controlled by the PPS signal. 1662858Swollman */ 16744574Sphk#define PPS_FAVG 2 /* min freq avg interval (s) (shift) */ 16875540Sjhay#define PPS_FAVGDEF 8 /* default freq avg int (s) (shift) */ 16950656Sphk#define PPS_FAVGMAX 15 /* max freq avg interval (s) (shift) */ 17044574Sphk#define PPS_PAVG 4 /* phase avg interval (s) (shift) */ 17144574Sphk#define PPS_VALID 120 /* PPS signal watchdog max (s) */ 17250656Sphk#define PPS_MAXWANDER 100000 /* max PPS wander (ns/s) */ 17350656Sphk#define PPS_POPCORN 2 /* popcorn spike threshold (shift) */ 17432513Sphk 17550656Sphkstatic struct timespec pps_tf[3]; /* phase median filter */ 17644574Sphkstatic l_fp pps_freq; /* scaled frequency offset (ns/s) */ 17745294Sphkstatic long pps_fcount; /* frequency accumulator */ 17850656Sphkstatic long pps_jitter; /* nominal jitter (ns) */ 17950656Sphkstatic long pps_stabil; /* nominal stability (scaled ns/s) */ 18044574Sphkstatic long pps_lastsec; /* time at last calibration (s) */ 18144574Sphkstatic int pps_valid; /* signal watchdog counter */ 18244574Sphkstatic int pps_shift = PPS_FAVG; /* interval duration (s) (shift) */ 18350656Sphkstatic int pps_shiftmax = PPS_FAVGDEF; /* max interval duration (s) (shift) */ 18444574Sphkstatic int pps_intcnt; /* wander counter */ 18544574Sphk 18632513Sphk/* 18732513Sphk * PPS signal quality monitors 18832513Sphk */ 18944574Sphkstatic long pps_calcnt; /* calibration intervals */ 19044574Sphkstatic long pps_jitcnt; /* jitter limit exceeded */ 19144574Sphkstatic long pps_stbcnt; /* stability limit exceeded */ 19244574Sphkstatic long pps_errcnt; /* calibration errors */ 1932858Swollman#endif /* PPS_SYNC */ 19432513Sphk/* 19544574Sphk * End of phase/frequency-lock loop (PLL/FLL) definitions 19632513Sphk */ 19732513Sphk 19844574Sphkstatic void ntp_init(void); 19944574Sphkstatic void hardupdate(long offset); 200137873Smarksstatic void ntp_gettime1(struct ntptimeval *ntvp); 20132513Sphk 202137873Smarksstatic void 203137873Smarksntp_gettime1(struct ntptimeval *ntvp) 2042858Swollman{ 20544574Sphk struct timespec atv; /* nanosecond time */ 2062858Swollman 207146722Srwatson GIANT_REQUIRED; 208146722Srwatson 20944574Sphk nanotime(&atv); 210137873Smarks ntvp->time.tv_sec = atv.tv_sec; 211137873Smarks ntvp->time.tv_nsec = atv.tv_nsec; 212137873Smarks ntvp->maxerror = time_maxerror; 213137873Smarks ntvp->esterror = time_esterror; 214137873Smarks ntvp->tai = time_tai; 215137873Smarks ntvp->time_state = time_state; 2162858Swollman 2172858Swollman /* 21844574Sphk * Status word error decode. If any of these conditions occur, 21944574Sphk * an error is returned, instead of the status word. Most 22044574Sphk * applications will care only about the fact the system clock 22144574Sphk * may not be trusted, not about the details. 2222858Swollman * 2232858Swollman * Hardware or software error 2242858Swollman */ 22544574Sphk if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) || 2262858Swollman 2272858Swollman /* 22844574Sphk * PPS signal lost when either time or frequency synchronization 22944574Sphk * requested 2302858Swollman */ 23144574Sphk (time_status & (STA_PPSFREQ | STA_PPSTIME) && 23244574Sphk !(time_status & STA_PPSSIGNAL)) || 2332858Swollman 2342858Swollman /* 23544574Sphk * PPS jitter exceeded when time synchronization requested 2362858Swollman */ 23744574Sphk (time_status & STA_PPSTIME && 23844574Sphk time_status & STA_PPSJITTER) || 2392858Swollman 2402858Swollman /* 24144574Sphk * PPS wander exceeded or calibration error when frequency 24244574Sphk * synchronization requested 2432858Swollman */ 24444574Sphk (time_status & STA_PPSFREQ && 24544574Sphk time_status & (STA_PPSWANDER | STA_PPSERROR))) 246137873Smarks ntvp->time_state = TIME_ERROR; 2472858Swollman} 2482858Swollman 249137879Smarks/* 250137879Smarks * ntp_gettime() - NTP user application interface 251137879Smarks * 252137879Smarks * See the timex.h header file for synopsis and API description. Note 253137879Smarks * that the TAI offset is returned in the ntvtimeval.tai structure 254137879Smarks * member. 255137879Smarks */ 256137873Smarks#ifndef _SYS_SYSPROTO_H_ 257137873Smarksstruct ntp_gettime_args { 258137873Smarks struct ntptimeval *ntvp; 259137873Smarks}; 260137873Smarks#endif 261137873Smarks/* ARGSUSED */ 262137873Smarksint 263137873Smarksntp_gettime(struct thread *td, struct ntp_gettime_args *uap) 264137873Smarks{ 265137873Smarks struct ntptimeval ntv; 266137873Smarks 267146722Srwatson mtx_lock(&Giant); 268137873Smarks ntp_gettime1(&ntv); 269146722Srwatson mtx_unlock(&Giant); 270137873Smarks 271165969Simp td->td_retval[0] = ntv.time_state; 272137873Smarks return (copyout(&ntv, uap->ntvp, sizeof(ntv))); 273137873Smarks} 274137873Smarks 275137873Smarksstatic int 276137873Smarksntp_sysctl(SYSCTL_HANDLER_ARGS) 277137873Smarks{ 278137873Smarks struct ntptimeval ntv; /* temporary structure */ 279137873Smarks 280137873Smarks ntp_gettime1(&ntv); 281137873Smarks 282137873Smarks return (sysctl_handle_opaque(oidp, &ntv, sizeof(ntv), req)); 283137873Smarks} 284137873Smarks 28544574SphkSYSCTL_NODE(_kern, OID_AUTO, ntp_pll, CTLFLAG_RW, 0, ""); 28644574SphkSYSCTL_PROC(_kern_ntp_pll, OID_AUTO, gettime, CTLTYPE_OPAQUE|CTLFLAG_RD, 28712623Sphk 0, sizeof(struct ntptimeval) , ntp_sysctl, "S,ntptimeval", ""); 28812279Sphk 28950663Sphk#ifdef PPS_SYNC 29050656SphkSYSCTL_INT(_kern_ntp_pll, OID_AUTO, pps_shiftmax, CTLFLAG_RW, &pps_shiftmax, 0, ""); 29155413SphkSYSCTL_INT(_kern_ntp_pll, OID_AUTO, pps_shift, CTLFLAG_RW, &pps_shift, 0, ""); 29265673SphkSYSCTL_INT(_kern_ntp_pll, OID_AUTO, time_monitor, CTLFLAG_RD, &time_monitor, 0, ""); 29356458Sphk 29456458SphkSYSCTL_OPAQUE(_kern_ntp_pll, OID_AUTO, pps_freq, CTLFLAG_RD, &pps_freq, sizeof(pps_freq), "I", ""); 29556458SphkSYSCTL_OPAQUE(_kern_ntp_pll, OID_AUTO, time_freq, CTLFLAG_RD, &time_freq, sizeof(time_freq), "I", ""); 29650663Sphk#endif 2972858Swollman/* 2982858Swollman * ntp_adjtime() - NTP daemon application interface 29944574Sphk * 30065432Sphk * See the timex.h header file for synopsis and API description. Note 30165432Sphk * that the timex.constant structure member has a dual purpose to set 30265432Sphk * the time constant and to set the TAI offset. 3032858Swollman */ 30412221Sbde#ifndef _SYS_SYSPROTO_H_ 3052858Swollmanstruct ntp_adjtime_args { 30644574Sphk struct timex *tp; 3072858Swollman}; 30812221Sbde#endif 3092858Swollman 31082717Sdillon/* 31182717Sdillon * MPSAFE 31282717Sdillon */ 3132858Swollmanint 31483366Sjulianntp_adjtime(struct thread *td, struct ntp_adjtime_args *uap) 3152858Swollman{ 31644574Sphk struct timex ntv; /* temporary structure */ 31745294Sphk long freq; /* frequency ns/s) */ 31844574Sphk int modes; /* mode bits from structure */ 31944574Sphk int s; /* caller priority */ 3202858Swollman int error; 3212858Swollman 3222858Swollman error = copyin((caddr_t)uap->tp, (caddr_t)&ntv, sizeof(ntv)); 3232858Swollman if (error) 32444574Sphk return(error); 3252858Swollman 3262858Swollman /* 3272858Swollman * Update selected clock variables - only the superuser can 3282858Swollman * change anything. Note that there is no error checking here on 3292858Swollman * the assumption the superuser should know what it is doing. 33065432Sphk * Note that either the time constant or TAI offset are loaded 33175540Sjhay * from the ntv.constant member, depending on the mode bits. If 33275540Sjhay * the STA_PLL bit in the status word is cleared, the state and 33375540Sjhay * status words are reset to the initial values at boot. 3342858Swollman */ 33582717Sdillon mtx_lock(&Giant); 3362858Swollman modes = ntv.modes; 33744776Sphk if (modes) 338164033Srwatson error = priv_check(td, PRIV_NTP_ADJTIME); 33944574Sphk if (error) 34082717Sdillon goto done2; 3412858Swollman s = splclock(); 3422858Swollman if (modes & MOD_MAXERROR) 3432858Swollman time_maxerror = ntv.maxerror; 3442858Swollman if (modes & MOD_ESTERROR) 3452858Swollman time_esterror = ntv.esterror; 3462858Swollman if (modes & MOD_STATUS) { 34775540Sjhay if (time_status & STA_PLL && !(ntv.status & STA_PLL)) { 34875540Sjhay time_state = TIME_OK; 34975540Sjhay time_status = STA_UNSYNC; 35075540Sjhay#ifdef PPS_SYNC 35175540Sjhay pps_shift = PPS_FAVG; 35275540Sjhay#endif /* PPS_SYNC */ 35375540Sjhay } 3542858Swollman time_status &= STA_RONLY; 3552858Swollman time_status |= ntv.status & ~STA_RONLY; 3562858Swollman } 35745294Sphk if (modes & MOD_TIMECONST) { 35845294Sphk if (ntv.constant < 0) 35945294Sphk time_constant = 0; 36045294Sphk else if (ntv.constant > MAXTC) 36145294Sphk time_constant = MAXTC; 36245294Sphk else 36345294Sphk time_constant = ntv.constant; 36445294Sphk } 36565432Sphk if (modes & MOD_TAI) { 36665432Sphk if (ntv.constant > 0) /* XXX zero & negative numbers ? */ 36765432Sphk time_tai = ntv.constant; 36865432Sphk } 36950656Sphk#ifdef PPS_SYNC 37050656Sphk if (modes & MOD_PPSMAX) { 37150656Sphk if (ntv.shift < PPS_FAVG) 37250656Sphk pps_shiftmax = PPS_FAVG; 37350656Sphk else if (ntv.shift > PPS_FAVGMAX) 37450656Sphk pps_shiftmax = PPS_FAVGMAX; 37550656Sphk else 37650656Sphk pps_shiftmax = ntv.shift; 37750656Sphk } 37850656Sphk#endif /* PPS_SYNC */ 37944574Sphk if (modes & MOD_NANO) 38044574Sphk time_status |= STA_NANO; 38144574Sphk if (modes & MOD_MICRO) 38244574Sphk time_status &= ~STA_NANO; 38344574Sphk if (modes & MOD_CLKB) 38444574Sphk time_status |= STA_CLK; 38544574Sphk if (modes & MOD_CLKA) 38644574Sphk time_status &= ~STA_CLK; 38775540Sjhay if (modes & MOD_FREQUENCY) { 38875540Sjhay freq = (ntv.freq * 1000LL) >> 16; 38975540Sjhay if (freq > MAXFREQ) 39075540Sjhay L_LINT(time_freq, MAXFREQ); 39175540Sjhay else if (freq < -MAXFREQ) 39275540Sjhay L_LINT(time_freq, -MAXFREQ); 393126974Sphk else { 394126974Sphk /* 395126974Sphk * ntv.freq is [PPM * 2^16] = [us/s * 2^16] 396126974Sphk * time_freq is [ns/s * 2^32] 397126974Sphk */ 398126974Sphk time_freq = ntv.freq * 1000LL * 65536LL; 399126974Sphk } 40075540Sjhay#ifdef PPS_SYNC 40175540Sjhay pps_freq = time_freq; 40275540Sjhay#endif /* PPS_SYNC */ 40375540Sjhay } 404124937Sphk if (modes & MOD_OFFSET) { 405124937Sphk if (time_status & STA_NANO) 406124937Sphk hardupdate(ntv.offset); 407124937Sphk else 408124937Sphk hardupdate(ntv.offset * 1000); 409124937Sphk } 4102858Swollman 4112858Swollman /* 41265432Sphk * Retrieve all clock variables. Note that the TAI offset is 41365432Sphk * returned only by ntp_gettime(); 4142858Swollman */ 41544574Sphk if (time_status & STA_NANO) 41694740Sphk ntv.offset = L_GINT(time_offset); 4172858Swollman else 41894740Sphk ntv.offset = L_GINT(time_offset) / 1000; /* XXX rounding ? */ 41945295Sphk ntv.freq = L_GINT((time_freq / 1000LL) << 16); 4202858Swollman ntv.maxerror = time_maxerror; 4212858Swollman ntv.esterror = time_esterror; 4222858Swollman ntv.status = time_status; 42345294Sphk ntv.constant = time_constant; 42444574Sphk if (time_status & STA_NANO) 42544574Sphk ntv.precision = time_precision; 42644574Sphk else 42744574Sphk ntv.precision = time_precision / 1000; 42844574Sphk ntv.tolerance = MAXFREQ * SCALE_PPM; 4292858Swollman#ifdef PPS_SYNC 4302858Swollman ntv.shift = pps_shift; 43145295Sphk ntv.ppsfreq = L_GINT((pps_freq / 1000LL) << 16); 43244574Sphk if (time_status & STA_NANO) 43344574Sphk ntv.jitter = pps_jitter; 43444574Sphk else 43544574Sphk ntv.jitter = pps_jitter / 1000; 4362858Swollman ntv.stabil = pps_stabil; 4372858Swollman ntv.calcnt = pps_calcnt; 4382858Swollman ntv.errcnt = pps_errcnt; 4392858Swollman ntv.jitcnt = pps_jitcnt; 4402858Swollman ntv.stbcnt = pps_stbcnt; 4412858Swollman#endif /* PPS_SYNC */ 44244574Sphk splx(s); 4432858Swollman 4442858Swollman error = copyout((caddr_t)&ntv, (caddr_t)uap->tp, sizeof(ntv)); 44544574Sphk if (error) 44682717Sdillon goto done2; 44744574Sphk 44844574Sphk /* 44944574Sphk * Status word error decode. See comments in 45044574Sphk * ntp_gettime() routine. 45144574Sphk */ 45244574Sphk if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) || 45344574Sphk (time_status & (STA_PPSFREQ | STA_PPSTIME) && 45444574Sphk !(time_status & STA_PPSSIGNAL)) || 45544574Sphk (time_status & STA_PPSTIME && 45644574Sphk time_status & STA_PPSJITTER) || 45744574Sphk (time_status & STA_PPSFREQ && 45882717Sdillon time_status & (STA_PPSWANDER | STA_PPSERROR))) { 45983366Sjulian td->td_retval[0] = TIME_ERROR; 46082717Sdillon } else { 46183366Sjulian td->td_retval[0] = time_state; 46282717Sdillon } 46382717Sdillondone2: 46482717Sdillon mtx_unlock(&Giant); 46545302Sphk return (error); 46644574Sphk} 46744574Sphk 46844574Sphk/* 46944574Sphk * second_overflow() - called after ntp_tick_adjust() 47044574Sphk * 47144574Sphk * This routine is ordinarily called immediately following the above 47244574Sphk * routine ntp_tick_adjust(). While these two routines are normally 47344574Sphk * combined, they are separated here only for the purposes of 47444574Sphk * simulation. 47544574Sphk */ 47644574Sphkvoid 47795529Sphkntp_update_second(int64_t *adjustment, time_t *newsec) 47844574Sphk{ 47994754Sphk int tickrate; 48065432Sphk l_fp ftemp; /* 32/64-bit temporary */ 48144574Sphk 48250656Sphk /* 48350656Sphk * On rollover of the second both the nanosecond and microsecond 48450656Sphk * clocks are updated and the state machine cranked as 48550656Sphk * necessary. The phase adjustment to be used for the next 48650656Sphk * second is calculated and the maximum error is increased by 48750656Sphk * the tolerance. 48850656Sphk */ 48944574Sphk time_maxerror += MAXFREQ / 1000; 49044574Sphk 49144574Sphk /* 49244574Sphk * Leap second processing. If in leap-insert state at 49344574Sphk * the end of the day, the system clock is set back one 49444574Sphk * second; if in leap-delete state, the system clock is 49544574Sphk * set ahead one second. The nano_time() routine or 49644574Sphk * external clock driver will insure that reported time 49744574Sphk * is always monotonic. 49844574Sphk */ 49944574Sphk switch (time_state) { 50044574Sphk 5012858Swollman /* 50244574Sphk * No warning. 5032858Swollman */ 50444574Sphk case TIME_OK: 50544574Sphk if (time_status & STA_INS) 50644574Sphk time_state = TIME_INS; 50744574Sphk else if (time_status & STA_DEL) 50844574Sphk time_state = TIME_DEL; 50944574Sphk break; 51044574Sphk 51144574Sphk /* 51244574Sphk * Insert second 23:59:60 following second 51344574Sphk * 23:59:59. 51444574Sphk */ 51544574Sphk case TIME_INS: 51644574Sphk if (!(time_status & STA_INS)) 51744574Sphk time_state = TIME_OK; 51844574Sphk else if ((*newsec) % 86400 == 0) { 51944574Sphk (*newsec)--; 52044574Sphk time_state = TIME_OOP; 521116838Simp time_tai++; 52244574Sphk } 52344574Sphk break; 52444574Sphk 52544574Sphk /* 52644574Sphk * Delete second 23:59:59. 52744574Sphk */ 52844574Sphk case TIME_DEL: 52944574Sphk if (!(time_status & STA_DEL)) 53044574Sphk time_state = TIME_OK; 53144574Sphk else if (((*newsec) + 1) % 86400 == 0) { 53244574Sphk (*newsec)++; 53365432Sphk time_tai--; 53444574Sphk time_state = TIME_WAIT; 53544574Sphk } 53644574Sphk break; 53744574Sphk 53844574Sphk /* 53944574Sphk * Insert second in progress. 54044574Sphk */ 54144574Sphk case TIME_OOP: 54265432Sphk time_state = TIME_WAIT; 54344574Sphk break; 54444574Sphk 54544574Sphk /* 54644574Sphk * Wait for status bits to clear. 54744574Sphk */ 54844574Sphk case TIME_WAIT: 54944574Sphk if (!(time_status & (STA_INS | STA_DEL))) 55044574Sphk time_state = TIME_OK; 5512858Swollman } 55244574Sphk 55344574Sphk /* 55450656Sphk * Compute the total time adjustment for the next second 55550656Sphk * in ns. The offset is reduced by a factor depending on 55650656Sphk * whether the PPS signal is operating. Note that the 55750656Sphk * value is in effect scaled by the clock frequency, 55850656Sphk * since the adjustment is added at each tick interrupt. 55944574Sphk */ 56065432Sphk ftemp = time_offset; 56144574Sphk#ifdef PPS_SYNC 56265432Sphk /* XXX even if PPS signal dies we should finish adjustment ? */ 56365432Sphk if (time_status & STA_PPSTIME && time_status & 56465673Sphk STA_PPSSIGNAL) 56565432Sphk L_RSHIFT(ftemp, pps_shift); 56665432Sphk else 56765432Sphk L_RSHIFT(ftemp, SHIFT_PLL + time_constant); 56844574Sphk#else 56965432Sphk L_RSHIFT(ftemp, SHIFT_PLL + time_constant); 57044574Sphk#endif /* PPS_SYNC */ 57165432Sphk time_adj = ftemp; 57265432Sphk L_SUB(time_offset, ftemp); 57344574Sphk L_ADD(time_adj, time_freq); 57494754Sphk 57594754Sphk /* 57694754Sphk * Apply any correction from adjtime(2). If more than one second 57794754Sphk * off we slew at a rate of 5ms/s (5000 PPM) else 500us/s (500PPM) 57894754Sphk * until the last second is slewed the final < 500 usecs. 57994754Sphk */ 58094754Sphk if (time_adjtime != 0) { 58194754Sphk if (time_adjtime > 1000000) 58294754Sphk tickrate = 5000; 58394754Sphk else if (time_adjtime < -1000000) 58494754Sphk tickrate = -5000; 58594754Sphk else if (time_adjtime > 500) 58694754Sphk tickrate = 500; 58794754Sphk else if (time_adjtime < -500) 58894754Sphk tickrate = -500; 589126974Sphk else 59094754Sphk tickrate = time_adjtime; 59194754Sphk time_adjtime -= tickrate; 59294754Sphk L_LINT(ftemp, tickrate * 1000); 59394754Sphk L_ADD(time_adj, ftemp); 59494754Sphk } 59595529Sphk *adjustment = time_adj; 59694754Sphk 59744574Sphk#ifdef PPS_SYNC 59844574Sphk if (pps_valid > 0) 59944574Sphk pps_valid--; 60044574Sphk else 60175540Sjhay time_status &= ~STA_PPSSIGNAL; 60244574Sphk#endif /* PPS_SYNC */ 6032858Swollman} 6042858Swollman 60544574Sphk/* 60644574Sphk * ntp_init() - initialize variables and structures 60744574Sphk * 60844574Sphk * This routine must be called after the kernel variables hz and tick 60944574Sphk * are set or changed and before the next tick interrupt. In this 61044574Sphk * particular implementation, these values are assumed set elsewhere in 61144574Sphk * the kernel. The design allows the clock frequency and tick interval 61244574Sphk * to be changed while the system is running. So, this routine should 61344574Sphk * probably be integrated with the code that does that. 61444574Sphk */ 61544574Sphkstatic void 61644574Sphkntp_init() 61744574Sphk{ 61844574Sphk 61944574Sphk /* 62044574Sphk * The following variables are initialized only at startup. Only 62144574Sphk * those structures not cleared by the compiler need to be 62244574Sphk * initialized, and these only in the simulator. In the actual 62344574Sphk * kernel, any nonzero values here will quickly evaporate. 62444574Sphk */ 62544574Sphk L_CLR(time_offset); 62644574Sphk L_CLR(time_freq); 62732513Sphk#ifdef PPS_SYNC 62850656Sphk pps_tf[0].tv_sec = pps_tf[0].tv_nsec = 0; 62950656Sphk pps_tf[1].tv_sec = pps_tf[1].tv_nsec = 0; 63050656Sphk pps_tf[2].tv_sec = pps_tf[2].tv_nsec = 0; 63144794Sphk pps_fcount = 0; 63244574Sphk L_CLR(pps_freq); 63344574Sphk#endif /* PPS_SYNC */ 63444574Sphk} 6352858Swollman 636108755SpeterSYSINIT(ntpclocks, SI_SUB_CLOCKS, SI_ORDER_MIDDLE, ntp_init, NULL) 63732513Sphk 63844574Sphk/* 63944574Sphk * hardupdate() - local clock update 64044574Sphk * 64144574Sphk * This routine is called by ntp_adjtime() to update the local clock 64244574Sphk * phase and frequency. The implementation is of an adaptive-parameter, 64344574Sphk * hybrid phase/frequency-lock loop (PLL/FLL). The routine computes new 64444574Sphk * time and frequency offset estimates for each call. If the kernel PPS 64544574Sphk * discipline code is configured (PPS_SYNC), the PPS signal itself 64644574Sphk * determines the new time offset, instead of the calling argument. 64744574Sphk * Presumably, calls to ntp_adjtime() occur only when the caller 64844574Sphk * believes the local clock is valid within some bound (+-128 ms with 64944574Sphk * NTP). If the caller's time is far different than the PPS time, an 65044574Sphk * argument will ensue, and it's not clear who will lose. 65144574Sphk * 65244574Sphk * For uncompensated quartz crystal oscillators and nominal update 65344574Sphk * intervals less than 256 s, operation should be in phase-lock mode, 65444574Sphk * where the loop is disciplined to phase. For update intervals greater 65544574Sphk * than 1024 s, operation should be in frequency-lock mode, where the 65644574Sphk * loop is disciplined to frequency. Between 256 s and 1024 s, the mode 65744574Sphk * is selected by the STA_MODE status bit. 65844574Sphk */ 65944574Sphkstatic void 66044574Sphkhardupdate(offset) 66144574Sphk long offset; /* clock offset (ns) */ 66244574Sphk{ 66365432Sphk long mtemp; 66444574Sphk l_fp ftemp; 66532513Sphk 66644574Sphk /* 66744574Sphk * Select how the phase is to be controlled and from which 66844574Sphk * source. If the PPS signal is present and enabled to 66944574Sphk * discipline the time, the PPS offset is used; otherwise, the 67044574Sphk * argument offset is used. 67144574Sphk */ 67250656Sphk if (!(time_status & STA_PLL)) 67350656Sphk return; 67465432Sphk if (!(time_status & STA_PPSTIME && time_status & 67565432Sphk STA_PPSSIGNAL)) { 67665432Sphk if (offset > MAXPHASE) 67765432Sphk time_monitor = MAXPHASE; 67865432Sphk else if (offset < -MAXPHASE) 67965432Sphk time_monitor = -MAXPHASE; 68065432Sphk else 68165432Sphk time_monitor = offset; 68265432Sphk L_LINT(time_offset, time_monitor); 68365432Sphk } 68432513Sphk 68544574Sphk /* 68644574Sphk * Select how the frequency is to be controlled and in which 68744574Sphk * mode (PLL or FLL). If the PPS signal is present and enabled 68844574Sphk * to discipline the frequency, the PPS frequency is used; 68944574Sphk * otherwise, the argument offset is used to compute it. 69044574Sphk */ 69144574Sphk if (time_status & STA_PPSFREQ && time_status & STA_PPSSIGNAL) { 69244574Sphk time_reftime = time_second; 69344574Sphk return; 69444574Sphk } 69544574Sphk if (time_status & STA_FREQHOLD || time_reftime == 0) 69644574Sphk time_reftime = time_second; 69744574Sphk mtemp = time_second - time_reftime; 69865432Sphk L_LINT(ftemp, time_monitor); 69950656Sphk L_RSHIFT(ftemp, (SHIFT_PLL + 2 + time_constant) << 1); 70050656Sphk L_MPY(ftemp, mtemp); 70150656Sphk L_ADD(time_freq, ftemp); 70250656Sphk time_status &= ~STA_MODE; 70365432Sphk if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > 70465432Sphk MAXSEC)) { 70565432Sphk L_LINT(ftemp, (time_monitor << 4) / mtemp); 70644574Sphk L_RSHIFT(ftemp, SHIFT_FLL + 4); 70744574Sphk L_ADD(time_freq, ftemp); 70844574Sphk time_status |= STA_MODE; 70944574Sphk } 71044574Sphk time_reftime = time_second; 71144574Sphk if (L_GINT(time_freq) > MAXFREQ) 71244574Sphk L_LINT(time_freq, MAXFREQ); 71344574Sphk else if (L_GINT(time_freq) < -MAXFREQ) 71444574Sphk L_LINT(time_freq, -MAXFREQ); 71544574Sphk} 71644574Sphk 71744574Sphk#ifdef PPS_SYNC 71832513Sphk/* 71932513Sphk * hardpps() - discipline CPU clock oscillator to external PPS signal 72032513Sphk * 72132513Sphk * This routine is called at each PPS interrupt in order to discipline 72265432Sphk * the CPU clock oscillator to the PPS signal. There are two independent 72365432Sphk * first-order feedback loops, one for the phase, the other for the 72465432Sphk * frequency. The phase loop measures and grooms the PPS phase offset 72565432Sphk * and leaves it in a handy spot for the seconds overflow routine. The 72665432Sphk * frequency loop averages successive PPS phase differences and 72765432Sphk * calculates the PPS frequency offset, which is also processed by the 72865432Sphk * seconds overflow routine. The code requires the caller to capture the 72965432Sphk * time and architecture-dependent hardware counter values in 73065432Sphk * nanoseconds at the on-time PPS signal transition. 73132513Sphk * 73244574Sphk * Note that, on some Unix systems this routine runs at an interrupt 73332513Sphk * priority level higher than the timer interrupt routine hardclock(). 73432513Sphk * Therefore, the variables used are distinct from the hardclock() 73544574Sphk * variables, except for the actual time and frequency variables, which 73644574Sphk * are determined by this routine and updated atomically. 73732513Sphk */ 73832513Sphkvoid 73944574Sphkhardpps(tsp, nsec) 74044574Sphk struct timespec *tsp; /* time at PPS */ 74144574Sphk long nsec; /* hardware counter at PPS */ 74232513Sphk{ 74365432Sphk long u_sec, u_nsec, v_nsec; /* temps */ 74444574Sphk l_fp ftemp; 74532513Sphk 74632513Sphk /* 74765432Sphk * The signal is first processed by a range gate and frequency 74865432Sphk * discriminator. The range gate rejects noise spikes outside 74965432Sphk * the range +-500 us. The frequency discriminator rejects input 75065432Sphk * signals with apparent frequency outside the range 1 +-500 75165432Sphk * PPM. If two hits occur in the same second, we ignore the 75265432Sphk * later hit; if not and a hit occurs outside the range gate, 75365432Sphk * keep the later hit for later comparison, but do not process 75465432Sphk * it. 75532513Sphk */ 75644574Sphk time_status |= STA_PPSSIGNAL | STA_PPSJITTER; 75744574Sphk time_status &= ~(STA_PPSWANDER | STA_PPSERROR); 75844574Sphk pps_valid = PPS_VALID; 75944574Sphk u_sec = tsp->tv_sec; 76044574Sphk u_nsec = tsp->tv_nsec; 76144574Sphk if (u_nsec >= (NANOSECOND >> 1)) { 76244574Sphk u_nsec -= NANOSECOND; 76344574Sphk u_sec++; 76444574Sphk } 76550656Sphk v_nsec = u_nsec - pps_tf[0].tv_nsec; 76675540Sjhay if (u_sec == pps_tf[0].tv_sec && v_nsec < NANOSECOND - 76775540Sjhay MAXFREQ) 76844574Sphk return; 76944574Sphk pps_tf[2] = pps_tf[1]; 77044574Sphk pps_tf[1] = pps_tf[0]; 77150656Sphk pps_tf[0].tv_sec = u_sec; 77250656Sphk pps_tf[0].tv_nsec = u_nsec; 77332513Sphk 77432513Sphk /* 77544574Sphk * Compute the difference between the current and previous 77644574Sphk * counter values. If the difference exceeds 0.5 s, assume it 77744574Sphk * has wrapped around, so correct 1.0 s. If the result exceeds 77844574Sphk * the tick interval, the sample point has crossed a tick 77944574Sphk * boundary during the last second, so correct the tick. Very 78044574Sphk * intricate. 78144574Sphk */ 78244666Sphk u_nsec = nsec; 78344574Sphk if (u_nsec > (NANOSECOND >> 1)) 78444574Sphk u_nsec -= NANOSECOND; 78544574Sphk else if (u_nsec < -(NANOSECOND >> 1)) 78644574Sphk u_nsec += NANOSECOND; 78744794Sphk pps_fcount += u_nsec; 78875540Sjhay if (v_nsec > MAXFREQ || v_nsec < -MAXFREQ) 78944574Sphk return; 79044574Sphk time_status &= ~STA_PPSJITTER; 79144574Sphk 79244574Sphk /* 79344574Sphk * A three-stage median filter is used to help denoise the PPS 79432513Sphk * time. The median sample becomes the time offset estimate; the 79532513Sphk * difference between the other two samples becomes the time 79632513Sphk * dispersion (jitter) estimate. 79732513Sphk */ 79850656Sphk if (pps_tf[0].tv_nsec > pps_tf[1].tv_nsec) { 79950656Sphk if (pps_tf[1].tv_nsec > pps_tf[2].tv_nsec) { 80050656Sphk v_nsec = pps_tf[1].tv_nsec; /* 0 1 2 */ 80150656Sphk u_nsec = pps_tf[0].tv_nsec - pps_tf[2].tv_nsec; 80250656Sphk } else if (pps_tf[2].tv_nsec > pps_tf[0].tv_nsec) { 80350656Sphk v_nsec = pps_tf[0].tv_nsec; /* 2 0 1 */ 80450656Sphk u_nsec = pps_tf[2].tv_nsec - pps_tf[1].tv_nsec; 80544574Sphk } else { 80650656Sphk v_nsec = pps_tf[2].tv_nsec; /* 0 2 1 */ 80750656Sphk u_nsec = pps_tf[0].tv_nsec - pps_tf[1].tv_nsec; 80844574Sphk } 80944574Sphk } else { 81050656Sphk if (pps_tf[1].tv_nsec < pps_tf[2].tv_nsec) { 81150656Sphk v_nsec = pps_tf[1].tv_nsec; /* 2 1 0 */ 81250656Sphk u_nsec = pps_tf[2].tv_nsec - pps_tf[0].tv_nsec; 81365673Sphk } else if (pps_tf[2].tv_nsec < pps_tf[0].tv_nsec) { 81450656Sphk v_nsec = pps_tf[0].tv_nsec; /* 1 0 2 */ 81550656Sphk u_nsec = pps_tf[1].tv_nsec - pps_tf[2].tv_nsec; 81644574Sphk } else { 81750656Sphk v_nsec = pps_tf[2].tv_nsec; /* 1 2 0 */ 81850656Sphk u_nsec = pps_tf[1].tv_nsec - pps_tf[0].tv_nsec; 81944574Sphk } 82044574Sphk } 82132513Sphk 82232513Sphk /* 82365673Sphk * Nominal jitter is due to PPS signal noise and interrupt 82465432Sphk * latency. If it exceeds the popcorn threshold, the sample is 82565432Sphk * discarded. otherwise, if so enabled, the time offset is 82665432Sphk * updated. We can tolerate a modest loss of data here without 82765432Sphk * much degrading time accuracy. 82832513Sphk */ 82950656Sphk if (u_nsec > (pps_jitter << PPS_POPCORN)) { 83044574Sphk time_status |= STA_PPSJITTER; 83144574Sphk pps_jitcnt++; 83244574Sphk } else if (time_status & STA_PPSTIME) { 83365432Sphk time_monitor = -v_nsec; 83465432Sphk L_LINT(time_offset, time_monitor); 83532513Sphk } 83644574Sphk pps_jitter += (u_nsec - pps_jitter) >> PPS_FAVG; 83750656Sphk u_sec = pps_tf[0].tv_sec - pps_lastsec; 83844574Sphk if (u_sec < (1 << pps_shift)) 83944574Sphk return; 84044574Sphk 84132513Sphk /* 84244574Sphk * At the end of the calibration interval the difference between 84344574Sphk * the first and last counter values becomes the scaled 84444574Sphk * frequency. It will later be divided by the length of the 84544574Sphk * interval to determine the frequency update. If the frequency 84644574Sphk * exceeds a sanity threshold, or if the actual calibration 84744574Sphk * interval is not equal to the expected length, the data are 84844574Sphk * discarded. We can tolerate a modest loss of data here without 84965432Sphk * much degrading frequency accuracy. 85032513Sphk */ 85144574Sphk pps_calcnt++; 85244794Sphk v_nsec = -pps_fcount; 85350656Sphk pps_lastsec = pps_tf[0].tv_sec; 85444794Sphk pps_fcount = 0; 85544574Sphk u_nsec = MAXFREQ << pps_shift; 85644574Sphk if (v_nsec > u_nsec || v_nsec < -u_nsec || u_sec != (1 << 85744574Sphk pps_shift)) { 85844574Sphk time_status |= STA_PPSERROR; 85932513Sphk pps_errcnt++; 86032513Sphk return; 86132513Sphk } 86232513Sphk 86332513Sphk /* 86450656Sphk * Here the raw frequency offset and wander (stability) is 86550656Sphk * calculated. If the wander is less than the wander threshold 86650656Sphk * for four consecutive averaging intervals, the interval is 86750656Sphk * doubled; if it is greater than the threshold for four 86850656Sphk * consecutive intervals, the interval is halved. The scaled 86950656Sphk * frequency offset is converted to frequency offset. The 87050656Sphk * stability metric is calculated as the average of recent 87150656Sphk * frequency changes, but is used only for performance 87244574Sphk * monitoring. 87332513Sphk */ 87444574Sphk L_LINT(ftemp, v_nsec); 87544574Sphk L_RSHIFT(ftemp, pps_shift); 87644574Sphk L_SUB(ftemp, pps_freq); 87744574Sphk u_nsec = L_GINT(ftemp); 87850656Sphk if (u_nsec > PPS_MAXWANDER) { 87950656Sphk L_LINT(ftemp, PPS_MAXWANDER); 88044574Sphk pps_intcnt--; 88144574Sphk time_status |= STA_PPSWANDER; 88232513Sphk pps_stbcnt++; 88350656Sphk } else if (u_nsec < -PPS_MAXWANDER) { 88450656Sphk L_LINT(ftemp, -PPS_MAXWANDER); 88544574Sphk pps_intcnt--; 88632513Sphk time_status |= STA_PPSWANDER; 88744574Sphk pps_stbcnt++; 88844574Sphk } else { 88944574Sphk pps_intcnt++; 89032513Sphk } 89165432Sphk if (pps_intcnt >= 4) { 89244574Sphk pps_intcnt = 4; 89350656Sphk if (pps_shift < pps_shiftmax) { 89444574Sphk pps_shift++; 89544574Sphk pps_intcnt = 0; 89632513Sphk } 89765432Sphk } else if (pps_intcnt <= -4 || pps_shift > pps_shiftmax) { 89844574Sphk pps_intcnt = -4; 89944574Sphk if (pps_shift > PPS_FAVG) { 90044574Sphk pps_shift--; 90144574Sphk pps_intcnt = 0; 90244574Sphk } 90332513Sphk } 90444574Sphk if (u_nsec < 0) 90544574Sphk u_nsec = -u_nsec; 90644574Sphk pps_stabil += (u_nsec * SCALE_PPM - pps_stabil) >> PPS_FAVG; 90732513Sphk 90832513Sphk /* 90950656Sphk * The PPS frequency is recalculated and clamped to the maximum 91050656Sphk * MAXFREQ. If enabled, the system clock frequency is updated as 91150656Sphk * well. 91232513Sphk */ 91344574Sphk L_ADD(pps_freq, ftemp); 91444574Sphk u_nsec = L_GINT(pps_freq); 91544574Sphk if (u_nsec > MAXFREQ) 91644574Sphk L_LINT(pps_freq, MAXFREQ); 91744574Sphk else if (u_nsec < -MAXFREQ) 91844574Sphk L_LINT(pps_freq, -MAXFREQ); 91965432Sphk if (time_status & STA_PPSFREQ) 92044574Sphk time_freq = pps_freq; 92132513Sphk} 92232513Sphk#endif /* PPS_SYNC */ 92394754Sphk 92494754Sphk#ifndef _SYS_SYSPROTO_H_ 92594754Sphkstruct adjtime_args { 92694754Sphk struct timeval *delta; 92794754Sphk struct timeval *olddelta; 92894754Sphk}; 92994754Sphk#endif 93094754Sphk/* 93194754Sphk * MPSAFE 93294754Sphk */ 93394754Sphk/* ARGSUSED */ 93494754Sphkint 93594754Sphkadjtime(struct thread *td, struct adjtime_args *uap) 93694754Sphk{ 937144445Sjhb struct timeval delta, olddelta, *deltap; 938144445Sjhb int error; 939144445Sjhb 940144445Sjhb if (uap->delta) { 941144445Sjhb error = copyin(uap->delta, &delta, sizeof(delta)); 942144445Sjhb if (error) 943144445Sjhb return (error); 944144445Sjhb deltap = δ 945144445Sjhb } else 946144445Sjhb deltap = NULL; 947144445Sjhb error = kern_adjtime(td, deltap, &olddelta); 948144445Sjhb if (uap->olddelta && error == 0) 949144445Sjhb error = copyout(&olddelta, uap->olddelta, sizeof(olddelta)); 950144445Sjhb return (error); 951144445Sjhb} 952144445Sjhb 953144445Sjhbint 954144445Sjhbkern_adjtime(struct thread *td, struct timeval *delta, struct timeval *olddelta) 955144445Sjhb{ 95694754Sphk struct timeval atv; 95794754Sphk int error; 95894754Sphk 959164033Srwatson if ((error = priv_check(td, PRIV_ADJTIME))) 96095036Sphk return (error); 96195036Sphk 96294754Sphk mtx_lock(&Giant); 963144445Sjhb if (olddelta) { 96494754Sphk atv.tv_sec = time_adjtime / 1000000; 96594754Sphk atv.tv_usec = time_adjtime % 1000000; 96694754Sphk if (atv.tv_usec < 0) { 96794754Sphk atv.tv_usec += 1000000; 96894754Sphk atv.tv_sec--; 96994754Sphk } 970144445Sjhb *olddelta = atv; 97194754Sphk } 972144445Sjhb if (delta) 973144445Sjhb time_adjtime = (int64_t)delta->tv_sec * 1000000 + 974144445Sjhb delta->tv_usec; 97594754Sphk mtx_unlock(&Giant); 97694754Sphk return (error); 97794754Sphk} 97894754Sphk 979