33 #include <sys/cdefs.h>
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/sysproto.h>
41 #include <sys/eventhandler.h>
42 #include <sys/kernel.h>
46 #include <sys/mutex.h>
48 #include <sys/timex.h>
49 #include <sys/timetc.h>
50 #include <sys/timepps.h>
51 #include <sys/syscallsubr.h>
52 #include <sys/sysctl.h>
55 FEATURE(pps_sync,
"Support usage of external PPS signal by kernel PLL");
62 #define L_ADD(v, u) ((v) += (u))
63 #define L_SUB(v, u) ((v) -= (u))
64 #define L_ADDHI(v, a) ((v) += (int64_t)(a) << 32)
65 #define L_NEG(v) ((v) = -(v))
66 #define L_RSHIFT(v, n) \
69 (v) = -(-(v) >> (n)); \
73 #define L_MPY(v, a) ((v) *= (a))
74 #define L_CLR(v) ((v) = 0)
75 #define L_ISNEG(v) ((v) < 0)
76 #define L_LINT(v, a) ((v) = (int64_t)(a) << 32)
77 #define L_GINT(v) ((v) < 0 ? -(-(v) >> 32) : (v) >> 32)
173 #define PPS_FAVGDEF 8
174 #define PPS_FAVGMAX 15
176 #define PPS_VALID 120
177 #define PPS_MAXWANDER 100000
178 #define PPS_POPCORN 2
180 static struct timespec pps_tf[3];
181 static l_fp pps_freq;
182 static long pps_fcount;
183 static long pps_jitter;
184 static long pps_stabil;
185 static long pps_lastsec;
186 static int pps_valid;
187 static int pps_shift = PPS_FAVG;
188 static int pps_shiftmax = PPS_FAVGDEF;
189 static int pps_intcnt;
194 static long pps_calcnt;
195 static long pps_jitcnt;
196 static long pps_stbcnt;
197 static long pps_errcnt;
253 ntvp->time.tv_sec = atv.tv_sec;
254 ntvp->time.tv_nsec = atv.tv_nsec;
261 ntvp->time_state = TIME_ERROR;
270 #ifndef _SYS_SYSPROTO_H_
279 struct ntptimeval ntv;
285 td->td_retval[0] = ntv.time_state;
286 return (copyout(&ntv, uap->
ntvp,
sizeof(ntv)));
292 struct ntptimeval ntv;
299 SYSCTL_NODE(_kern, OID_AUTO, ntp_pll, CTLFLAG_RW, 0,
"");
301 0,
sizeof(
struct ntptimeval) ,
ntp_sysctl,
"S,ntptimeval",
"");
304 SYSCTL_INT(_kern_ntp_pll, OID_AUTO, pps_shiftmax, CTLFLAG_RW, &pps_shiftmax, 0,
"");
305 SYSCTL_INT(_kern_ntp_pll, OID_AUTO, pps_shift, CTLFLAG_RW, &pps_shift, 0,
"");
309 SYSCTL_OPAQUE(_kern_ntp_pll, OID_AUTO, pps_freq, CTLFLAG_RD, &pps_freq,
sizeof(pps_freq),
"I",
"");
320 #ifndef _SYS_SYSPROTO_H_
335 error = copyin((caddr_t)uap->
tp, (caddr_t)&ntv,
sizeof(ntv));
355 if (modes & MOD_MAXERROR)
357 if (modes & MOD_ESTERROR)
359 if (modes & MOD_STATUS) {
360 if (
time_status & STA_PLL && !(ntv.status & STA_PLL)) {
364 pps_shift = PPS_FAVG;
370 if (modes & MOD_TIMECONST) {
371 if (ntv.constant < 0)
373 else if (ntv.constant > MAXTC)
378 if (modes & MOD_TAI) {
379 if (ntv.constant > 0)
383 if (modes & MOD_PPSMAX) {
384 if (ntv.shift < PPS_FAVG)
385 pps_shiftmax = PPS_FAVG;
386 else if (ntv.shift > PPS_FAVGMAX)
387 pps_shiftmax = PPS_FAVGMAX;
389 pps_shiftmax = ntv.shift;
392 if (modes & MOD_NANO)
394 if (modes & MOD_MICRO)
396 if (modes & MOD_CLKB)
398 if (modes & MOD_CLKA)
400 if (modes & MOD_FREQUENCY) {
401 freq = (ntv.freq * 1000LL) >> 16;
404 else if (freq < -MAXFREQ)
417 if (modes & MOD_OFFSET) {
441 ntv.tolerance = MAXFREQ * SCALE_PPM;
443 ntv.shift = pps_shift;
444 ntv.ppsfreq =
L_GINT((pps_freq / 1000LL) << 16);
446 ntv.jitter = pps_jitter;
448 ntv.jitter = pps_jitter / 1000;
449 ntv.stabil = pps_stabil;
450 ntv.calcnt = pps_calcnt;
451 ntv.errcnt = pps_errcnt;
452 ntv.jitcnt = pps_jitcnt;
453 ntv.stbcnt = pps_stbcnt;
457 error = copyout((caddr_t)&ntv, (caddr_t)uap->
tp,
sizeof(ntv));
462 td->td_retval[0] = TIME_ERROR;
521 else if ((*newsec) % 86400 == 0) {
534 else if (((*newsec) + 1) % 86400 == 0) {
595 L_LINT(ftemp, tickrate * 1000);
631 pps_tf[0].tv_sec = pps_tf[0].tv_nsec = 0;
632 pps_tf[1].tv_sec = pps_tf[1].tv_nsec = 0;
633 pps_tf[2].tv_sec = pps_tf[2].tv_nsec = 0;
679 if (offset > MAXPHASE)
681 else if (offset < -MAXPHASE)
706 if (mtemp >= MINSEC && (
time_status & STA_FLL || mtemp >
743 struct timespec *tsp;
746 long u_sec, u_nsec, v_nsec;
761 pps_valid = PPS_VALID;
763 u_nsec = tsp->tv_nsec;
764 if (u_nsec >= (NANOSECOND >> 1)) {
765 u_nsec -= NANOSECOND;
768 v_nsec = u_nsec - pps_tf[0].tv_nsec;
769 if (u_sec == pps_tf[0].tv_sec && v_nsec < NANOSECOND -
772 pps_tf[2] = pps_tf[1];
773 pps_tf[1] = pps_tf[0];
774 pps_tf[0].tv_sec = u_sec;
775 pps_tf[0].tv_nsec = u_nsec;
786 if (u_nsec > (NANOSECOND >> 1))
787 u_nsec -= NANOSECOND;
788 else if (u_nsec < -(NANOSECOND >> 1))
789 u_nsec += NANOSECOND;
790 pps_fcount += u_nsec;
791 if (v_nsec > MAXFREQ || v_nsec < -MAXFREQ)
801 if (pps_tf[0].tv_nsec > pps_tf[1].tv_nsec) {
802 if (pps_tf[1].tv_nsec > pps_tf[2].tv_nsec) {
803 v_nsec = pps_tf[1].tv_nsec;
804 u_nsec = pps_tf[0].tv_nsec - pps_tf[2].tv_nsec;
805 }
else if (pps_tf[2].tv_nsec > pps_tf[0].tv_nsec) {
806 v_nsec = pps_tf[0].tv_nsec;
807 u_nsec = pps_tf[2].tv_nsec - pps_tf[1].tv_nsec;
809 v_nsec = pps_tf[2].tv_nsec;
810 u_nsec = pps_tf[0].tv_nsec - pps_tf[1].tv_nsec;
813 if (pps_tf[1].tv_nsec < pps_tf[2].tv_nsec) {
814 v_nsec = pps_tf[1].tv_nsec;
815 u_nsec = pps_tf[2].tv_nsec - pps_tf[0].tv_nsec;
816 }
else if (pps_tf[2].tv_nsec < pps_tf[0].tv_nsec) {
817 v_nsec = pps_tf[0].tv_nsec;
818 u_nsec = pps_tf[1].tv_nsec - pps_tf[2].tv_nsec;
820 v_nsec = pps_tf[2].tv_nsec;
821 u_nsec = pps_tf[1].tv_nsec - pps_tf[0].tv_nsec;
832 if (u_nsec > (pps_jitter << PPS_POPCORN)) {
839 pps_jitter += (u_nsec - pps_jitter) >> PPS_FAVG;
840 u_sec = pps_tf[0].tv_sec - pps_lastsec;
841 if (u_sec < (1 << pps_shift))
855 v_nsec = -pps_fcount;
856 pps_lastsec = pps_tf[0].tv_sec;
858 u_nsec = MAXFREQ << pps_shift;
859 if (v_nsec > u_nsec || v_nsec < -u_nsec || u_sec != (1 <<
879 L_SUB(ftemp, pps_freq);
881 if (u_nsec > PPS_MAXWANDER) {
882 L_LINT(ftemp, PPS_MAXWANDER);
886 }
else if (u_nsec < -PPS_MAXWANDER) {
887 L_LINT(ftemp, -PPS_MAXWANDER);
894 if (pps_intcnt >= 4) {
896 if (pps_shift < pps_shiftmax) {
900 }
else if (pps_intcnt <= -4 || pps_shift > pps_shiftmax) {
902 if (pps_shift > PPS_FAVG) {
909 pps_stabil += (u_nsec * SCALE_PPM - pps_stabil) >> PPS_FAVG;
916 L_ADD(pps_freq, ftemp);
917 u_nsec =
L_GINT(pps_freq);
918 if (u_nsec > MAXFREQ)
919 L_LINT(pps_freq, MAXFREQ);
920 else if (u_nsec < -MAXFREQ)
921 L_LINT(pps_freq, -MAXFREQ);
927 #ifndef _SYS_SYSPROTO_H_
937 struct timeval delta, olddelta, *deltap;
941 error = copyin(uap->
delta, &delta,
sizeof(delta));
949 error = copyout(&olddelta, uap->
olddelta,
sizeof(olddelta));
954 kern_adjtime(
struct thread *td,
struct timeval *delta,
struct timeval *olddelta)
963 if (atv.tv_usec < 0) {
964 atv.tv_usec += 1000000;
993 if (resettodr_period > 0)
1015 if (error || !req->newptr)
1017 if (resettodr_period == 0)
1025 SYSCTL_PROC(_machdep, OID_AUTO, rtc_save_period, CTLTYPE_INT|CTLFLAG_RW,
1027 "Save system time to RTC with this period (in seconds)");
1028 TUNABLE_INT(
"machdep.rtc_save_period", &resettodr_period);
1035 SHUTDOWN_PRI_FIRST);
1037 if (resettodr_period == 0)
volatile time_t time_second
static long time_constant
int sys_ntp_adjtime(struct thread *td, struct ntp_adjtime_args *uap)
int kern_adjtime(struct thread *td, struct timeval *delta, struct timeval *olddelta)
static void ntp_init(void)
TUNABLE_INT("machdep.rtc_save_period",&resettodr_period)
static int ntp_sysctl(SYSCTL_HANDLER_ARGS)
SYSCTL_INT(_debug, OID_AUTO, boothowto, CTLFLAG_RD,&boothowto, 0,"Boot control flags, passed from loader")
int callout_schedule(struct callout *c, int to_ticks)
static long time_esterror
SYSINIT(ntpclocks, SI_SUB_CLOCKS, SI_ORDER_MIDDLE, ntp_init, NULL)
SYSCTL_PROC(_kern_ntp_pll, OID_AUTO, gettime, CTLTYPE_OPAQUE|CTLFLAG_RD, 0, sizeof(struct ntptimeval), ntp_sysctl,"S,ntptimeval","")
static void hardupdate(long offset)
static long time_precision
int priv_check(struct thread *td, int priv)
static int resettodr_period
void ntp_update_second(int64_t *adjustment, time_t *newsec)
static void periodic_resettodr(void *arg __unused)
static struct callout resettodr_callout
int sysctl_handle_opaque(SYSCTL_HANDLER_ARGS)
int sysctl_handle_int(SYSCTL_HANDLER_ARGS)
struct timeval * olddelta
void nanotime(struct timespec *tsp)
static long time_maxerror
SYSCTL_LONG(_hw, OID_AUTO, availpages, CTLFLAG_RD,&physmem, 0,"")
SYSCTL_OPAQUE(_vfs_cache, OID_AUTO, nchstats, CTLFLAG_RD|CTLFLAG_MPSAFE,&nchstats, sizeof(nchstats),"LU","VFS cache effectiveness statistics")
static int ntp_is_time_error(void)
static void shutdown_resettodr(void *arg __unused, int howto __unused)
SYSCTL_NODE(_kern, OID_AUTO, ntp_pll, CTLFLAG_RW, 0,"")
void callout_init(struct callout *c, int mpsafe)
static void ntp_gettime1(struct ntptimeval *ntvp)
static int sysctl_resettodr_period(SYSCTL_HANDLER_ARGS)
FEATURE(kdtrace_hooks,"Kernel DTrace hooks which are required to load DTrace kernel modules")
static void start_periodic_resettodr(void *arg __unused)
int sys_ntp_gettime(struct thread *td, struct ntp_gettime_args *uap)
static int64_t time_adjtime
int sys_adjtime(struct thread *td, struct adjtime_args *uap)