kern_ntptime.c revision 44666
144574Sphk/***********************************************************************
244574Sphk *								       *
344574Sphk * Copyright (c) David L. Mills 1993-1998			       *
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.
302858Swollman */
3132925Seivind
3244666Sphk#include "opt_ntp.h"
3344666Sphk
342858Swollman#include <sys/param.h>
352858Swollman#include <sys/systm.h>
3612221Sbde#include <sys/sysproto.h>
372858Swollman#include <sys/kernel.h>
382858Swollman#include <sys/proc.h>
3944574Sphk#include <sys/time.h>
402858Swollman#include <sys/timex.h>
4136941Sphk#include <sys/timepps.h>
422858Swollman#include <sys/sysctl.h>
432858Swollman
442858Swollman/*
4544574Sphk * Single-precision macros for 64-bit machines
4644574Sphk */
4744574Sphktypedef long long l_fp;
4844574Sphk#define L_ADD(v, u)	((v) += (u))
4944574Sphk#define L_SUB(v, u)	((v) -= (u))
5044574Sphk#define L_ADDHI(v, a)	((v) += (long long)(a) << 32)
5144574Sphk#define L_NEG(v)	((v) = -(v))
5244574Sphk#define L_RSHIFT(v, n) \
5344574Sphk	do { \
5444574Sphk		if ((v) < 0) \
5544574Sphk			(v) = -(-(v) >> (n)); \
5644574Sphk		else \
5744574Sphk			(v) = (v) >> (n); \
5844574Sphk	} while (0)
5944574Sphk#define L_MPY(v, a)	((v) *= (a))
6044574Sphk#define L_CLR(v)	((v) = 0)
6144574Sphk#define L_ISNEG(v)	((v) < 0)
6244574Sphk#define L_LINT(v, a)	((v) = (long long)(a) << 32)
6344574Sphk#define L_GINT(v)	((v) < 0 ? -(-(v) >> 32) : (v) >> 32)
6444574Sphk
6544574Sphk/*
6644574Sphk * Generic NTP kernel interface
6732513Sphk *
6844574Sphk * These routines constitute the Network Time Protocol (NTP) interfaces
6944574Sphk * for user and daemon application programs. The ntp_gettime() routine
7044574Sphk * provides the time, maximum error (synch distance) and estimated error
7144574Sphk * (dispersion) to client user application programs. The ntp_adjtime()
7244574Sphk * routine is used by the NTP daemon to adjust the system clock to an
7344574Sphk * externally derived time. The time offset and related variables set by
7444574Sphk * this routine are used by other routines in this module to adjust the
7544574Sphk * phase and frequency of the clock discipline loop which controls the
7644574Sphk * system clock.
7732513Sphk *
7844574Sphk * When the kernel time is reckoned directly in nanoseconds (NANO
7944574Sphk * defined), the time at each tick interrupt is derived directly from
8044574Sphk * the kernel time variable. When the kernel time is reckoned in
8144574Sphk * microseconds, (NANO undefined), the time is derived from the kernel
8244574Sphk * time variable together with a variable representing the leftover
8344574Sphk * nanoseconds at the last tick interrupt. In either case, the current
8444574Sphk * nanosecond time is reckoned from these values plus an interpolated
8544574Sphk * value derived by the clock routines in another architecture-specific
8644574Sphk * module. The interpolation can use either a dedicated counter or a
8744574Sphk * processor cycle counter (PCC) implemented in some architectures.
8832513Sphk *
8944574Sphk * Note that all routines must run at priority splclock or higher.
9044574Sphk */
9144574Sphk
9244574Sphk/*
9344574Sphk * Phase/frequency-lock loop (PLL/FLL) definitions
9432513Sphk *
9544574Sphk * The nanosecond clock discipline uses two variable types, time
9644574Sphk * variables and frequency variables. Both types are represented as 64-
9744574Sphk * bit fixed-point quantities with the decimal point between two 32-bit
9844574Sphk * halves. On a 32-bit machine, each half is represented as a single
9944574Sphk * word and mathematical operations are done using multiple-precision
10044574Sphk * arithmetic. On a 64-bit machine, ordinary computer arithmetic is
10144574Sphk * used.
10232513Sphk *
10344574Sphk * A time variable is a signed 64-bit fixed-point number in ns and
10444574Sphk * fraction. It represents the remaining time offset to be amortized
10544574Sphk * over succeeding tick interrupts. The maximum time offset is about
10644574Sphk * 0.512 s and the resolution is about 2.3e-10 ns.
10732513Sphk *
10844574Sphk *			1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
10944574Sphk *  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
11044574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
11144574Sphk * |s s s|			 ns				   |
11244574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
11344574Sphk * |			    fraction				   |
11444574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
11532513Sphk *
11644574Sphk * A frequency variable is a signed 64-bit fixed-point number in ns/s
11744574Sphk * and fraction. It represents the ns and fraction to be added to the
11844574Sphk * kernel time variable at each second. The maximum frequency offset is
11944574Sphk * about +-512000 ns/s and the resolution is about 2.3e-10 ns/s.
12032513Sphk *
12144574Sphk *			1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
12244574Sphk *  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
12344574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
12444574Sphk * |s s s s s s s s s s s s s|	          ns/s			   |
12544574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
12644574Sphk * |			    fraction				   |
12744574Sphk * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1282858Swollman */
12932513Sphk/*
13032513Sphk * The following variables establish the state of the PLL/FLL and the
13144574Sphk * residual time and frequency offset of the local clock.
13232513Sphk */
13344574Sphk#define SHIFT_PLL	4		/* PLL loop gain (shift) */
13444574Sphk#define SHIFT_FLL	2		/* FLL loop gain (shift) */
13532513Sphk
13644574Sphkstatic int time_state = TIME_OK;	/* clock state */
13744574Sphkstatic int time_status = STA_UNSYNC;	/* clock status bits */
13844574Sphkstatic long time_constant;		/* poll interval (shift) (s) */
13944574Sphkstatic long time_precision = 1;		/* clock precision (ns) */
14044574Sphkstatic long time_maxerror = MAXPHASE / 1000; /* maximum error (us) */
14144574Sphkstatic long time_esterror = MAXPHASE / 1000; /* estimated error (us) */
14244574Sphkstatic long time_reftime;		/* time at last adjustment (s) */
14344574Sphkstatic long time_tick;			/* nanoseconds per tick (ns) */
14444574Sphkstatic l_fp time_offset;		/* time offset (ns) */
14544574Sphkstatic l_fp time_freq;			/* frequency offset (ns/s) */
14644574Sphk
1472858Swollman#ifdef PPS_SYNC
1482858Swollman/*
14944574Sphk * The following variables are used when a pulse-per-second (PPS) signal
15044574Sphk * is available and connected via a modem control lead. They establish
15144574Sphk * the engineering parameters of the clock discipline loop when
15244574Sphk * controlled by the PPS signal.
1532858Swollman */
15444574Sphk#define PPS_FAVG	2		/* min freq avg interval (s) (shift) */
15544574Sphk#define PPS_FAVGMAX	8		/* max freq avg interval (s) (shift) */
15644574Sphk#define PPS_PAVG	4		/* phase avg interval (s) (shift) */
15744574Sphk#define PPS_VALID	120		/* PPS signal watchdog max (s) */
15844574Sphk#define MAXTIME		500000		/* max PPS error (jitter) (ns) */
15944574Sphk#define MAXWANDER	500000		/* max PPS wander (ns/s/s) */
16032513Sphk
16144574Sphkstruct ppstime {
16244574Sphk	long sec;			/* PPS seconds */
16344574Sphk	long nsec;			/* PPS nanoseconds */
16444574Sphk	long count;			/* PPS nanosecond counter */
16544574Sphk};
16644574Sphkstatic struct ppstime pps_tf[3];	/* phase median filter */
16744574Sphkstatic struct ppstime pps_filt;		/* phase offset */
16844574Sphkstatic l_fp pps_freq;			/* scaled frequency offset (ns/s) */
16944574Sphkstatic long pps_offacc;			/* offset accumulator */
17044574Sphkstatic long pps_jitter;			/* scaled time dispersion (ns) */
17144574Sphkstatic long pps_stabil;			/* scaled frequency dispersion (ns/s) */
17244574Sphkstatic long pps_lastcount;		/* last counter offset */
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) */
17644574Sphkstatic int pps_intcnt;			/* wander counter */
17744574Sphkstatic int pps_offcnt;			/* offset accumulator counter */
17844574Sphk
17932513Sphk/*
18032513Sphk * PPS signal quality monitors
18132513Sphk */
18244574Sphkstatic long pps_calcnt;			/* calibration intervals */
18344574Sphkstatic long pps_jitcnt;			/* jitter limit exceeded */
18444574Sphkstatic long pps_stbcnt;			/* stability limit exceeded */
18544574Sphkstatic long pps_errcnt;			/* calibration errors */
1862858Swollman#endif /* PPS_SYNC */
18732513Sphk/*
18844574Sphk * End of phase/frequency-lock loop (PLL/FLL) definitions
18932513Sphk */
19032513Sphk
19144574Sphkstatic void ntp_init(void);
19244574Sphkstatic void hardupdate(long offset);
19332513Sphk
19433690Sphk/*
19544574Sphk * ntp_gettime() - NTP user application interface
19633690Sphk *
19744574Sphk * See the timex.h header file for synopsis and API description.
19833690Sphk */
19912279Sphkstatic int
20012279Sphkntp_sysctl SYSCTL_HANDLER_ARGS
2012858Swollman{
20244574Sphk	struct ntptimeval ntv;	/* temporary structure */
20344574Sphk	struct timespec atv;	/* nanosecond time */
2042858Swollman
20544574Sphk	nanotime(&atv);
20644574Sphk	ntv.time.tv_sec = atv.tv_sec;
20744574Sphk	ntv.time.tv_nsec = atv.tv_nsec;
2082858Swollman	ntv.maxerror = time_maxerror;
2092858Swollman	ntv.esterror = time_esterror;
2102858Swollman	ntv.time_state = time_state;
2112858Swollman
2122858Swollman	/*
21344574Sphk	 * Status word error decode. If any of these conditions occur,
21444574Sphk	 * an error is returned, instead of the status word. Most
21544574Sphk	 * applications will care only about the fact the system clock
21644574Sphk	 * may not be trusted, not about the details.
2172858Swollman	 *
2182858Swollman	 * Hardware or software error
2192858Swollman	 */
22044574Sphk	if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) ||
2212858Swollman
2222858Swollman	/*
22344574Sphk	 * PPS signal lost when either time or frequency synchronization
22444574Sphk	 * requested
2252858Swollman	 */
22644574Sphk	    (time_status & (STA_PPSFREQ | STA_PPSTIME) &&
22744574Sphk	    !(time_status & STA_PPSSIGNAL)) ||
2282858Swollman
2292858Swollman	/*
23044574Sphk	 * PPS jitter exceeded when time synchronization requested
2312858Swollman	 */
23244574Sphk	    (time_status & STA_PPSTIME &&
23344574Sphk	    time_status & STA_PPSJITTER) ||
2342858Swollman
2352858Swollman	/*
23644574Sphk	 * PPS wander exceeded or calibration error when frequency
23744574Sphk	 * synchronization requested
2382858Swollman	 */
23944574Sphk	    (time_status & STA_PPSFREQ &&
24044574Sphk	    time_status & (STA_PPSWANDER | STA_PPSERROR)))
2412858Swollman		ntv.time_state = TIME_ERROR;
24212279Sphk	return (sysctl_handle_opaque(oidp, &ntv, sizeof ntv, req));
2432858Swollman}
2442858Swollman
24544574SphkSYSCTL_NODE(_kern, OID_AUTO, ntp_pll, CTLFLAG_RW, 0, "");
24644574SphkSYSCTL_PROC(_kern_ntp_pll, OID_AUTO, gettime, CTLTYPE_OPAQUE|CTLFLAG_RD,
24712623Sphk	0, sizeof(struct ntptimeval) , ntp_sysctl, "S,ntptimeval", "");
24812279Sphk
24944574Sphk
2502858Swollman/*
2512858Swollman * ntp_adjtime() - NTP daemon application interface
25244574Sphk *
25344574Sphk * See the timex.h header file for synopsis and API description.
2542858Swollman */
25512221Sbde#ifndef _SYS_SYSPROTO_H_
2562858Swollmanstruct ntp_adjtime_args {
25744574Sphk	struct timex *tp;
2582858Swollman};
25912221Sbde#endif
2602858Swollman
2612858Swollmanint
26230994Sphkntp_adjtime(struct proc *p, struct ntp_adjtime_args *uap)
2632858Swollman{
26444574Sphk	struct timex ntv;	/* temporary structure */
26544574Sphk	int modes;		/* mode bits from structure */
26644574Sphk	int s;			/* caller priority */
2672858Swollman	int error;
2682858Swollman
2692858Swollman	error = copyin((caddr_t)uap->tp, (caddr_t)&ntv, sizeof(ntv));
2702858Swollman	if (error)
27144574Sphk		return(error);
2722858Swollman
2732858Swollman	/*
2742858Swollman	 * Update selected clock variables - only the superuser can
2752858Swollman	 * change anything. Note that there is no error checking here on
2762858Swollman	 * the assumption the superuser should know what it is doing.
2772858Swollman	 */
2782858Swollman	modes = ntv.modes;
27944574Sphk	error = suser(p->p_cred->pc_ucred, &p->p_acflag);
28044574Sphk	if (error)
28144574Sphk		return (error);
2822858Swollman	s = splclock();
28344574Sphk	if (modes & MOD_FREQUENCY) {
28444574Sphk		L_LINT(time_freq, ntv.freq / SCALE_PPM);
2852858Swollman#ifdef PPS_SYNC
28644574Sphk		pps_freq = time_freq;
2872858Swollman#endif /* PPS_SYNC */
28844574Sphk	}
2892858Swollman	if (modes & MOD_MAXERROR)
2902858Swollman		time_maxerror = ntv.maxerror;
2912858Swollman	if (modes & MOD_ESTERROR)
2922858Swollman		time_esterror = ntv.esterror;
2932858Swollman	if (modes & MOD_STATUS) {
2942858Swollman		time_status &= STA_RONLY;
2952858Swollman		time_status |= ntv.status & ~STA_RONLY;
2962858Swollman	}
2972858Swollman	if (modes & MOD_TIMECONST)
2982858Swollman		time_constant = ntv.constant;
29944574Sphk	if (modes & MOD_NANO)
30044574Sphk		time_status |= STA_NANO;
30144574Sphk	if (modes & MOD_MICRO)
30244574Sphk		time_status &= ~STA_NANO;
30344574Sphk	if (modes & MOD_CLKB)
30444574Sphk		time_status |= STA_CLK;
30544574Sphk	if (modes & MOD_CLKA)
30644574Sphk		time_status &= ~STA_CLK;
30744574Sphk	if (modes & MOD_OFFSET) {
30844574Sphk		if (time_status & STA_NANO)
30944574Sphk			hardupdate(ntv.offset);
31044574Sphk		else
31144574Sphk			hardupdate(ntv.offset * 1000);
31244574Sphk	}
3132858Swollman
3142858Swollman	/*
3152858Swollman	 * Retrieve all clock variables
3162858Swollman	 */
31744574Sphk	if (time_status & STA_NANO)
31844574Sphk		ntv.offset = L_GINT(time_offset);
3192858Swollman	else
32044574Sphk		ntv.offset = L_GINT(time_offset) / 1000;
32144574Sphk	ntv.freq = L_GINT(time_freq) * SCALE_PPM;
3222858Swollman	ntv.maxerror = time_maxerror;
3232858Swollman	ntv.esterror = time_esterror;
3242858Swollman	ntv.status = time_status;
32544574Sphk	if (ntv.constant < 0)
32644574Sphk		time_constant = 0;
32744574Sphk	else if (ntv.constant > MAXTC)
32844574Sphk		time_constant = MAXTC;
32944574Sphk	else
33044574Sphk		time_constant = ntv.constant;
33144574Sphk	if (time_status & STA_NANO)
33244574Sphk		ntv.precision = time_precision;
33344574Sphk	else
33444574Sphk		ntv.precision = time_precision / 1000;
33544574Sphk	ntv.tolerance = MAXFREQ * SCALE_PPM;
3362858Swollman#ifdef PPS_SYNC
3372858Swollman	ntv.shift = pps_shift;
33844574Sphk	ntv.ppsfreq = L_GINT(pps_freq) * SCALE_PPM;
33944574Sphk	ntv.jitter = pps_jitter;
34044574Sphk	if (time_status & STA_NANO)
34144574Sphk		ntv.jitter = pps_jitter;
34244574Sphk	else
34344574Sphk		ntv.jitter = pps_jitter / 1000;
3442858Swollman	ntv.stabil = pps_stabil;
3452858Swollman	ntv.calcnt = pps_calcnt;
3462858Swollman	ntv.errcnt = pps_errcnt;
3472858Swollman	ntv.jitcnt = pps_jitcnt;
3482858Swollman	ntv.stbcnt = pps_stbcnt;
3492858Swollman#endif /* PPS_SYNC */
35044574Sphk	splx(s);
3512858Swollman
3522858Swollman	error = copyout((caddr_t)&ntv, (caddr_t)uap->tp, sizeof(ntv));
35344574Sphk	if (error)
35444574Sphk		return (error);
35544574Sphk
35644574Sphk	/*
35744574Sphk	 * Status word error decode. See comments in
35844574Sphk	 * ntp_gettime() routine.
35944574Sphk	 */
36044574Sphk	if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) ||
36144574Sphk	    (time_status & (STA_PPSFREQ | STA_PPSTIME) &&
36244574Sphk	    !(time_status & STA_PPSSIGNAL)) ||
36344574Sphk	    (time_status & STA_PPSTIME &&
36444574Sphk	    time_status & STA_PPSJITTER) ||
36544574Sphk	    (time_status & STA_PPSFREQ &&
36644574Sphk	    time_status & (STA_PPSWANDER | STA_PPSERROR)))
36744574Sphk		return (TIME_ERROR);
36844574Sphk	return (time_state);
36944574Sphk}
37044574Sphk
37144574Sphk/*
37244574Sphk * second_overflow() - called after ntp_tick_adjust()
37344574Sphk *
37444574Sphk * This routine is ordinarily called immediately following the above
37544574Sphk * routine ntp_tick_adjust(). While these two routines are normally
37644574Sphk * combined, they are separated here only for the purposes of
37744574Sphk * simulation.
37844574Sphk */
37944574Sphkvoid
38044574Sphkntp_update_second(struct timecounter *tcp)
38144574Sphk{
38244574Sphk	u_int32_t *newsec;
38344666Sphk	l_fp ftemp, time_adj;		/* 32/64-bit temporaries */
38444574Sphk
38544574Sphk	newsec = &tcp->tc_offset_sec;
38644574Sphk	time_maxerror += MAXFREQ / 1000;
38744574Sphk
38844574Sphk	/*
38944574Sphk	 * Leap second processing. If in leap-insert state at
39044574Sphk	 * the end of the day, the system clock is set back one
39144574Sphk	 * second; if in leap-delete state, the system clock is
39244574Sphk	 * set ahead one second. The nano_time() routine or
39344574Sphk	 * external clock driver will insure that reported time
39444574Sphk	 * is always monotonic.
39544574Sphk	 */
39644574Sphk	switch (time_state) {
39744574Sphk
3982858Swollman		/*
39944574Sphk		 * No warning.
4002858Swollman		 */
40144574Sphk		case TIME_OK:
40244574Sphk		if (time_status & STA_INS)
40344574Sphk			time_state = TIME_INS;
40444574Sphk		else if (time_status & STA_DEL)
40544574Sphk			time_state = TIME_DEL;
40644574Sphk		break;
40744574Sphk
40844574Sphk		/*
40944574Sphk		 * Insert second 23:59:60 following second
41044574Sphk		 * 23:59:59.
41144574Sphk		 */
41244574Sphk		case TIME_INS:
41344574Sphk		if (!(time_status & STA_INS))
41444574Sphk			time_state = TIME_OK;
41544574Sphk		else if ((*newsec) % 86400 == 0) {
41644574Sphk			(*newsec)--;
41744574Sphk			time_state = TIME_OOP;
41844574Sphk		}
41944574Sphk		break;
42044574Sphk
42144574Sphk		/*
42244574Sphk		 * Delete second 23:59:59.
42344574Sphk		 */
42444574Sphk		case TIME_DEL:
42544574Sphk		if (!(time_status & STA_DEL))
42644574Sphk			time_state = TIME_OK;
42744574Sphk		else if (((*newsec) + 1) % 86400 == 0) {
42844574Sphk			(*newsec)++;
42944574Sphk			time_state = TIME_WAIT;
43044574Sphk		}
43144574Sphk		break;
43244574Sphk
43344574Sphk		/*
43444574Sphk		 * Insert second in progress.
43544574Sphk		 */
43644574Sphk		case TIME_OOP:
43744574Sphk		time_state = TIME_WAIT;
43844574Sphk		break;
43944574Sphk
44044574Sphk		/*
44144574Sphk		 * Wait for status bits to clear.
44244574Sphk		 */
44344574Sphk		case TIME_WAIT:
44444574Sphk		if (!(time_status & (STA_INS | STA_DEL)))
44544574Sphk			time_state = TIME_OK;
4462858Swollman	}
44744574Sphk
44844574Sphk	/*
44944574Sphk	 * Compute the total time adjustment for the next
45044574Sphk	 * second in ns. The offset is reduced by a factor
45144574Sphk	 * depending on FLL or PLL mode and whether the PPS
45244574Sphk	 * signal is operating. Note that the value is in effect
45344574Sphk	 * scaled by the clock frequency, since the adjustment
45444574Sphk	 * is added at each tick interrupt.
45544574Sphk	 */
45644574Sphk	ftemp = time_offset;
45744574Sphk#ifdef PPS_SYNC
45844574Sphk	if (time_status & STA_PPSTIME && time_status &
45944574Sphk	    STA_PPSSIGNAL)
46044574Sphk		L_RSHIFT(ftemp, PPS_FAVG);
46144574Sphk	else if (time_status & STA_MODE)
46244574Sphk#else
46344574Sphk	if (time_status & STA_MODE)
46444574Sphk#endif /* PPS_SYNC */
46544574Sphk		L_RSHIFT(ftemp, SHIFT_FLL);
46644574Sphk	else
46744574Sphk		L_RSHIFT(ftemp, SHIFT_PLL + time_constant);
46844574Sphk	time_adj = ftemp;
46944574Sphk	L_SUB(time_offset, ftemp);
47044574Sphk	L_ADD(time_adj, time_freq);
47144574Sphk	tcp->tc_adjustment = time_adj;
47244574Sphk#ifdef PPS_SYNC
47344574Sphk	if (pps_valid > 0)
47444574Sphk		pps_valid--;
47544574Sphk	else
47644574Sphk		time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER |
47744574Sphk		    STA_PPSWANDER | STA_PPSERROR);
47844574Sphk#endif /* PPS_SYNC */
4792858Swollman}
4802858Swollman
48144574Sphk/*
48244574Sphk * ntp_init() - initialize variables and structures
48344574Sphk *
48444574Sphk * This routine must be called after the kernel variables hz and tick
48544574Sphk * are set or changed and before the next tick interrupt. In this
48644574Sphk * particular implementation, these values are assumed set elsewhere in
48744574Sphk * the kernel. The design allows the clock frequency and tick interval
48844574Sphk * to be changed while the system is running. So, this routine should
48944574Sphk * probably be integrated with the code that does that.
49044574Sphk */
49144574Sphkstatic void
49244574Sphkntp_init()
49344574Sphk{
49444574Sphk
49544574Sphk	/*
49644574Sphk	 * The following variable must be initialized any time the
49744574Sphk	 * kernel variable hz is changed.
49844574Sphk	 */
49944574Sphk	time_tick = NANOSECOND / hz;
50044574Sphk
50144574Sphk	/*
50244574Sphk	 * The following variables are initialized only at startup. Only
50344574Sphk	 * those structures not cleared by the compiler need to be
50444574Sphk	 * initialized, and these only in the simulator. In the actual
50544574Sphk	 * kernel, any nonzero values here will quickly evaporate.
50644574Sphk	 */
50744574Sphk	L_CLR(time_offset);
50844574Sphk	L_CLR(time_freq);
50932513Sphk#ifdef PPS_SYNC
51044574Sphk	pps_filt.sec = pps_filt.nsec = pps_filt.count = 0;
51144574Sphk	pps_tf[0] = pps_tf[1] = pps_tf[2] = pps_filt;
51244574Sphk	L_CLR(pps_freq);
51344574Sphk#endif /* PPS_SYNC */
51444574Sphk}
5152858Swollman
51644574SphkSYSINIT(ntpclocks, SI_SUB_CLOCKS, SI_ORDER_FIRST, ntp_init, NULL)
51732513Sphk
51844574Sphk/*
51944574Sphk * hardupdate() - local clock update
52044574Sphk *
52144574Sphk * This routine is called by ntp_adjtime() to update the local clock
52244574Sphk * phase and frequency. The implementation is of an adaptive-parameter,
52344574Sphk * hybrid phase/frequency-lock loop (PLL/FLL). The routine computes new
52444574Sphk * time and frequency offset estimates for each call. If the kernel PPS
52544574Sphk * discipline code is configured (PPS_SYNC), the PPS signal itself
52644574Sphk * determines the new time offset, instead of the calling argument.
52744574Sphk * Presumably, calls to ntp_adjtime() occur only when the caller
52844574Sphk * believes the local clock is valid within some bound (+-128 ms with
52944574Sphk * NTP). If the caller's time is far different than the PPS time, an
53044574Sphk * argument will ensue, and it's not clear who will lose.
53144574Sphk *
53244574Sphk * For uncompensated quartz crystal oscillators and nominal update
53344574Sphk * intervals less than 256 s, operation should be in phase-lock mode,
53444574Sphk * where the loop is disciplined to phase. For update intervals greater
53544574Sphk * than 1024 s, operation should be in frequency-lock mode, where the
53644574Sphk * loop is disciplined to frequency. Between 256 s and 1024 s, the mode
53744574Sphk * is selected by the STA_MODE status bit.
53844574Sphk */
53944574Sphkstatic void
54044574Sphkhardupdate(offset)
54144574Sphk	long offset;		/* clock offset (ns) */
54244574Sphk{
54344574Sphk	long ltemp, mtemp;
54444574Sphk	l_fp ftemp;
54532513Sphk
54644574Sphk	/*
54744574Sphk	 * Select how the phase is to be controlled and from which
54844574Sphk	 * source. If the PPS signal is present and enabled to
54944574Sphk	 * discipline the time, the PPS offset is used; otherwise, the
55044574Sphk	 * argument offset is used.
55144574Sphk	 */
55244574Sphk	ltemp = offset;
55344574Sphk	if (ltemp > MAXPHASE)
55444574Sphk		ltemp = MAXPHASE;
55544574Sphk	else if (ltemp < -MAXPHASE)
55644574Sphk		ltemp = -MAXPHASE;
55744574Sphk	if (!(time_status & STA_PPSTIME && time_status & STA_PPSSIGNAL))
55844574Sphk		L_LINT(time_offset, ltemp);
55932513Sphk
56044574Sphk	/*
56144574Sphk	 * Select how the frequency is to be controlled and in which
56244574Sphk	 * mode (PLL or FLL). If the PPS signal is present and enabled
56344574Sphk	 * to discipline the frequency, the PPS frequency is used;
56444574Sphk	 * otherwise, the argument offset is used to compute it.
56544574Sphk	 */
56644574Sphk	if (time_status & STA_PPSFREQ && time_status & STA_PPSSIGNAL) {
56744574Sphk		time_reftime = time_second;
56844574Sphk		return;
56944574Sphk	}
57044574Sphk	if (time_status & STA_FREQHOLD || time_reftime == 0)
57144574Sphk		time_reftime = time_second;
57244574Sphk	mtemp = time_second - time_reftime;
57344574Sphk	if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)
57444574Sphk	    ) {
57544574Sphk		L_LINT(ftemp, (ltemp << 4) / mtemp);
57644574Sphk		L_RSHIFT(ftemp, SHIFT_FLL + 4);
57744574Sphk		L_ADD(time_freq, ftemp);
57844574Sphk		time_status |= STA_MODE;
57944574Sphk	} else {
58044574Sphk		L_LINT(ftemp, ltemp);
58144574Sphk		L_RSHIFT(ftemp, (SHIFT_PLL + 2 + time_constant) << 1);
58244574Sphk		L_MPY(ftemp, mtemp);
58344574Sphk		L_ADD(time_freq, ftemp);
58444574Sphk		time_status &= ~STA_MODE;
58544574Sphk	}
58644574Sphk	time_reftime = time_second;
58744574Sphk	if (L_GINT(time_freq) > MAXFREQ)
58844574Sphk		L_LINT(time_freq, MAXFREQ);
58944574Sphk	else if (L_GINT(time_freq) < -MAXFREQ)
59044574Sphk		L_LINT(time_freq, -MAXFREQ);
59144574Sphk}
59244574Sphk
59344574Sphk#ifdef PPS_SYNC
59432513Sphk/*
59532513Sphk * hardpps() - discipline CPU clock oscillator to external PPS signal
59632513Sphk *
59732513Sphk * This routine is called at each PPS interrupt in order to discipline
59832513Sphk * the CPU clock oscillator to the PPS signal. It measures the PPS phase
59932513Sphk * and leaves it in a handy spot for the hardclock() routine. It
60032513Sphk * integrates successive PPS phase differences and calculates the
60132513Sphk * frequency offset. This is used in hardclock() to discipline the CPU
60244574Sphk * clock oscillator so that the intrinsic frequency error is cancelled
60344574Sphk * out. The code requires the caller to capture the time and
60444574Sphk * architecture-dependent hardware counter values in nanoseconds at the
60544574Sphk * on-time PPS signal transition.
60632513Sphk *
60744574Sphk * Note that, on some Unix systems this routine runs at an interrupt
60832513Sphk * priority level higher than the timer interrupt routine hardclock().
60932513Sphk * Therefore, the variables used are distinct from the hardclock()
61044574Sphk * variables, except for the actual time and frequency variables, which
61144574Sphk * are determined by this routine and updated atomically.
61232513Sphk */
61332513Sphkvoid
61444574Sphkhardpps(tsp, nsec)
61544574Sphk	struct timespec *tsp;	/* time at PPS */
61644574Sphk	long nsec;		/* hardware counter at PPS */
61732513Sphk{
61844574Sphk	long u_sec, u_nsec, v_nsec; /* temps */
61944574Sphk	l_fp ftemp;
62032513Sphk
62132513Sphk	/*
62244574Sphk	 * The signal is first processed by a frequency discriminator
62344574Sphk	 * which rejects noise and input signals with frequencies
62444574Sphk	 * outside the range 1 +-MAXFREQ PPS. If two hits occur in the
62544574Sphk	 * same second, we ignore the later hit; if not and a hit occurs
62644574Sphk	 * outside the range gate, keep the later hit but do not
62744574Sphk	 * process it.
62832513Sphk	 */
62944574Sphk	time_status |= STA_PPSSIGNAL | STA_PPSJITTER;
63044574Sphk	time_status &= ~(STA_PPSWANDER | STA_PPSERROR);
63144574Sphk	pps_valid = PPS_VALID;
63244574Sphk	u_sec = tsp->tv_sec;
63344574Sphk	u_nsec = tsp->tv_nsec;
63444574Sphk	if (u_nsec >= (NANOSECOND >> 1)) {
63544574Sphk		u_nsec -= NANOSECOND;
63644574Sphk		u_sec++;
63744574Sphk	}
63844574Sphk	v_nsec = u_nsec - pps_tf[0].nsec;
63944574Sphk	if (u_sec == pps_tf[0].sec && v_nsec < -MAXFREQ) {
64044574Sphk		return;
64144574Sphk	}
64244574Sphk	pps_tf[2] = pps_tf[1];
64344574Sphk	pps_tf[1] = pps_tf[0];
64444574Sphk	pps_tf[0].sec = u_sec;
64544574Sphk	pps_tf[0].nsec = u_nsec;
64632513Sphk
64732513Sphk	/*
64844574Sphk	 * Compute the difference between the current and previous
64944574Sphk	 * counter values. If the difference exceeds 0.5 s, assume it
65044574Sphk	 * has wrapped around, so correct 1.0 s. If the result exceeds
65144574Sphk	 * the tick interval, the sample point has crossed a tick
65244574Sphk	 * boundary during the last second, so correct the tick. Very
65344574Sphk	 * intricate.
65444574Sphk	 */
65544666Sphk	u_nsec = nsec;
65644574Sphk	if (u_nsec > (NANOSECOND >> 1))
65744574Sphk		u_nsec -= NANOSECOND;
65844574Sphk	else if (u_nsec < -(NANOSECOND >> 1))
65944574Sphk		u_nsec += NANOSECOND;
66044666Sphk#if 0
66144574Sphk	if (u_nsec > (time_tick >> 1))
66244574Sphk		u_nsec -= time_tick;
66344574Sphk	else if (u_nsec < -(time_tick >> 1))
66444574Sphk		u_nsec += time_tick;
66544666Sphk#endif
66644574Sphk	pps_tf[0].count = pps_tf[1].count + u_nsec;
66744574Sphk	if (v_nsec > MAXFREQ) {
66844574Sphk		return;
66944574Sphk	}
67044574Sphk	time_status &= ~STA_PPSJITTER;
67144574Sphk
67244574Sphk	/*
67344574Sphk	 * A three-stage median filter is used to help denoise the PPS
67432513Sphk	 * time. The median sample becomes the time offset estimate; the
67532513Sphk	 * difference between the other two samples becomes the time
67632513Sphk	 * dispersion (jitter) estimate.
67732513Sphk	 */
67844574Sphk	if (pps_tf[0].nsec > pps_tf[1].nsec) {
67944574Sphk		if (pps_tf[1].nsec > pps_tf[2].nsec) {
68044574Sphk			pps_filt = pps_tf[1];	/* 0 1 2 */
68144574Sphk			u_nsec = pps_tf[0].nsec - pps_tf[2].nsec;
68244574Sphk		} else if (pps_tf[2].nsec > pps_tf[0].nsec) {
68344574Sphk			pps_filt = pps_tf[0];	/* 2 0 1 */
68444574Sphk			u_nsec = pps_tf[2].nsec - pps_tf[1].nsec;
68544574Sphk		} else {
68644574Sphk			pps_filt = pps_tf[2];	/* 0 2 1 */
68744574Sphk			u_nsec = pps_tf[0].nsec - pps_tf[1].nsec;
68844574Sphk		}
68944574Sphk	} else {
69044574Sphk		if (pps_tf[1].nsec < pps_tf[2].nsec) {
69144574Sphk			pps_filt = pps_tf[1];	/* 2 1 0 */
69244574Sphk			u_nsec = pps_tf[2].nsec - pps_tf[0].nsec;
69344574Sphk		} else  if (pps_tf[2].nsec < pps_tf[0].nsec) {
69444574Sphk			pps_filt = pps_tf[0];	/* 1 0 2 */
69544574Sphk			u_nsec = pps_tf[1].nsec - pps_tf[2].nsec;
69644574Sphk		} else {
69744574Sphk			pps_filt = pps_tf[2];	/* 1 2 0 */
69844574Sphk			u_nsec = pps_tf[1].nsec - pps_tf[0].nsec;
69944574Sphk		}
70044574Sphk	}
70132513Sphk
70232513Sphk	/*
70344574Sphk	 * Nominal jitter is due to PPS signal noise and  interrupt
70444574Sphk	 * latency. If it exceeds the jitter limit, the sample is
70544574Sphk	 * discarded. otherwise, if so enabled, the time offset is
70644574Sphk	 * updated. The offsets are accumulated over the phase averaging
70744574Sphk	 * interval to improve accuracy. The jitter is averaged only for
70844574Sphk	 * performance monitoring. We can tolerate a modest loss of data
70944574Sphk	 * here without degrading time accuracy.
71032513Sphk	 */
71144574Sphk	if (u_nsec > MAXTIME) {
71244574Sphk		time_status |= STA_PPSJITTER;
71344574Sphk		pps_jitcnt++;
71444574Sphk	} else if (time_status & STA_PPSTIME) {
71544574Sphk		pps_offacc -= pps_filt.nsec;
71644574Sphk		pps_offcnt++;
71732513Sphk	}
71844574Sphk	if (pps_offcnt >= (1 << PPS_PAVG)) {
71944574Sphk		if (time_status & STA_PPSTIME) {
72044574Sphk			L_LINT(time_offset, pps_offacc);
72144574Sphk			L_RSHIFT(time_offset, PPS_PAVG);
72244574Sphk		}
72344574Sphk		pps_offacc = 0;
72444574Sphk		pps_offcnt = 0;
72532513Sphk
72644574Sphk	}
72744574Sphk	pps_jitter += (u_nsec - pps_jitter) >> PPS_FAVG;
72844574Sphk	u_sec = pps_tf[0].sec - pps_lastsec;
72944574Sphk	if (u_sec < (1 << pps_shift))
73044574Sphk		return;
73144574Sphk
73232513Sphk	/*
73344574Sphk	 * At the end of the calibration interval the difference between
73444574Sphk	 * the first and last counter values becomes the scaled
73544574Sphk	 * frequency. It will later be divided by the length of the
73644574Sphk	 * interval to determine the frequency update. If the frequency
73744574Sphk	 * exceeds a sanity threshold, or if the actual calibration
73844574Sphk	 * interval is not equal to the expected length, the data are
73944574Sphk	 * discarded. We can tolerate a modest loss of data here without
74044574Sphk	 * degrading frequency ccuracy.
74132513Sphk	 */
74244574Sphk	pps_calcnt++;
74344574Sphk	v_nsec = -pps_filt.count;
74444574Sphk	pps_lastsec = pps_tf[0].sec;
74544574Sphk	pps_tf[0].count = 0;
74644574Sphk	u_nsec = MAXFREQ << pps_shift;
74744574Sphk	if (v_nsec > u_nsec || v_nsec < -u_nsec || u_sec != (1 <<
74844574Sphk	    pps_shift)) {
74944574Sphk		time_status |= STA_PPSERROR;
75032513Sphk		pps_errcnt++;
75132513Sphk		return;
75232513Sphk	}
75332513Sphk
75432513Sphk	/*
75544574Sphk	 * If the actual calibration interval is not equal to the
75644574Sphk	 * expected length, the data are discarded. If the wander is
75744574Sphk	 * less than the wander threshold for four consecutive
75844574Sphk	 * intervals, the interval is doubled; if it is greater than the
75944574Sphk	 * threshold for four consecutive intervals, the interval is
76044574Sphk	 * halved. The scaled frequency offset is converted to frequency
76144574Sphk	 * offset. The stability metric is calculated as the average of
76244574Sphk	 * recent frequency changes, but is used only for performance
76344574Sphk	 * monitoring.
76432513Sphk	 */
76544574Sphk	L_LINT(ftemp, v_nsec);
76644574Sphk	L_RSHIFT(ftemp, pps_shift);
76744574Sphk	L_SUB(ftemp, pps_freq);
76844574Sphk	u_nsec = L_GINT(ftemp);
76944574Sphk	if (u_nsec > MAXWANDER) {
77044574Sphk		L_LINT(ftemp, MAXWANDER);
77144574Sphk		pps_intcnt--;
77244574Sphk		time_status |= STA_PPSWANDER;
77332513Sphk		pps_stbcnt++;
77444574Sphk	} else if (u_nsec < -MAXWANDER) {
77544574Sphk		L_LINT(ftemp, -MAXWANDER);
77644574Sphk		pps_intcnt--;
77732513Sphk		time_status |= STA_PPSWANDER;
77844574Sphk		pps_stbcnt++;
77944574Sphk	} else {
78044574Sphk		pps_intcnt++;
78132513Sphk	}
78244574Sphk	if (pps_intcnt >= 4) {
78344574Sphk		pps_intcnt = 4;
78444574Sphk		if (pps_shift < PPS_FAVGMAX) {
78544574Sphk			pps_shift++;
78644574Sphk			pps_intcnt = 0;
78732513Sphk		}
78844574Sphk	} else if (pps_intcnt <= -4) {
78944574Sphk		pps_intcnt = -4;
79044574Sphk		if (pps_shift > PPS_FAVG) {
79144574Sphk			pps_shift--;
79244574Sphk			pps_intcnt = 0;
79344574Sphk		}
79432513Sphk	}
79544574Sphk	if (u_nsec < 0)
79644574Sphk		u_nsec = -u_nsec;
79744574Sphk	pps_stabil += (u_nsec * SCALE_PPM - pps_stabil) >> PPS_FAVG;
79832513Sphk
79932513Sphk	/*
80044574Sphk	 * The frequency offset is averaged into the PPS frequency. If
80144574Sphk	 * enabled, the system clock frequency is updated as well.
80232513Sphk	 */
80344574Sphk	L_RSHIFT(ftemp, PPS_FAVG);
80444574Sphk	L_ADD(pps_freq, ftemp);
80544574Sphk	u_nsec = L_GINT(pps_freq);
80644574Sphk	if (u_nsec > MAXFREQ)
80744574Sphk		L_LINT(pps_freq, MAXFREQ);
80844574Sphk	else if (u_nsec < -MAXFREQ)
80944574Sphk		L_LINT(pps_freq, -MAXFREQ);
81044574Sphk	if (time_status & STA_PPSFREQ)
81144574Sphk		time_freq = pps_freq;
81232513Sphk}
81332513Sphk#endif /* PPS_SYNC */
814