10 #include <sys/cdefs.h> 
   13 #include "opt_compat.h" 
   16 #include <sys/param.h> 
   17 #include <sys/kernel.h> 
   18 #include <sys/sysctl.h> 
   19 #include <sys/syslog.h> 
   20 #include <sys/systm.h> 
   21 #include <sys/timepps.h> 
   22 #include <sys/timetc.h> 
   23 #include <sys/timex.h> 
   32 #define LARGE_STEP      200 
   67 static struct timehands th9 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &
th0};
 
   68 static struct timehands th8 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th9};
 
   69 static struct timehands th7 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th8};
 
   70 static struct timehands th6 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th7};
 
   71 static struct timehands th5 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th6};
 
   72 static struct timehands th4 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th5};
 
   73 static struct timehands th3 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th4};
 
   74 static struct timehands th2 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th3};
 
   75 static struct timehands th1 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th2};
 
   79         (uint64_t)-1 / 1000000,
 
  104 static SYSCTL_NODE(_kern_timecounter, OID_AUTO, tc, CTLFLAG_RW, 0, 
"");
 
  107 SYSCTL_INT(_kern_timecounter, OID_AUTO, stepwarnings, CTLFLAG_RW,
 
  121         if (req->flags & SCTL_MASK32) {
 
  124                 return SYSCTL_OUT(req, tv, 
sizeof(tv));
 
  136         ncount = tc->tc_get_timecount(tc);
 
  146         freq = tc->tc_frequency;
 
  154 static __inline u_int
 
  161             tc->tc_counter_mask);
 
  173         struct timehands *th;
 
  190         bintime2timespec(&bt, tsp);
 
  199         bintime2timeval(&bt, tvp);
 
  216         bintime2timespec(&bt, tsp);
 
  225         bintime2timeval(&bt, tvp);
 
  231         struct timehands *th;
 
  244         struct timehands *th;
 
  257         struct timehands *th;
 
  270         struct timehands *th;
 
  284         struct timehands *th;
 
  297         struct timehands *th;
 
  315         struct timehands *th;
 
  332         struct sysctl_oid *tc_root;
 
  334         u = tc->tc_frequency / tc->tc_counter_mask;
 
  338         if (u > 
hz && tc->tc_quality >= 0) {
 
  339                 tc->tc_quality = -2000;
 
  341                         printf(
"Timecounter \"%s\" frequency %ju Hz",
 
  342                             tc->tc_name, (uintmax_t)tc->tc_frequency);
 
  343                         printf(
" -- Insufficient hz, needs at least %u\n", u);
 
  346                 printf(
"Timecounter \"%s\" frequency %ju Hz quality %d\n",
 
  347                     tc->tc_name, (uintmax_t)tc->tc_frequency,
 
  356         tc_root = SYSCTL_ADD_NODE(NULL,
 
  357             SYSCTL_STATIC_CHILDREN(_kern_timecounter_tc), OID_AUTO, tc->tc_name,
 
  358             CTLFLAG_RW, 0, 
"timecounter description");
 
  359         SYSCTL_ADD_UINT(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO,
 
  360             "mask", CTLFLAG_RD, &(tc->tc_counter_mask), 0,
 
  361             "mask for implemented bits");
 
  362         SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO,
 
  363             "counter", CTLTYPE_UINT | CTLFLAG_RD, tc, 
sizeof(*tc),
 
  365         SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO,
 
  366             "frequency", CTLTYPE_U64 | CTLFLAG_RD, tc, 
sizeof(*tc),
 
  368         SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO,
 
  369             "quality", CTLFLAG_RD, &(tc->tc_quality), 0,
 
  370             "goodness of time counter");
 
  376         if (tc->tc_quality < 0)
 
  383         (void)tc->tc_get_timecount(tc);
 
  384         (void)tc->tc_get_timecount(tc);
 
  404         struct timespec tbef, taft;
 
  409         timespec2bintime(ts, &bt);
 
  411         bintime_sub(&bt, &bt2);
 
  421                     "Time stepped from %jd.%09ld to %jd.%09ld (%jd.%09ld)\n",
 
  422                     (intmax_t)tbef.tv_sec, tbef.tv_nsec,
 
  423                     (intmax_t)taft.tv_sec, taft.tv_nsec,
 
  424                     (intmax_t)ts->tv_sec, ts->tv_nsec);
 
  438         struct timehands *th, *tho;
 
  440         u_int delta, ncount, ogen;
 
  467         while (delta > th->
th_counter->tc_frequency) {
 
  472         if ((delta > th->
th_counter->tc_frequency / 2) &&
 
  473             (th->
th_scale * delta < ((uint64_t)1 << 63))) {
 
  518                 if ((
timecounter->tc_flags & TC_FLAGS_C2STOP) != 0)
 
  520                 if ((th->
th_counter->tc_flags & TC_FLAGS_C2STOP) != 0)
 
  526                     (((uint64_t)
timecounter->tc_counter_mask + 1) / 3));
 
  552         scale = (uint64_t)1 << 63;
 
  581         strlcpy(newname, tc->tc_name, 
sizeof(newname));
 
  584         if (error != 0 || req->newptr == NULL ||
 
  585             strcmp(newname, tc->tc_name) == 0)
 
  587         for (newtc = 
timecounters; newtc != NULL; newtc = newtc->tc_next) {
 
  588                 if (strcmp(newname, newtc->tc_name) != 0)
 
  592                 (void)newtc->tc_get_timecount(newtc);
 
  593                 (void)newtc->tc_get_timecount(newtc);
 
  602 SYSCTL_PROC(_kern_timecounter, OID_AUTO, hardware, CTLTYPE_STRING | CTLFLAG_RW,
 
  604     "Timecounter hardware selected");
 
  617         for (tc = 
timecounters; error == 0 && tc != NULL; tc = tc->tc_next) {
 
  619                     spc, tc->tc_name, tc->tc_quality);
 
  620                 error = SYSCTL_OUT(req, buf, strlen(buf));
 
  626 SYSCTL_PROC(_kern_timecounter, OID_AUTO, choice, CTLTYPE_STRING | CTLFLAG_RD,
 
  634 pps_ioctl(u_long cmd, caddr_t data, 
struct pps_state *pps)
 
  637         struct pps_fetch_args *fapi;
 
  639         struct pps_kcbind_args *kapi;
 
  642         KASSERT(pps != NULL, (
"NULL pps pointer in pps_ioctl"));
 
  646         case PPS_IOC_DESTROY:
 
  648         case PPS_IOC_SETPARAMS:
 
  649                 app = (pps_params_t *)data;
 
  650                 if (app->mode & ~pps->ppscap)
 
  652                 pps->ppsparam = *app;
 
  654         case PPS_IOC_GETPARAMS:
 
  655                 app = (pps_params_t *)data;
 
  656                 *app = pps->ppsparam;
 
  657                 app->api_version = PPS_API_VERS_1;
 
  660                 *(
int*)data = pps->ppscap;
 
  663                 fapi = (
struct pps_fetch_args *)data;
 
  664                 if (fapi->tsformat && fapi->tsformat != PPS_TSFMT_TSPEC)
 
  666                 if (fapi->timeout.tv_sec || fapi->timeout.tv_nsec)
 
  668                 pps->ppsinfo.current_mode = pps->ppsparam.mode;
 
  669                 fapi->pps_info_buf = pps->ppsinfo;
 
  673                 kapi = (
struct pps_kcbind_args *)data;
 
  675                 if (kapi->tsformat && kapi->tsformat != PPS_TSFMT_TSPEC)
 
  677                 if (kapi->kernel_consumer != PPS_KC_HARDPPS)
 
  679                 if (kapi->edge & ~pps->ppscap)
 
  681                 pps->kcmode = kapi->edge;
 
  694         pps->ppscap |= PPS_TSFMT_TSPEC;
 
  695         if (pps->ppscap & PPS_CAPTUREASSERT)
 
  696                 pps->ppscap |= PPS_OFFSETASSERT;
 
  697         if (pps->ppscap & PPS_CAPTURECLEAR)
 
  698                 pps->ppscap |= PPS_OFFSETCLEAR;
 
  704         struct timehands *th;
 
  706         KASSERT(pps != NULL, (
"NULL pps pointer in pps_capture"));
 
  719         struct timespec ts, *tsp, *osp;
 
  720         u_int tcount, *pcount;
 
  724         KASSERT(pps != NULL, (
"NULL pps pointer in pps_event"));
 
  726         if (pps->capgen == 0 || pps->capgen != pps->capth->th_generation)
 
  730         if (event == PPS_CAPTUREASSERT) {
 
  731                 tsp = &pps->ppsinfo.assert_timestamp;
 
  732                 osp = &pps->ppsparam.assert_offset;
 
  733                 foff = pps->ppsparam.mode & PPS_OFFSETASSERT;
 
  734                 fhard = pps->kcmode & PPS_CAPTUREASSERT;
 
  735                 pcount = &pps->ppscount[0];
 
  736                 pseq = &pps->ppsinfo.assert_sequence;
 
  738                 tsp = &pps->ppsinfo.clear_timestamp;
 
  739                 osp = &pps->ppsparam.clear_offset;
 
  740                 foff = pps->ppsparam.mode & PPS_OFFSETCLEAR;
 
  741                 fhard = pps->kcmode & PPS_CAPTURECLEAR;
 
  742                 pcount = &pps->ppscount[1];
 
  743                 pseq = &pps->ppsinfo.clear_sequence;
 
  750         if (pps->ppstc != pps->capth->th_counter) {
 
  751                 pps->ppstc = pps->capth->th_counter;
 
  752                 *pcount = pps->capcount;
 
  753                 pps->ppscount[2] = pps->capcount;
 
  758         tcount = pps->capcount - pps->capth->th_offset_count;
 
  759         tcount &= pps->capth->th_counter->tc_counter_mask;
 
  760         bt = pps->capth->th_offset;
 
  761         bintime_addx(&bt, pps->capth->th_scale * tcount);
 
  763         bintime2timespec(&bt, &ts);
 
  766         if (pps->capgen != pps->capth->th_generation)
 
  769         *pcount = pps->capcount;
 
  774                 timespecadd(tsp, osp);
 
  775                 if (tsp->tv_nsec < 0) {
 
  776                         tsp->tv_nsec += 1000000000;
 
  789                 tcount = pps->capcount - pps->ppscount[2];
 
  790                 pps->ppscount[2] = pps->capcount;
 
  791                 tcount &= pps->capth->th_counter->tc_counter_mask;
 
  792                 scale = (uint64_t)1 << 63;
 
  793                 scale /= pps->capth->th_counter->tc_frequency;
 
  797                 bintime_addx(&bt, scale * tcount);
 
  798                 bintime2timespec(&bt, &ts);
 
  799                 hardpps(tsp, ts.tv_nsec + 1000000000 * ts.tv_sec);
 
  813     "Approximate number of hardclock ticks in a millisecond");
 
  845         printf(
"Timecounters tick every %d.%03u msec\n", p / 1000, p % 1000);
 
  863         static uint64_t base;
 
  864         static unsigned last;
 
  869         u = tc->tc_get_timecount(tc) & tc->tc_counter_mask;
 
  871                 base += (uint64_t)tc->tc_counter_mask + 1;
 
  879         static time_t last_calib;
 
  898         static uint64_t c_last;
 
  899         uint64_t c_this, c_delta;
 
  901         struct bintime t_this, t_delta;
 
  916         if (t_last.sec != 0) {
 
  917                 c_delta = c_this - c_last;
 
  919                 bintime_sub(&t_delta, &t_last);
 
  927                 divi = t_delta.sec << 20;
 
  928                 divi |= t_delta.frac >> (64 - 20);
 
  933                                 printf(
"cpu_tick increased to %ju Hz\n",
 
  978         if (tick > 18446744073709551LL)         
 
  980         else if (tick > 18446744073709LL)       
 
  992         int old_vdso_th_enable, error;
 
 1002 SYSCTL_PROC(_kern_timecounter, OID_AUTO, fast_gettime,
 
 1003     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
 
 1009         struct timehands *th;
 
 1013         vdso_th->th_algo = VDSO_TH_ALGO_1;
 
 1016         vdso_th->th_counter_mask = th->
th_counter->tc_counter_mask;
 
 1027 tc_fill_vdso_timehands32(
struct vdso_timehands32 *vdso_th32)
 
 1029         struct timehands *th;
 
 1033         vdso_th32->th_algo = VDSO_TH_ALGO_1;
 
 1036         vdso_th32->th_counter_mask = th->
th_counter->tc_counter_mask;
 
 1037         vdso_th32->th_offset.sec = th->
th_offset.sec;
 
 1038         *(uint64_t *)&vdso_th32->th_offset.frac[0] = th->
th_offset.frac;
 
 1040         *(uint64_t *)&vdso_th32->th_boottime.frac[0] = 
boottimebin.frac;
 
 1041         enabled = cpu_fill_vdso_timehands32(vdso_th32);
 
void set_cputicker(cpu_tick_f *func, uint64_t freq, unsigned var)
static struct timehands th3
static struct timehands th5
volatile time_t time_second
struct timehands * th_next
uint32_t cpu_fill_vdso_timehands(struct vdso_timehands *vdso_th)
void tc_ticktock(int cnt)
static void tc_windup(void)
int sprintf(char *buf, const char *cfmt,...)
void tc_init(struct timecounter *tc)
static int sysctl_kern_timecounter_get(SYSCTL_HANDLER_ARGS)
int pps_ioctl(u_long cmd, caddr_t data, struct pps_state *pps)
static struct timehands th4
void pps_init(struct pps_state *pps)
static struct timecounter dummy_timecounter
static void cpu_tick_calibrate(int)
int sysctl_handle_string(SYSCTL_HANDLER_ARGS)
void getnanouptime(struct timespec *tsp)
static int sysctl_kern_timecounter_hardware(SYSCTL_HANDLER_ARGS)
static int sysctl_fast_gettime(SYSCTL_HANDLER_ARGS)
void getmicrouptime(struct timeval *tvp)
struct bintime boottimebin
static int cpu_tick_variable
void ntp_update_second(int64_t *adjustment, time_t *newsec)
volatile u_int th_generation
struct timecounter * timecounter
uint64_t cputick2usec(uint64_t tick)
static void inittimecounter(void *dummy)
void tc_setclock(struct timespec *ts)
SYSCTL_INT(_kern_timecounter, OID_AUTO, stepwarnings, CTLFLAG_RW,×tepwarnings, 0,"Log time steps")
static struct timecounter * timecounters
static struct timehands th7
int sysctl_handle_int(SYSCTL_HANDLER_ARGS)
void getmicrotime(struct timeval *tvp)
static int sysctl_kern_boottime(SYSCTL_HANDLER_ARGS)
void nanotime(struct timespec *tsp)
int sysctl_handle_64(SYSCTL_HANDLER_ARGS)
static int vdso_th_enable
static u_int dummy_get_timecount(struct timecounter *tc)
void log(int level, const char *fmt,...)
SYSINIT(timecounter, SI_SUB_CLOCKS, SI_ORDER_SECOND, inittimecounter, NULL)
static __inline u_int tc_delta(struct timehands *th)
void getnanotime(struct timespec *tsp)
void pps_event(struct pps_state *pps, int event)
struct timecounter * th_counter
struct timeval th_microtime
int printf(const char *fmt,...)
static int timestepwarnings
static int sysctl_kern_timecounter_choice(SYSCTL_HANDLER_ARGS)
static struct timehands th1
uint32_t tc_fill_vdso_timehands(struct vdso_timehands *vdso_th)
void bintime(struct bintime *bt)
void dtrace_getnanotime(struct timespec *tsp)
void getbinuptime(struct bintime *bt)
SYSCTL_PROC(_kern, KERN_BOOTTIME, boottime, CTLTYPE_STRUCT|CTLFLAG_RD, NULL, 0, sysctl_kern_boottime,"S,timeval","System boottime")
void getbintime(struct bintime *bt)
uint64_t cpu_tickrate(void)
uint64_t tc_getfrequency(void)
volatile time_t time_uptime
void microuptime(struct timeval *tvp)
void binuptime(struct bintime *bt)
void timekeep_push_vdso(void)
void pps_capture(struct pps_state *pps)
void microtime(struct timeval *tvp)
static struct timehands *volatile timehands
void nanouptime(struct timespec *tsp)
static struct timehands th6
static uint64_t tc_cpu_ticks(void)
static struct timehands th9
static struct timehands th2
void cpu_tick_calibration(void)
static struct timehands th0
SYSCTL_NODE(_kern, OID_AUTO, timecounter, CTLFLAG_RW, 0,"")
static uint64_t cpu_tick_frequency
static int sysctl_kern_timecounter_freq(SYSCTL_HANDLER_ARGS)
static struct timehands th8
struct timespec th_nanotime