40#include <sys/sysproto.h>
41#include <sys/eventhandler.h>
42#include <sys/kernel.h>
49#include <sys/timetc.h>
50#include <sys/timepps.h>
51#include <sys/syscallsubr.h>
52#include <sys/sysctl.h>
55FEATURE(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)
168#define NTP_LOCK() mtx_lock_spin(&ntp_lock)
169#define NTP_UNLOCK() mtx_unlock_spin(&ntp_lock)
170#define NTP_ASSERT_LOCKED() mtx_assert(&ntp_lock, MA_OWNED)
181#define PPS_FAVGMAX 15
184#define PPS_MAXWANDER 100000
187static struct timespec pps_tf[3];
189static long pps_fcount;
190static long pps_jitter;
191static long pps_stabil;
192static long pps_lastsec;
194static int pps_shift = PPS_FAVG;
195static int pps_shiftmax = PPS_FAVGDEF;
196static int pps_intcnt;
201static long pps_calcnt;
202static long pps_jitcnt;
203static long pps_stbcnt;
204static long pps_errcnt;
226 if ((tsl & (STA_UNSYNC | STA_CLOCKERR)) ||
232 (tsl & (STA_PPSFREQ | STA_PPSTIME) &&
233 !(tsl & STA_PPSSIGNAL)) ||
238 (tsl & STA_PPSTIME && tsl & STA_PPSJITTER) ||
244 (tsl & STA_PPSFREQ &&
245 tsl & (STA_PPSWANDER | STA_PPSERROR)))
259 ntvp->time.tv_sec = atv.tv_sec;
260 ntvp->time.tv_nsec = atv.tv_nsec;
267 ntvp->time_state = TIME_ERROR;
276#ifndef _SYS_SYSPROTO_H_
285 struct ntptimeval ntv;
287 memset(&ntv, 0,
sizeof(ntv));
293 td->td_retval[0] = ntv.time_state;
294 return (copyout(&ntv, uap->
ntvp,
sizeof(ntv)));
300 struct ntptimeval ntv;
302 memset(&ntv, 0,
sizeof(ntv));
311SYSCTL_NODE(_kern, OID_AUTO, ntp_pll, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
314 CTLFLAG_MPSAFE, 0,
sizeof(
struct ntptimeval) ,
ntp_sysctl,
"S,ntptimeval",
318SYSCTL_INT(_kern_ntp_pll, OID_AUTO, pps_shiftmax, CTLFLAG_RW,
319 &pps_shiftmax, 0,
"Max interval duration (sec) (shift)");
320SYSCTL_INT(_kern_ntp_pll, OID_AUTO, pps_shift, CTLFLAG_RW,
321 &pps_shift, 0,
"Interval duration (sec) (shift)");
325SYSCTL_S64(_kern_ntp_pll, OID_AUTO, pps_freq, CTLFLAG_RD | CTLFLAG_MPSAFE,
327 "Scaled frequency offset (ns/sec)");
328SYSCTL_S64(_kern_ntp_pll, OID_AUTO,
time_freq, CTLFLAG_RD | CTLFLAG_MPSAFE,
330 "Frequency offset (ns/sec)");
363 if (modes & MOD_MAXERROR)
365 if (modes & MOD_ESTERROR)
367 if (modes & MOD_STATUS) {
368 if (
time_status & STA_PLL && !(ntv->status & STA_PLL)) {
372 pps_shift = PPS_FAVG;
378 if (modes & MOD_TIMECONST) {
379 if (ntv->constant < 0)
381 else if (ntv->constant > MAXTC)
386 if (modes & MOD_TAI) {
387 if (ntv->constant > 0)
391 if (modes & MOD_PPSMAX) {
392 if (ntv->shift < PPS_FAVG)
393 pps_shiftmax = PPS_FAVG;
394 else if (ntv->shift > PPS_FAVGMAX)
395 pps_shiftmax = PPS_FAVGMAX;
397 pps_shiftmax = ntv->shift;
400 if (modes & MOD_NANO)
402 if (modes & MOD_MICRO)
404 if (modes & MOD_CLKB)
406 if (modes & MOD_CLKA)
408 if (modes & MOD_FREQUENCY) {
409 freq = (ntv->freq * 1000LL) >> 16;
412 else if (freq < -MAXFREQ)
419 time_freq = ntv->freq * 1000LL * 65536LL;
425 if (modes & MOD_OFFSET) {
449 ntv->tolerance = MAXFREQ * SCALE_PPM;
451 ntv->shift = pps_shift;
452 ntv->ppsfreq =
L_GINT((pps_freq / 1000LL) << 16);
454 ntv->jitter = pps_jitter;
456 ntv->jitter = pps_jitter / 1000;
457 ntv->stabil = pps_stabil;
458 ntv->calcnt = pps_calcnt;
459 ntv->errcnt = pps_errcnt;
460 ntv->jitcnt = pps_jitcnt;
461 ntv->stbcnt = pps_stbcnt;
470#ifndef _SYS_SYSPROTO_H_
482 error = copyin(uap->
tp, &ntv,
sizeof(ntv));
486 error = copyout(&ntv, uap->
tp,
sizeof(ntv));
488 td->td_retval[0] = retval;
545 else if ((*newsec) % 86400 == 0) {
558 else if (((*newsec) + 1) % 86400 == 0) {
619 L_LINT(ftemp, tickrate * 1000);
674 if (offset > MAXPHASE)
676 else if (offset < -MAXPHASE)
701 if (mtemp >= MINSEC && (
time_status & STA_FLL || mtemp >
740hardpps(
struct timespec *tsp,
long nsec)
742 long u_sec, u_nsec, v_nsec;
759 pps_valid = PPS_VALID;
761 u_nsec = tsp->tv_nsec;
762 if (u_nsec >= (NANOSECOND >> 1)) {
763 u_nsec -= NANOSECOND;
766 v_nsec = u_nsec - pps_tf[0].tv_nsec;
767 if (u_sec == pps_tf[0].tv_sec && v_nsec < NANOSECOND - MAXFREQ)
769 pps_tf[2] = pps_tf[1];
770 pps_tf[1] = pps_tf[0];
771 pps_tf[0].tv_sec = u_sec;
772 pps_tf[0].tv_nsec = u_nsec;
783 if (u_nsec > (NANOSECOND >> 1))
784 u_nsec -= NANOSECOND;
785 else if (u_nsec < -(NANOSECOND >> 1))
786 u_nsec += NANOSECOND;
787 pps_fcount += u_nsec;
788 if (v_nsec > MAXFREQ || v_nsec < -MAXFREQ)
798 if (pps_tf[0].tv_nsec > pps_tf[1].tv_nsec) {
799 if (pps_tf[1].tv_nsec > pps_tf[2].tv_nsec) {
800 v_nsec = pps_tf[1].tv_nsec;
801 u_nsec = pps_tf[0].tv_nsec - pps_tf[2].tv_nsec;
802 }
else if (pps_tf[2].tv_nsec > pps_tf[0].tv_nsec) {
803 v_nsec = pps_tf[0].tv_nsec;
804 u_nsec = pps_tf[2].tv_nsec - pps_tf[1].tv_nsec;
806 v_nsec = pps_tf[2].tv_nsec;
807 u_nsec = pps_tf[0].tv_nsec - pps_tf[1].tv_nsec;
810 if (pps_tf[1].tv_nsec < pps_tf[2].tv_nsec) {
811 v_nsec = pps_tf[1].tv_nsec;
812 u_nsec = pps_tf[2].tv_nsec - pps_tf[0].tv_nsec;
813 }
else if (pps_tf[2].tv_nsec < pps_tf[0].tv_nsec) {
814 v_nsec = pps_tf[0].tv_nsec;
815 u_nsec = pps_tf[1].tv_nsec - pps_tf[2].tv_nsec;
817 v_nsec = pps_tf[2].tv_nsec;
818 u_nsec = pps_tf[1].tv_nsec - pps_tf[0].tv_nsec;
835 if (u_nsec > lmax(pps_jitter << PPS_POPCORN,
843 pps_jitter += (u_nsec - pps_jitter) >> PPS_FAVG;
844 u_sec = pps_tf[0].tv_sec - pps_lastsec;
845 if (u_sec < (1 << pps_shift))
859 v_nsec = -pps_fcount;
860 pps_lastsec = pps_tf[0].tv_sec;
862 u_nsec = MAXFREQ << pps_shift;
863 if (v_nsec > u_nsec || v_nsec < -u_nsec || u_sec != (1 << pps_shift)) {
882 L_SUB(ftemp, pps_freq);
884 if (u_nsec > PPS_MAXWANDER) {
885 L_LINT(ftemp, PPS_MAXWANDER);
889 }
else if (u_nsec < -PPS_MAXWANDER) {
890 L_LINT(ftemp, -PPS_MAXWANDER);
897 if (pps_intcnt >= 4) {
899 if (pps_shift < pps_shiftmax) {
903 }
else if (pps_intcnt <= -4 || pps_shift > pps_shiftmax) {
905 if (pps_shift > PPS_FAVG) {
912 pps_stabil += (u_nsec * SCALE_PPM - pps_stabil) >> PPS_FAVG;
919 L_ADD(pps_freq, ftemp);
920 u_nsec =
L_GINT(pps_freq);
921 if (u_nsec > MAXFREQ)
922 L_LINT(pps_freq, MAXFREQ);
923 else if (u_nsec < -MAXFREQ)
924 L_LINT(pps_freq, -MAXFREQ);
933#ifndef _SYS_SYSPROTO_H_
943 struct timeval delta, olddelta, *deltap;
947 error = copyin(uap->
delta, &delta,
sizeof(delta));
955 error = copyout(&olddelta, uap->
olddelta,
sizeof(olddelta));
960kern_adjtime(
struct thread *td,
struct timeval *delta,
struct timeval *olddelta)
970 ltw = (int64_t)delta->tv_sec * 1000000 + delta->tv_usec;
977 if (olddelta != NULL) {
978 atv.tv_sec = ltr / 1000000;
979 atv.tv_usec = ltr % 1000000;
980 if (atv.tv_usec < 0) {
981 atv.tv_usec += 1000000;
1022 if (error || !req->newptr)
1035SYSCTL_PROC(_machdep, OID_AUTO, rtc_save_period, CTLTYPE_INT | CTLFLAG_RWTUN |
1037 "Save system time to RTC with this period (in seconds)");
1044 SHUTDOWN_PRI_FIRST);
SYSCTL_INT(ASLR_NODE_OID, OID_AUTO, enable, CTLFLAG_RWTUN, &__elfN(aslr_enabled), 0, ": enable address map randomization")
FEATURE(kdtrace_hooks, "Kernel DTrace hooks which are required to load DTrace kernel modules")
SYSCTL_LONG(_hw, OID_AUTO, availpages, CTLFLAG_RD, &physmem, 0, "Amount of physical memory (in pages)")
int sys_ntp_adjtime(struct thread *td, struct ntp_adjtime_args *uap)
static int64_t time_adjtime
#define NTP_ASSERT_LOCKED()
int sys_ntp_gettime(struct thread *td, struct ntp_gettime_args *uap)
SYSINIT(periodic_resettodr, SI_SUB_LAST, SI_ORDER_MIDDLE, start_periodic_resettodr, NULL)
static void ntp_gettime1(struct ntptimeval *ntvp)
static long time_maxerror
static long time_precision
static int resettodr_period
int sys_adjtime(struct thread *td, struct adjtime_args *uap)
SYSCTL_PROC(_kern_ntp_pll, OID_AUTO, gettime, CTLTYPE_OPAQUE|CTLFLAG_RD|CTLFLAG_MPSAFE, 0, sizeof(struct ntptimeval), ntp_sysctl, "S,ntptimeval", "")
static int ntp_sysctl(SYSCTL_HANDLER_ARGS)
static void periodic_resettodr(void *arg __unused)
static void shutdown_resettodr(void *arg __unused, int howto __unused)
int kern_ntp_adjtime(struct thread *td, struct timex *ntv, int *retvalp)
static long time_constant
static int sysctl_resettodr_period(SYSCTL_HANDLER_ARGS)
void ntp_update_second(int64_t *adjustment, time_t *newsec)
static bool ntp_is_time_error(int tsl)
int kern_adjtime(struct thread *td, struct timeval *delta, struct timeval *olddelta)
MTX_SYSINIT(ntp, &ntp_lock, "ntp", MTX_SPIN)
static struct mtx ntp_lock
static void start_periodic_resettodr(void *arg __unused)
static struct callout resettodr_callout
static void hardupdate(long offset)
SYSCTL_NODE(_kern, OID_AUTO, ntp_pll, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "")
int priv_check(struct thread *td, int priv)
int sysctl_handle_opaque(SYSCTL_HANDLER_ARGS)
int sysctl_handle_int(SYSCTL_HANDLER_ARGS)
uint64_t tc_getfrequency(void)
volatile time_t time_uptime
void nanotime(struct timespec *tsp)
void callout_init(struct callout *c, int mpsafe)
int callout_schedule(struct callout *c, int to_ticks)
struct timeval * olddelta