195821Sphk/*-
258377Sphk * ----------------------------------------------------------------------------
358377Sphk * "THE BEER-WARE LICENSE" (Revision 42):
458377Sphk * <phk@FreeBSD.ORG> wrote this file.  As long as you retain this notice you
558377Sphk * can do whatever you want with this stuff. If we meet some day, and you think
658377Sphk * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
758377Sphk * ----------------------------------------------------------------------------
8227723Slstewart *
9227723Slstewart * Copyright (c) 2011 The FreeBSD Foundation
10227723Slstewart * All rights reserved.
11227723Slstewart *
12227723Slstewart * Portions of this software were developed by Julien Ridoux at the University
13227723Slstewart * of Melbourne under sponsorship from the FreeBSD Foundation.
141541Srgrimes */
151541Srgrimes
16116182Sobrien#include <sys/cdefs.h>
17116182Sobrien__FBSDID("$FreeBSD$");
18116182Sobrien
19237433Skib#include "opt_compat.h"
2044666Sphk#include "opt_ntp.h"
21227723Slstewart#include "opt_ffclock.h"
2244666Sphk
231541Srgrimes#include <sys/param.h>
2458377Sphk#include <sys/kernel.h>
25247777Sdavide#include <sys/limits.h>
26227723Slstewart#ifdef FFCLOCK
27227723Slstewart#include <sys/lock.h>
28227723Slstewart#include <sys/mutex.h>
29227723Slstewart#endif
3058377Sphk#include <sys/sysctl.h>
31124812Sphk#include <sys/syslog.h>
321541Srgrimes#include <sys/systm.h>
33227723Slstewart#include <sys/timeffc.h>
3495976Sphk#include <sys/timepps.h>
3595821Sphk#include <sys/timetc.h>
362858Swollman#include <sys/timex.h>
37237433Skib#include <sys/vdso.h>
381541Srgrimes
3940609Sphk/*
40119183Simp * A large step happens on boot.  This constant detects such steps.
41119183Simp * It is relatively small so that ntp_update_second gets called enough
42119183Simp * in the typical 'missed a couple of seconds' case, but doesn't loop
43119183Simp * forever when the time step is large.
44116841Simp */
45116841Simp#define LARGE_STEP	200
46116841Simp
47116841Simp/*
4895530Sphk * Implement a dummy timecounter which we can use until we get a real one
4995530Sphk * in the air.  This allows the console and other early stuff to use
5095821Sphk * time services.
5140609Sphk */
5240609Sphk
5395661Sphkstatic u_int
5495530Sphkdummy_get_timecount(struct timecounter *tc)
5595530Sphk{
5695661Sphk	static u_int now;
5740609Sphk
5895530Sphk	return (++now);
5995530Sphk}
6095530Sphk
6195530Sphkstatic struct timecounter dummy_timecounter = {
62118987Sphk	dummy_get_timecount, 0, ~0u, 1000000, "dummy", -1000000
6395530Sphk};
6495530Sphk
6595530Sphkstruct timehands {
6695530Sphk	/* These fields must be initialized by the driver. */
6795661Sphk	struct timecounter	*th_counter;
6895661Sphk	int64_t			th_adjustment;
69209390Sed	uint64_t		th_scale;
7095661Sphk	u_int	 		th_offset_count;
7195661Sphk	struct bintime		th_offset;
7295661Sphk	struct timeval		th_microtime;
7395661Sphk	struct timespec		th_nanotime;
7495821Sphk	/* Fields not to be copied in tc_windup start with th_generation. */
7595661Sphk	volatile u_int		th_generation;
7695661Sphk	struct timehands	*th_next;
7795530Sphk};
7895530Sphk
79149848Sobrienstatic struct timehands th0;
8095821Sphkstatic struct timehands th9 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th0};
8195821Sphkstatic struct timehands th8 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th9};
8295821Sphkstatic struct timehands th7 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th8};
8395821Sphkstatic struct timehands th6 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th7};
8495821Sphkstatic struct timehands th5 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th6};
8595821Sphkstatic struct timehands th4 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th5};
8695821Sphkstatic struct timehands th3 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th4};
8795821Sphkstatic struct timehands th2 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th3};
8895821Sphkstatic struct timehands th1 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th2};
8995551Sphkstatic struct timehands th0 = {
9095551Sphk	&dummy_timecounter,
9195551Sphk	0,
9295821Sphk	(uint64_t)-1 / 1000000,
9395551Sphk	0,
9495659Sphk	{1, 0},
9595551Sphk	{0, 0},
9695551Sphk	{0, 0},
9795551Sphk	1,
9895551Sphk	&th1
9995551Sphk};
10095530Sphk
10195530Sphkstatic struct timehands *volatile timehands = &th0;
10295530Sphkstruct timecounter *timecounter = &dummy_timecounter;
10395530Sphkstatic struct timecounter *timecounters = &dummy_timecounter;
10495530Sphk
105212603Smavint tc_min_ticktock_freq = 1;
106212603Smav
107246037Sjhbvolatile time_t time_second = 1;
108246037Sjhbvolatile time_t time_uptime = 1;
10934961Sphk
110209216Sjkimstruct bintime boottimebin;
11195821Sphkstruct timeval boottime;
112136404Speterstatic int sysctl_kern_boottime(SYSCTL_HANDLER_ARGS);
113136404SpeterSYSCTL_PROC(_kern, KERN_BOOTTIME, boottime, CTLTYPE_STRUCT|CTLFLAG_RD,
114136404Speter    NULL, 0, sysctl_kern_boottime, "S,timeval", "System boottime");
11551229Sbde
11658377SphkSYSCTL_NODE(_kern, OID_AUTO, timecounter, CTLFLAG_RW, 0, "");
117227309Sedstatic SYSCTL_NODE(_kern_timecounter, OID_AUTO, tc, CTLFLAG_RW, 0, "");
11841415Sphk
119124812Sphkstatic int timestepwarnings;
120124812SphkSYSCTL_INT(_kern_timecounter, OID_AUTO, stepwarnings, CTLFLAG_RW,
121215281Sbrucec    &timestepwarnings, 0, "Log time steps");
122124812Sphk
123247777Sdavidestruct bintime bt_timethreshold;
124247777Sdavidestruct bintime bt_tickthreshold;
125247777Sdavidesbintime_t sbt_timethreshold;
126247777Sdavidesbintime_t sbt_tickthreshold;
127247777Sdavidestruct bintime tc_tick_bt;
128247777Sdavidesbintime_t tc_tick_sbt;
129247777Sdavideint tc_precexp;
130247777Sdavideint tc_timepercentage = TC_DEFAULTPERC;
131247777SdavideTUNABLE_INT("kern.timecounter.alloweddeviation", &tc_timepercentage);
132247777Sdavidestatic int sysctl_kern_timecounter_adjprecision(SYSCTL_HANDLER_ARGS);
133247777SdavideSYSCTL_PROC(_kern_timecounter, OID_AUTO, alloweddeviation,
134247777Sdavide    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 0,
135247777Sdavide    sysctl_kern_timecounter_adjprecision, "I",
136247777Sdavide    "Allowed time interval deviation in percents");
137247777Sdavide
13895497Sphkstatic void tc_windup(void);
139155534Sphkstatic void cpu_tick_calibrate(int);
14095497Sphk
141238537Sgnnvoid dtrace_getnanotime(struct timespec *tsp);
142238537Sgnn
143136404Speterstatic int
144136404Spetersysctl_kern_boottime(SYSCTL_HANDLER_ARGS)
145136404Speter{
146232449Sjmallett#ifndef __mips__
147136404Speter#ifdef SCTL_MASK32
148136404Speter	int tv[2];
149136404Speter
150136404Speter	if (req->flags & SCTL_MASK32) {
151136404Speter		tv[0] = boottime.tv_sec;
152136404Speter		tv[1] = boottime.tv_usec;
153136404Speter		return SYSCTL_OUT(req, tv, sizeof(tv));
154136404Speter	} else
155136404Speter#endif
156232449Sjmallett#endif
157136404Speter		return SYSCTL_OUT(req, &boottime, sizeof(boottime));
158136404Speter}
159155444Sphk
160159669Sdwmalonestatic int
161159669Sdwmalonesysctl_kern_timecounter_get(SYSCTL_HANDLER_ARGS)
162159669Sdwmalone{
163159669Sdwmalone	u_int ncount;
164159669Sdwmalone	struct timecounter *tc = arg1;
165159669Sdwmalone
166159669Sdwmalone	ncount = tc->tc_get_timecount(tc);
167170289Sdwmalone	return sysctl_handle_int(oidp, &ncount, 0, req);
168159669Sdwmalone}
169159669Sdwmalone
170159669Sdwmalonestatic int
171159669Sdwmalonesysctl_kern_timecounter_freq(SYSCTL_HANDLER_ARGS)
172159669Sdwmalone{
173209390Sed	uint64_t freq;
174159669Sdwmalone	struct timecounter *tc = arg1;
175159669Sdwmalone
176159669Sdwmalone	freq = tc->tc_frequency;
177217616Smdf	return sysctl_handle_64(oidp, &freq, 0, req);
178159669Sdwmalone}
179159669Sdwmalone
18095821Sphk/*
18195821Sphk * Return the difference between the timehands' counter value now and what
18295821Sphk * was when we copied it to the timehands' offset_count.
18395821Sphk */
18495661Sphkstatic __inline u_int
18595661Sphktc_delta(struct timehands *th)
18636441Sphk{
18795661Sphk	struct timecounter *tc;
18834901Sphk
18995661Sphk	tc = th->th_counter;
19095661Sphk	return ((tc->tc_get_timecount(tc) - th->th_offset_count) &
19195661Sphk	    tc->tc_counter_mask);
19236441Sphk}
19336441Sphk
19495821Sphk/*
19595661Sphk * Functions for reading the time.  We have to loop until we are sure that
19695821Sphk * the timehands that we operated on was not updated under our feet.  See
19795821Sphk * the comment in <sys/time.h> for a description of these 12 functions.
19895661Sphk */
19995661Sphk
200227747Slstewart#ifdef FFCLOCK
201228117Slstewartvoid
202227747Slstewartfbclock_binuptime(struct bintime *bt)
203227747Slstewart{
204227747Slstewart	struct timehands *th;
205227747Slstewart	unsigned int gen;
206227747Slstewart
207227747Slstewart	do {
208227747Slstewart		th = timehands;
209227747Slstewart		gen = th->th_generation;
210227747Slstewart		*bt = th->th_offset;
211227747Slstewart		bintime_addx(bt, th->th_scale * tc_delta(th));
212227747Slstewart	} while (gen == 0 || gen != th->th_generation);
213227747Slstewart}
214227747Slstewart
215228117Slstewartvoid
216227747Slstewartfbclock_nanouptime(struct timespec *tsp)
217227747Slstewart{
218227747Slstewart	struct bintime bt;
219227747Slstewart
220228115Slstewart	fbclock_binuptime(&bt);
221227747Slstewart	bintime2timespec(&bt, tsp);
222227747Slstewart}
223227747Slstewart
224228117Slstewartvoid
225227747Slstewartfbclock_microuptime(struct timeval *tvp)
226227747Slstewart{
227227747Slstewart	struct bintime bt;
228227747Slstewart
229228115Slstewart	fbclock_binuptime(&bt);
230227747Slstewart	bintime2timeval(&bt, tvp);
231227747Slstewart}
232227747Slstewart
233228117Slstewartvoid
234227747Slstewartfbclock_bintime(struct bintime *bt)
235227747Slstewart{
236227747Slstewart
237228115Slstewart	fbclock_binuptime(bt);
238227747Slstewart	bintime_add(bt, &boottimebin);
239227747Slstewart}
240227747Slstewart
241228117Slstewartvoid
242227747Slstewartfbclock_nanotime(struct timespec *tsp)
243227747Slstewart{
244227747Slstewart	struct bintime bt;
245227747Slstewart
246228115Slstewart	fbclock_bintime(&bt);
247227747Slstewart	bintime2timespec(&bt, tsp);
248227747Slstewart}
249227747Slstewart
250228117Slstewartvoid
251227747Slstewartfbclock_microtime(struct timeval *tvp)
252227747Slstewart{
253227747Slstewart	struct bintime bt;
254227747Slstewart
255228115Slstewart	fbclock_bintime(&bt);
256227747Slstewart	bintime2timeval(&bt, tvp);
257227747Slstewart}
258227747Slstewart
259228117Slstewartvoid
260227747Slstewartfbclock_getbinuptime(struct bintime *bt)
261227747Slstewart{
262227747Slstewart	struct timehands *th;
263227747Slstewart	unsigned int gen;
264227747Slstewart
265227747Slstewart	do {
266227747Slstewart		th = timehands;
267227747Slstewart		gen = th->th_generation;
268227747Slstewart		*bt = th->th_offset;
269227747Slstewart	} while (gen == 0 || gen != th->th_generation);
270227747Slstewart}
271227747Slstewart
272228117Slstewartvoid
273227747Slstewartfbclock_getnanouptime(struct timespec *tsp)
274227747Slstewart{
275227747Slstewart	struct timehands *th;
276227747Slstewart	unsigned int gen;
277227747Slstewart
278227747Slstewart	do {
279227747Slstewart		th = timehands;
280227747Slstewart		gen = th->th_generation;
281227747Slstewart		bintime2timespec(&th->th_offset, tsp);
282227747Slstewart	} while (gen == 0 || gen != th->th_generation);
283227747Slstewart}
284227747Slstewart
285228117Slstewartvoid
286227747Slstewartfbclock_getmicrouptime(struct timeval *tvp)
287227747Slstewart{
288227747Slstewart	struct timehands *th;
289227747Slstewart	unsigned int gen;
290227747Slstewart
291227747Slstewart	do {
292227747Slstewart		th = timehands;
293227747Slstewart		gen = th->th_generation;
294227747Slstewart		bintime2timeval(&th->th_offset, tvp);
295227747Slstewart	} while (gen == 0 || gen != th->th_generation);
296227747Slstewart}
297227747Slstewart
298228117Slstewartvoid
299227747Slstewartfbclock_getbintime(struct bintime *bt)
300227747Slstewart{
301227747Slstewart	struct timehands *th;
302227747Slstewart	unsigned int gen;
303227747Slstewart
304227747Slstewart	do {
305227747Slstewart		th = timehands;
306227747Slstewart		gen = th->th_generation;
307227747Slstewart		*bt = th->th_offset;
308227747Slstewart	} while (gen == 0 || gen != th->th_generation);
309227747Slstewart	bintime_add(bt, &boottimebin);
310227747Slstewart}
311227747Slstewart
312228117Slstewartvoid
313227747Slstewartfbclock_getnanotime(struct timespec *tsp)
314227747Slstewart{
315227747Slstewart	struct timehands *th;
316227747Slstewart	unsigned int gen;
317227747Slstewart
318227747Slstewart	do {
319227747Slstewart		th = timehands;
320227747Slstewart		gen = th->th_generation;
321227747Slstewart		*tsp = th->th_nanotime;
322227747Slstewart	} while (gen == 0 || gen != th->th_generation);
323227747Slstewart}
324227747Slstewart
325228117Slstewartvoid
326227747Slstewartfbclock_getmicrotime(struct timeval *tvp)
327227747Slstewart{
328227747Slstewart	struct timehands *th;
329227747Slstewart	unsigned int gen;
330227747Slstewart
331227747Slstewart	do {
332227747Slstewart		th = timehands;
333227747Slstewart		gen = th->th_generation;
334227747Slstewart		*tvp = th->th_microtime;
335227747Slstewart	} while (gen == 0 || gen != th->th_generation);
336227747Slstewart}
337227747Slstewart#else /* !FFCLOCK */
33833391Sphkvoid
33990362Sphkbinuptime(struct bintime *bt)
34090362Sphk{
34195661Sphk	struct timehands *th;
34295661Sphk	u_int gen;
34390362Sphk
34491200Sphk	do {
34595661Sphk		th = timehands;
34695661Sphk		gen = th->th_generation;
34795661Sphk		*bt = th->th_offset;
34895661Sphk		bintime_addx(bt, th->th_scale * tc_delta(th));
34995661Sphk	} while (gen == 0 || gen != th->th_generation);
35090362Sphk}
35190362Sphk
35290362Sphkvoid
35395821Sphknanouptime(struct timespec *tsp)
35495491Sphk{
35595491Sphk	struct bintime bt;
35695491Sphk
35795491Sphk	binuptime(&bt);
35895821Sphk	bintime2timespec(&bt, tsp);
35995491Sphk}
36095491Sphk
36195491Sphkvoid
36295821Sphkmicrouptime(struct timeval *tvp)
36395491Sphk{
36495491Sphk	struct bintime bt;
36595491Sphk
36695491Sphk	binuptime(&bt);
36795821Sphk	bintime2timeval(&bt, tvp);
36895491Sphk}
36995491Sphk
37095491Sphkvoid
37190362Sphkbintime(struct bintime *bt)
37290362Sphk{
37390362Sphk
37490362Sphk	binuptime(bt);
37590362Sphk	bintime_add(bt, &boottimebin);
37690362Sphk}
37790362Sphk
37890362Sphkvoid
37995821Sphknanotime(struct timespec *tsp)
38034901Sphk{
38195491Sphk	struct bintime bt;
38295491Sphk
38395491Sphk	bintime(&bt);
38495821Sphk	bintime2timespec(&bt, tsp);
38595491Sphk}
38695491Sphk
38795491Sphkvoid
38895821Sphkmicrotime(struct timeval *tvp)
38995491Sphk{
39095491Sphk	struct bintime bt;
39195491Sphk
39295491Sphk	bintime(&bt);
39395821Sphk	bintime2timeval(&bt, tvp);
39495491Sphk}
39595491Sphk
39695491Sphkvoid
39795491Sphkgetbinuptime(struct bintime *bt)
39895491Sphk{
39995661Sphk	struct timehands *th;
40095661Sphk	u_int gen;
40134901Sphk
40291200Sphk	do {
40395661Sphk		th = timehands;
40495661Sphk		gen = th->th_generation;
40595661Sphk		*bt = th->th_offset;
40695661Sphk	} while (gen == 0 || gen != th->th_generation);
40735029Sphk}
40835029Sphk
40935029Sphkvoid
41095491Sphkgetnanouptime(struct timespec *tsp)
41135029Sphk{
41295661Sphk	struct timehands *th;
41395661Sphk	u_int gen;
41435029Sphk
41591200Sphk	do {
41695661Sphk		th = timehands;
41795661Sphk		gen = th->th_generation;
41895661Sphk		bintime2timespec(&th->th_offset, tsp);
41995661Sphk	} while (gen == 0 || gen != th->th_generation);
42035029Sphk}
42135029Sphk
42235029Sphkvoid
42336119Sphkgetmicrouptime(struct timeval *tvp)
42435029Sphk{
42595661Sphk	struct timehands *th;
42695661Sphk	u_int gen;
42735029Sphk
42891200Sphk	do {
42995661Sphk		th = timehands;
43095661Sphk		gen = th->th_generation;
43195661Sphk		bintime2timeval(&th->th_offset, tvp);
43295661Sphk	} while (gen == 0 || gen != th->th_generation);
43334901Sphk}
43434901Sphk
43534901Sphkvoid
43695491Sphkgetbintime(struct bintime *bt)
43734901Sphk{
43895661Sphk	struct timehands *th;
43995661Sphk	u_int gen;
44034901Sphk
44191200Sphk	do {
44295661Sphk		th = timehands;
44395661Sphk		gen = th->th_generation;
44495661Sphk		*bt = th->th_offset;
44595661Sphk	} while (gen == 0 || gen != th->th_generation);
44695491Sphk	bintime_add(bt, &boottimebin);
44734901Sphk}
44834901Sphk
44934901Sphkvoid
45095491Sphkgetnanotime(struct timespec *tsp)
45133391Sphk{
45295661Sphk	struct timehands *th;
45395661Sphk	u_int gen;
45433690Sphk
45595491Sphk	do {
45695661Sphk		th = timehands;
45795661Sphk		gen = th->th_generation;
45895661Sphk		*tsp = th->th_nanotime;
45995661Sphk	} while (gen == 0 || gen != th->th_generation);
46033391Sphk}
46133690Sphk
46233690Sphkvoid
46395491Sphkgetmicrotime(struct timeval *tvp)
46433690Sphk{
46595661Sphk	struct timehands *th;
46695661Sphk	u_int gen;
46733690Sphk
46895491Sphk	do {
46995661Sphk		th = timehands;
47095661Sphk		gen = th->th_generation;
47195661Sphk		*tvp = th->th_microtime;
47295661Sphk	} while (gen == 0 || gen != th->th_generation);
47333690Sphk}
474227747Slstewart#endif /* FFCLOCK */
47533690Sphk
476227723Slstewart#ifdef FFCLOCK
47795821Sphk/*
478227723Slstewart * Support for feed-forward synchronization algorithms. This is heavily inspired
479227723Slstewart * by the timehands mechanism but kept independent from it. *_windup() functions
480227723Slstewart * have some connection to avoid accessing the timecounter hardware more than
481227723Slstewart * necessary.
482227723Slstewart */
483227723Slstewart
484227723Slstewart/* Feed-forward clock estimates kept updated by the synchronization daemon. */
485227723Slstewartstruct ffclock_estimate ffclock_estimate;
486227723Slstewartstruct bintime ffclock_boottime;	/* Feed-forward boot time estimate. */
487227723Slstewartuint32_t ffclock_status;		/* Feed-forward clock status. */
488227723Slstewartint8_t ffclock_updated;			/* New estimates are available. */
489227723Slstewartstruct mtx ffclock_mtx;			/* Mutex on ffclock_estimate. */
490227723Slstewart
491227723Slstewartstruct fftimehands {
492227723Slstewart	struct ffclock_estimate	cest;
493227723Slstewart	struct bintime		tick_time;
494227723Slstewart	struct bintime		tick_time_lerp;
495227723Slstewart	ffcounter		tick_ffcount;
496227723Slstewart	uint64_t		period_lerp;
497227723Slstewart	volatile uint8_t	gen;
498227723Slstewart	struct fftimehands	*next;
499227723Slstewart};
500227723Slstewart
501227723Slstewart#define	NUM_ELEMENTS(x) (sizeof(x) / sizeof(*x))
502227723Slstewart
503227723Slstewartstatic struct fftimehands ffth[10];
504227723Slstewartstatic struct fftimehands *volatile fftimehands = ffth;
505227723Slstewart
506227723Slstewartstatic void
507227723Slstewartffclock_init(void)
508227723Slstewart{
509227723Slstewart	struct fftimehands *cur;
510227723Slstewart	struct fftimehands *last;
511227723Slstewart
512227723Slstewart	memset(ffth, 0, sizeof(ffth));
513227723Slstewart
514227723Slstewart	last = ffth + NUM_ELEMENTS(ffth) - 1;
515227723Slstewart	for (cur = ffth; cur < last; cur++)
516227723Slstewart		cur->next = cur + 1;
517227723Slstewart	last->next = ffth;
518227723Slstewart
519227723Slstewart	ffclock_updated = 0;
520227723Slstewart	ffclock_status = FFCLOCK_STA_UNSYNC;
521227723Slstewart	mtx_init(&ffclock_mtx, "ffclock lock", NULL, MTX_DEF);
522227723Slstewart}
523227723Slstewart
524227723Slstewart/*
525227723Slstewart * Reset the feed-forward clock estimates. Called from inittodr() to get things
526227723Slstewart * kick started and uses the timecounter nominal frequency as a first period
527227723Slstewart * estimate. Note: this function may be called several time just after boot.
528227723Slstewart * Note: this is the only function that sets the value of boot time for the
529227723Slstewart * monotonic (i.e. uptime) version of the feed-forward clock.
530227723Slstewart */
531227723Slstewartvoid
532227723Slstewartffclock_reset_clock(struct timespec *ts)
533227723Slstewart{
534227723Slstewart	struct timecounter *tc;
535227723Slstewart	struct ffclock_estimate cest;
536227723Slstewart
537227723Slstewart	tc = timehands->th_counter;
538227723Slstewart	memset(&cest, 0, sizeof(struct ffclock_estimate));
539227723Slstewart
540227723Slstewart	timespec2bintime(ts, &ffclock_boottime);
541227723Slstewart	timespec2bintime(ts, &(cest.update_time));
542227723Slstewart	ffclock_read_counter(&cest.update_ffcount);
543227723Slstewart	cest.leapsec_next = 0;
544227723Slstewart	cest.period = ((1ULL << 63) / tc->tc_frequency) << 1;
545227723Slstewart	cest.errb_abs = 0;
546227723Slstewart	cest.errb_rate = 0;
547227723Slstewart	cest.status = FFCLOCK_STA_UNSYNC;
548227723Slstewart	cest.leapsec_total = 0;
549227723Slstewart	cest.leapsec = 0;
550227723Slstewart
551227723Slstewart	mtx_lock(&ffclock_mtx);
552227723Slstewart	bcopy(&cest, &ffclock_estimate, sizeof(struct ffclock_estimate));
553227723Slstewart	ffclock_updated = INT8_MAX;
554227723Slstewart	mtx_unlock(&ffclock_mtx);
555227723Slstewart
556227723Slstewart	printf("ffclock reset: %s (%llu Hz), time = %ld.%09lu\n", tc->tc_name,
557227723Slstewart	    (unsigned long long)tc->tc_frequency, (long)ts->tv_sec,
558227723Slstewart	    (unsigned long)ts->tv_nsec);
559227723Slstewart}
560227723Slstewart
561227723Slstewart/*
562227723Slstewart * Sub-routine to convert a time interval measured in RAW counter units to time
563227723Slstewart * in seconds stored in bintime format.
564227723Slstewart * NOTE: bintime_mul requires u_int, but the value of the ffcounter may be
565227723Slstewart * larger than the max value of u_int (on 32 bit architecture). Loop to consume
566227723Slstewart * extra cycles.
567227723Slstewart */
568227723Slstewartstatic void
569227723Slstewartffclock_convert_delta(ffcounter ffdelta, uint64_t period, struct bintime *bt)
570227723Slstewart{
571227723Slstewart	struct bintime bt2;
572227723Slstewart	ffcounter delta, delta_max;
573227723Slstewart
574227723Slstewart	delta_max = (1ULL << (8 * sizeof(unsigned int))) - 1;
575227723Slstewart	bintime_clear(bt);
576227723Slstewart	do {
577227723Slstewart		if (ffdelta > delta_max)
578227723Slstewart			delta = delta_max;
579227723Slstewart		else
580227723Slstewart			delta = ffdelta;
581227723Slstewart		bt2.sec = 0;
582227723Slstewart		bt2.frac = period;
583227723Slstewart		bintime_mul(&bt2, (unsigned int)delta);
584227723Slstewart		bintime_add(bt, &bt2);
585227723Slstewart		ffdelta -= delta;
586227723Slstewart	} while (ffdelta > 0);
587227723Slstewart}
588227723Slstewart
589227723Slstewart/*
590227723Slstewart * Update the fftimehands.
591227723Slstewart * Push the tick ffcount and time(s) forward based on current clock estimate.
592227723Slstewart * The conversion from ffcounter to bintime relies on the difference clock
593227723Slstewart * principle, whose accuracy relies on computing small time intervals. If a new
594227723Slstewart * clock estimate has been passed by the synchronisation daemon, make it
595227723Slstewart * current, and compute the linear interpolation for monotonic time if needed.
596227723Slstewart */
597227723Slstewartstatic void
598227723Slstewartffclock_windup(unsigned int delta)
599227723Slstewart{
600227723Slstewart	struct ffclock_estimate *cest;
601227723Slstewart	struct fftimehands *ffth;
602227723Slstewart	struct bintime bt, gap_lerp;
603227723Slstewart	ffcounter ffdelta;
604227723Slstewart	uint64_t frac;
605227723Slstewart	unsigned int polling;
606227723Slstewart	uint8_t forward_jump, ogen;
607227723Slstewart
608227723Slstewart	/*
609227723Slstewart	 * Pick the next timehand, copy current ffclock estimates and move tick
610227723Slstewart	 * times and counter forward.
611227723Slstewart	 */
612227723Slstewart	forward_jump = 0;
613227723Slstewart	ffth = fftimehands->next;
614227723Slstewart	ogen = ffth->gen;
615227723Slstewart	ffth->gen = 0;
616227723Slstewart	cest = &ffth->cest;
617227723Slstewart	bcopy(&fftimehands->cest, cest, sizeof(struct ffclock_estimate));
618227723Slstewart	ffdelta = (ffcounter)delta;
619227723Slstewart	ffth->period_lerp = fftimehands->period_lerp;
620227723Slstewart
621227723Slstewart	ffth->tick_time = fftimehands->tick_time;
622227723Slstewart	ffclock_convert_delta(ffdelta, cest->period, &bt);
623227723Slstewart	bintime_add(&ffth->tick_time, &bt);
624227723Slstewart
625227723Slstewart	ffth->tick_time_lerp = fftimehands->tick_time_lerp;
626227723Slstewart	ffclock_convert_delta(ffdelta, ffth->period_lerp, &bt);
627227723Slstewart	bintime_add(&ffth->tick_time_lerp, &bt);
628227723Slstewart
629227723Slstewart	ffth->tick_ffcount = fftimehands->tick_ffcount + ffdelta;
630227723Slstewart
631227723Slstewart	/*
632227723Slstewart	 * Assess the status of the clock, if the last update is too old, it is
633227723Slstewart	 * likely the synchronisation daemon is dead and the clock is free
634227723Slstewart	 * running.
635227723Slstewart	 */
636227723Slstewart	if (ffclock_updated == 0) {
637227723Slstewart		ffdelta = ffth->tick_ffcount - cest->update_ffcount;
638227723Slstewart		ffclock_convert_delta(ffdelta, cest->period, &bt);
639227723Slstewart		if (bt.sec > 2 * FFCLOCK_SKM_SCALE)
640227723Slstewart			ffclock_status |= FFCLOCK_STA_UNSYNC;
641227723Slstewart	}
642227723Slstewart
643227723Slstewart	/*
644227723Slstewart	 * If available, grab updated clock estimates and make them current.
645227723Slstewart	 * Recompute time at this tick using the updated estimates. The clock
646227723Slstewart	 * estimates passed the feed-forward synchronisation daemon may result
647227723Slstewart	 * in time conversion that is not monotonically increasing (just after
648227723Slstewart	 * the update). time_lerp is a particular linear interpolation over the
649227723Slstewart	 * synchronisation algo polling period that ensures monotonicity for the
650227723Slstewart	 * clock ids requesting it.
651227723Slstewart	 */
652227723Slstewart	if (ffclock_updated > 0) {
653227723Slstewart		bcopy(&ffclock_estimate, cest, sizeof(struct ffclock_estimate));
654227723Slstewart		ffdelta = ffth->tick_ffcount - cest->update_ffcount;
655227723Slstewart		ffth->tick_time = cest->update_time;
656227723Slstewart		ffclock_convert_delta(ffdelta, cest->period, &bt);
657227723Slstewart		bintime_add(&ffth->tick_time, &bt);
658227723Slstewart
659227723Slstewart		/* ffclock_reset sets ffclock_updated to INT8_MAX */
660227723Slstewart		if (ffclock_updated == INT8_MAX)
661227723Slstewart			ffth->tick_time_lerp = ffth->tick_time;
662227723Slstewart
663227723Slstewart		if (bintime_cmp(&ffth->tick_time, &ffth->tick_time_lerp, >))
664227723Slstewart			forward_jump = 1;
665227723Slstewart		else
666227723Slstewart			forward_jump = 0;
667227723Slstewart
668227723Slstewart		bintime_clear(&gap_lerp);
669227723Slstewart		if (forward_jump) {
670227723Slstewart			gap_lerp = ffth->tick_time;
671227723Slstewart			bintime_sub(&gap_lerp, &ffth->tick_time_lerp);
672227723Slstewart		} else {
673227723Slstewart			gap_lerp = ffth->tick_time_lerp;
674227723Slstewart			bintime_sub(&gap_lerp, &ffth->tick_time);
675227723Slstewart		}
676227723Slstewart
677227723Slstewart		/*
678227723Slstewart		 * The reset from the RTC clock may be far from accurate, and
679227723Slstewart		 * reducing the gap between real time and interpolated time
680227723Slstewart		 * could take a very long time if the interpolated clock insists
681227723Slstewart		 * on strict monotonicity. The clock is reset under very strict
682227723Slstewart		 * conditions (kernel time is known to be wrong and
683227723Slstewart		 * synchronization daemon has been restarted recently.
684227723Slstewart		 * ffclock_boottime absorbs the jump to ensure boot time is
685227723Slstewart		 * correct and uptime functions stay consistent.
686227723Slstewart		 */
687227723Slstewart		if (((ffclock_status & FFCLOCK_STA_UNSYNC) == FFCLOCK_STA_UNSYNC) &&
688227723Slstewart		    ((cest->status & FFCLOCK_STA_UNSYNC) == 0) &&
689227723Slstewart		    ((cest->status & FFCLOCK_STA_WARMUP) == FFCLOCK_STA_WARMUP)) {
690227723Slstewart			if (forward_jump)
691227723Slstewart				bintime_add(&ffclock_boottime, &gap_lerp);
692227723Slstewart			else
693227723Slstewart				bintime_sub(&ffclock_boottime, &gap_lerp);
694227723Slstewart			ffth->tick_time_lerp = ffth->tick_time;
695227723Slstewart			bintime_clear(&gap_lerp);
696227723Slstewart		}
697227723Slstewart
698227723Slstewart		ffclock_status = cest->status;
699227723Slstewart		ffth->period_lerp = cest->period;
700227723Slstewart
701227723Slstewart		/*
702227723Slstewart		 * Compute corrected period used for the linear interpolation of
703227723Slstewart		 * time. The rate of linear interpolation is capped to 5000PPM
704227723Slstewart		 * (5ms/s).
705227723Slstewart		 */
706227723Slstewart		if (bintime_isset(&gap_lerp)) {
707227723Slstewart			ffdelta = cest->update_ffcount;
708227723Slstewart			ffdelta -= fftimehands->cest.update_ffcount;
709227723Slstewart			ffclock_convert_delta(ffdelta, cest->period, &bt);
710227723Slstewart			polling = bt.sec;
711227723Slstewart			bt.sec = 0;
712227723Slstewart			bt.frac = 5000000 * (uint64_t)18446744073LL;
713227723Slstewart			bintime_mul(&bt, polling);
714227723Slstewart			if (bintime_cmp(&gap_lerp, &bt, >))
715227723Slstewart				gap_lerp = bt;
716227723Slstewart
717227723Slstewart			/* Approximate 1 sec by 1-(1/2^64) to ease arithmetic */
718227723Slstewart			frac = 0;
719227723Slstewart			if (gap_lerp.sec > 0) {
720227723Slstewart				frac -= 1;
721227723Slstewart				frac /= ffdelta / gap_lerp.sec;
722227723Slstewart			}
723227723Slstewart			frac += gap_lerp.frac / ffdelta;
724227723Slstewart
725227723Slstewart			if (forward_jump)
726227723Slstewart				ffth->period_lerp += frac;
727227723Slstewart			else
728227723Slstewart				ffth->period_lerp -= frac;
729227723Slstewart		}
730227723Slstewart
731227723Slstewart		ffclock_updated = 0;
732227723Slstewart	}
733227723Slstewart	if (++ogen == 0)
734227723Slstewart		ogen = 1;
735227723Slstewart	ffth->gen = ogen;
736227723Slstewart	fftimehands = ffth;
737227723Slstewart}
738227723Slstewart
739227723Slstewart/*
740227723Slstewart * Adjust the fftimehands when the timecounter is changed. Stating the obvious,
741227723Slstewart * the old and new hardware counter cannot be read simultaneously. tc_windup()
742227723Slstewart * does read the two counters 'back to back', but a few cycles are effectively
743227723Slstewart * lost, and not accumulated in tick_ffcount. This is a fairly radical
744227723Slstewart * operation for a feed-forward synchronization daemon, and it is its job to not
745227723Slstewart * pushing irrelevant data to the kernel. Because there is no locking here,
746227723Slstewart * simply force to ignore pending or next update to give daemon a chance to
747227723Slstewart * realize the counter has changed.
748227723Slstewart */
749227723Slstewartstatic void
750227723Slstewartffclock_change_tc(struct timehands *th)
751227723Slstewart{
752227723Slstewart	struct fftimehands *ffth;
753227723Slstewart	struct ffclock_estimate *cest;
754227723Slstewart	struct timecounter *tc;
755227723Slstewart	uint8_t ogen;
756227723Slstewart
757227723Slstewart	tc = th->th_counter;
758227723Slstewart	ffth = fftimehands->next;
759227723Slstewart	ogen = ffth->gen;
760227723Slstewart	ffth->gen = 0;
761227723Slstewart
762227723Slstewart	cest = &ffth->cest;
763227723Slstewart	bcopy(&(fftimehands->cest), cest, sizeof(struct ffclock_estimate));
764227723Slstewart	cest->period = ((1ULL << 63) / tc->tc_frequency ) << 1;
765227723Slstewart	cest->errb_abs = 0;
766227723Slstewart	cest->errb_rate = 0;
767227723Slstewart	cest->status |= FFCLOCK_STA_UNSYNC;
768227723Slstewart
769227723Slstewart	ffth->tick_ffcount = fftimehands->tick_ffcount;
770227723Slstewart	ffth->tick_time_lerp = fftimehands->tick_time_lerp;
771227723Slstewart	ffth->tick_time = fftimehands->tick_time;
772227723Slstewart	ffth->period_lerp = cest->period;
773227723Slstewart
774227723Slstewart	/* Do not lock but ignore next update from synchronization daemon. */
775227723Slstewart	ffclock_updated--;
776227723Slstewart
777227723Slstewart	if (++ogen == 0)
778227723Slstewart		ogen = 1;
779227723Slstewart	ffth->gen = ogen;
780227723Slstewart	fftimehands = ffth;
781227723Slstewart}
782227723Slstewart
783227723Slstewart/*
784227723Slstewart * Retrieve feed-forward counter and time of last kernel tick.
785227723Slstewart */
786227723Slstewartvoid
787227723Slstewartffclock_last_tick(ffcounter *ffcount, struct bintime *bt, uint32_t flags)
788227723Slstewart{
789227723Slstewart	struct fftimehands *ffth;
790227723Slstewart	uint8_t gen;
791227723Slstewart
792227723Slstewart	/*
793227723Slstewart	 * No locking but check generation has not changed. Also need to make
794227723Slstewart	 * sure ffdelta is positive, i.e. ffcount > tick_ffcount.
795227723Slstewart	 */
796227723Slstewart	do {
797227723Slstewart		ffth = fftimehands;
798227723Slstewart		gen = ffth->gen;
799227723Slstewart		if ((flags & FFCLOCK_LERP) == FFCLOCK_LERP)
800227723Slstewart			*bt = ffth->tick_time_lerp;
801227723Slstewart		else
802227723Slstewart			*bt = ffth->tick_time;
803227723Slstewart		*ffcount = ffth->tick_ffcount;
804227723Slstewart	} while (gen == 0 || gen != ffth->gen);
805227723Slstewart}
806227723Slstewart
807227723Slstewart/*
808227723Slstewart * Absolute clock conversion. Low level function to convert ffcounter to
809227723Slstewart * bintime. The ffcounter is converted using the current ffclock period estimate
810227723Slstewart * or the "interpolated period" to ensure monotonicity.
811227723Slstewart * NOTE: this conversion may have been deferred, and the clock updated since the
812227723Slstewart * hardware counter has been read.
813227723Slstewart */
814227723Slstewartvoid
815227723Slstewartffclock_convert_abs(ffcounter ffcount, struct bintime *bt, uint32_t flags)
816227723Slstewart{
817227723Slstewart	struct fftimehands *ffth;
818227723Slstewart	struct bintime bt2;
819227723Slstewart	ffcounter ffdelta;
820227723Slstewart	uint8_t gen;
821227723Slstewart
822227723Slstewart	/*
823227723Slstewart	 * No locking but check generation has not changed. Also need to make
824227723Slstewart	 * sure ffdelta is positive, i.e. ffcount > tick_ffcount.
825227723Slstewart	 */
826227723Slstewart	do {
827227723Slstewart		ffth = fftimehands;
828227723Slstewart		gen = ffth->gen;
829227723Slstewart		if (ffcount > ffth->tick_ffcount)
830227723Slstewart			ffdelta = ffcount - ffth->tick_ffcount;
831227723Slstewart		else
832227723Slstewart			ffdelta = ffth->tick_ffcount - ffcount;
833227723Slstewart
834227723Slstewart		if ((flags & FFCLOCK_LERP) == FFCLOCK_LERP) {
835227723Slstewart			*bt = ffth->tick_time_lerp;
836227723Slstewart			ffclock_convert_delta(ffdelta, ffth->period_lerp, &bt2);
837227723Slstewart		} else {
838227723Slstewart			*bt = ffth->tick_time;
839227723Slstewart			ffclock_convert_delta(ffdelta, ffth->cest.period, &bt2);
840227723Slstewart		}
841227723Slstewart
842227723Slstewart		if (ffcount > ffth->tick_ffcount)
843227723Slstewart			bintime_add(bt, &bt2);
844227723Slstewart		else
845227723Slstewart			bintime_sub(bt, &bt2);
846227723Slstewart	} while (gen == 0 || gen != ffth->gen);
847227723Slstewart}
848227723Slstewart
849227723Slstewart/*
850227723Slstewart * Difference clock conversion.
851227723Slstewart * Low level function to Convert a time interval measured in RAW counter units
852227723Slstewart * into bintime. The difference clock allows measuring small intervals much more
853227723Slstewart * reliably than the absolute clock.
854227723Slstewart */
855227723Slstewartvoid
856227723Slstewartffclock_convert_diff(ffcounter ffdelta, struct bintime *bt)
857227723Slstewart{
858227723Slstewart	struct fftimehands *ffth;
859227723Slstewart	uint8_t gen;
860227723Slstewart
861227723Slstewart	/* No locking but check generation has not changed. */
862227723Slstewart	do {
863227723Slstewart		ffth = fftimehands;
864227723Slstewart		gen = ffth->gen;
865227723Slstewart		ffclock_convert_delta(ffdelta, ffth->cest.period, bt);
866227723Slstewart	} while (gen == 0 || gen != ffth->gen);
867227723Slstewart}
868227723Slstewart
869227723Slstewart/*
870227723Slstewart * Access to current ffcounter value.
871227723Slstewart */
872227723Slstewartvoid
873227723Slstewartffclock_read_counter(ffcounter *ffcount)
874227723Slstewart{
875227723Slstewart	struct timehands *th;
876227723Slstewart	struct fftimehands *ffth;
877227723Slstewart	unsigned int gen, delta;
878227723Slstewart
879227723Slstewart	/*
880227723Slstewart	 * ffclock_windup() called from tc_windup(), safe to rely on
881227723Slstewart	 * th->th_generation only, for correct delta and ffcounter.
882227723Slstewart	 */
883227723Slstewart	do {
884227723Slstewart		th = timehands;
885227723Slstewart		gen = th->th_generation;
886227723Slstewart		ffth = fftimehands;
887227723Slstewart		delta = tc_delta(th);
888227723Slstewart		*ffcount = ffth->tick_ffcount;
889227723Slstewart	} while (gen == 0 || gen != th->th_generation);
890227723Slstewart
891227723Slstewart	*ffcount += delta;
892227723Slstewart}
893227747Slstewart
894227747Slstewartvoid
895227747Slstewartbinuptime(struct bintime *bt)
896227747Slstewart{
897227747Slstewart
898228123Slstewart	binuptime_fromclock(bt, sysclock_active);
899227747Slstewart}
900227747Slstewart
901227747Slstewartvoid
902227747Slstewartnanouptime(struct timespec *tsp)
903227747Slstewart{
904227747Slstewart
905228123Slstewart	nanouptime_fromclock(tsp, sysclock_active);
906227747Slstewart}
907227747Slstewart
908227747Slstewartvoid
909227747Slstewartmicrouptime(struct timeval *tvp)
910227747Slstewart{
911227747Slstewart
912228123Slstewart	microuptime_fromclock(tvp, sysclock_active);
913227747Slstewart}
914227747Slstewart
915227747Slstewartvoid
916227747Slstewartbintime(struct bintime *bt)
917227747Slstewart{
918227747Slstewart
919228123Slstewart	bintime_fromclock(bt, sysclock_active);
920227747Slstewart}
921227747Slstewart
922227747Slstewartvoid
923227747Slstewartnanotime(struct timespec *tsp)
924227747Slstewart{
925227747Slstewart
926228123Slstewart	nanotime_fromclock(tsp, sysclock_active);
927227747Slstewart}
928227747Slstewart
929227747Slstewartvoid
930227747Slstewartmicrotime(struct timeval *tvp)
931227747Slstewart{
932227747Slstewart
933228123Slstewart	microtime_fromclock(tvp, sysclock_active);
934227747Slstewart}
935227747Slstewart
936227747Slstewartvoid
937227747Slstewartgetbinuptime(struct bintime *bt)
938227747Slstewart{
939227747Slstewart
940228123Slstewart	getbinuptime_fromclock(bt, sysclock_active);
941227747Slstewart}
942227747Slstewart
943227747Slstewartvoid
944227747Slstewartgetnanouptime(struct timespec *tsp)
945227747Slstewart{
946227747Slstewart
947228123Slstewart	getnanouptime_fromclock(tsp, sysclock_active);
948227747Slstewart}
949227747Slstewart
950227747Slstewartvoid
951227747Slstewartgetmicrouptime(struct timeval *tvp)
952227747Slstewart{
953227747Slstewart
954228123Slstewart	getmicrouptime_fromclock(tvp, sysclock_active);
955227747Slstewart}
956227747Slstewart
957227747Slstewartvoid
958227747Slstewartgetbintime(struct bintime *bt)
959227747Slstewart{
960227747Slstewart
961228123Slstewart	getbintime_fromclock(bt, sysclock_active);
962227747Slstewart}
963227747Slstewart
964227747Slstewartvoid
965227747Slstewartgetnanotime(struct timespec *tsp)
966227747Slstewart{
967227747Slstewart
968228123Slstewart	getnanotime_fromclock(tsp, sysclock_active);
969227747Slstewart}
970227747Slstewart
971227747Slstewartvoid
972227747Slstewartgetmicrotime(struct timeval *tvp)
973227747Slstewart{
974227747Slstewart
975228123Slstewart	getmicrouptime_fromclock(tvp, sysclock_active);
976227747Slstewart}
977228856Slstewart
978227723Slstewart#endif /* FFCLOCK */
979227723Slstewart
980227723Slstewart/*
981238537Sgnn * This is a clone of getnanotime and used for walltimestamps.
982238537Sgnn * The dtrace_ prefix prevents fbt from creating probes for
983238537Sgnn * it so walltimestamp can be safely used in all fbt probes.
984238537Sgnn */
985238537Sgnnvoid
986238537Sgnndtrace_getnanotime(struct timespec *tsp)
987238537Sgnn{
988238537Sgnn	struct timehands *th;
989238537Sgnn	u_int gen;
990238537Sgnn
991238537Sgnn	do {
992238537Sgnn		th = timehands;
993238537Sgnn		gen = th->th_generation;
994238537Sgnn		*tsp = th->th_nanotime;
995238537Sgnn	} while (gen == 0 || gen != th->th_generation);
996238537Sgnn}
997238537Sgnn
998238537Sgnn/*
999228856Slstewart * System clock currently providing time to the system. Modifiable via sysctl
1000228856Slstewart * when the FFCLOCK option is defined.
1001228856Slstewart */
1002228856Slstewartint sysclock_active = SYSCLOCK_FBCK;
1003228856Slstewart
1004228856Slstewart/* Internal NTP status and error estimates. */
1005228856Slstewartextern int time_status;
1006228856Slstewartextern long time_esterror;
1007228856Slstewart
1008228856Slstewart/*
1009228856Slstewart * Take a snapshot of sysclock data which can be used to compare system clocks
1010228856Slstewart * and generate timestamps after the fact.
1011228856Slstewart */
1012228856Slstewartvoid
1013228856Slstewartsysclock_getsnapshot(struct sysclock_snap *clock_snap, int fast)
1014228856Slstewart{
1015228856Slstewart	struct fbclock_info *fbi;
1016228856Slstewart	struct timehands *th;
1017228856Slstewart	struct bintime bt;
1018228856Slstewart	unsigned int delta, gen;
1019228856Slstewart#ifdef FFCLOCK
1020228856Slstewart	ffcounter ffcount;
1021228856Slstewart	struct fftimehands *ffth;
1022228856Slstewart	struct ffclock_info *ffi;
1023228856Slstewart	struct ffclock_estimate cest;
1024228856Slstewart
1025228856Slstewart	ffi = &clock_snap->ff_info;
1026228856Slstewart#endif
1027228856Slstewart
1028228856Slstewart	fbi = &clock_snap->fb_info;
1029228856Slstewart	delta = 0;
1030228856Slstewart
1031228856Slstewart	do {
1032228856Slstewart		th = timehands;
1033228856Slstewart		gen = th->th_generation;
1034228856Slstewart		fbi->th_scale = th->th_scale;
1035228856Slstewart		fbi->tick_time = th->th_offset;
1036228856Slstewart#ifdef FFCLOCK
1037228856Slstewart		ffth = fftimehands;
1038228856Slstewart		ffi->tick_time = ffth->tick_time_lerp;
1039228856Slstewart		ffi->tick_time_lerp = ffth->tick_time_lerp;
1040228856Slstewart		ffi->period = ffth->cest.period;
1041228856Slstewart		ffi->period_lerp = ffth->period_lerp;
1042228856Slstewart		clock_snap->ffcount = ffth->tick_ffcount;
1043228856Slstewart		cest = ffth->cest;
1044228856Slstewart#endif
1045228856Slstewart		if (!fast)
1046228856Slstewart			delta = tc_delta(th);
1047228856Slstewart	} while (gen == 0 || gen != th->th_generation);
1048228856Slstewart
1049228856Slstewart	clock_snap->delta = delta;
1050228856Slstewart	clock_snap->sysclock_active = sysclock_active;
1051228856Slstewart
1052228856Slstewart	/* Record feedback clock status and error. */
1053228856Slstewart	clock_snap->fb_info.status = time_status;
1054228856Slstewart	/* XXX: Very crude estimate of feedback clock error. */
1055228856Slstewart	bt.sec = time_esterror / 1000000;
1056228856Slstewart	bt.frac = ((time_esterror - bt.sec) * 1000000) *
1057228856Slstewart	    (uint64_t)18446744073709ULL;
1058228856Slstewart	clock_snap->fb_info.error = bt;
1059228856Slstewart
1060228856Slstewart#ifdef FFCLOCK
1061228856Slstewart	if (!fast)
1062228856Slstewart		clock_snap->ffcount += delta;
1063228856Slstewart
1064228856Slstewart	/* Record feed-forward clock leap second adjustment. */
1065228856Slstewart	ffi->leapsec_adjustment = cest.leapsec_total;
1066228856Slstewart	if (clock_snap->ffcount > cest.leapsec_next)
1067228856Slstewart		ffi->leapsec_adjustment -= cest.leapsec;
1068228856Slstewart
1069228856Slstewart	/* Record feed-forward clock status and error. */
1070228856Slstewart	clock_snap->ff_info.status = cest.status;
1071228856Slstewart	ffcount = clock_snap->ffcount - cest.update_ffcount;
1072228856Slstewart	ffclock_convert_delta(ffcount, cest.period, &bt);
1073228856Slstewart	/* 18446744073709 = int(2^64/1e12), err_bound_rate in [ps/s]. */
1074228856Slstewart	bintime_mul(&bt, cest.errb_rate * (uint64_t)18446744073709ULL);
1075228856Slstewart	/* 18446744073 = int(2^64 / 1e9), since err_abs in [ns]. */
1076228856Slstewart	bintime_addx(&bt, cest.errb_abs * (uint64_t)18446744073ULL);
1077228856Slstewart	clock_snap->ff_info.error = bt;
1078228856Slstewart#endif
1079228856Slstewart}
1080228856Slstewart
1081228856Slstewart/*
1082228856Slstewart * Convert a sysclock snapshot into a struct bintime based on the specified
1083228856Slstewart * clock source and flags.
1084228856Slstewart */
1085228856Slstewartint
1086228856Slstewartsysclock_snap2bintime(struct sysclock_snap *cs, struct bintime *bt,
1087228856Slstewart    int whichclock, uint32_t flags)
1088228856Slstewart{
1089228856Slstewart#ifdef FFCLOCK
1090228856Slstewart	struct bintime bt2;
1091228856Slstewart	uint64_t period;
1092228856Slstewart#endif
1093228856Slstewart
1094228856Slstewart	switch (whichclock) {
1095228856Slstewart	case SYSCLOCK_FBCK:
1096228856Slstewart		*bt = cs->fb_info.tick_time;
1097228856Slstewart
1098228856Slstewart		/* If snapshot was created with !fast, delta will be >0. */
1099228856Slstewart		if (cs->delta > 0)
1100228856Slstewart			bintime_addx(bt, cs->fb_info.th_scale * cs->delta);
1101228856Slstewart
1102228856Slstewart		if ((flags & FBCLOCK_UPTIME) == 0)
1103228856Slstewart			bintime_add(bt, &boottimebin);
1104228856Slstewart		break;
1105228856Slstewart#ifdef FFCLOCK
1106228856Slstewart	case SYSCLOCK_FFWD:
1107228856Slstewart		if (flags & FFCLOCK_LERP) {
1108228856Slstewart			*bt = cs->ff_info.tick_time_lerp;
1109228856Slstewart			period = cs->ff_info.period_lerp;
1110228856Slstewart		} else {
1111228856Slstewart			*bt = cs->ff_info.tick_time;
1112228856Slstewart			period = cs->ff_info.period;
1113228856Slstewart		}
1114228856Slstewart
1115228856Slstewart		/* If snapshot was created with !fast, delta will be >0. */
1116228856Slstewart		if (cs->delta > 0) {
1117228856Slstewart			ffclock_convert_delta(cs->delta, period, &bt2);
1118228856Slstewart			bintime_add(bt, &bt2);
1119228856Slstewart		}
1120228856Slstewart
1121228856Slstewart		/* Leap second adjustment. */
1122228856Slstewart		if (flags & FFCLOCK_LEAPSEC)
1123228856Slstewart			bt->sec -= cs->ff_info.leapsec_adjustment;
1124228856Slstewart
1125228856Slstewart		/* Boot time adjustment, for uptime/monotonic clocks. */
1126228856Slstewart		if (flags & FFCLOCK_UPTIME)
1127228856Slstewart			bintime_sub(bt, &ffclock_boottime);
1128231341Skevlo		break;
1129228856Slstewart#endif
1130228856Slstewart	default:
1131228856Slstewart		return (EINVAL);
1132228856Slstewart		break;
1133228856Slstewart	}
1134228856Slstewart
1135228856Slstewart	return (0);
1136228856Slstewart}
1137228856Slstewart
1138228856Slstewart/*
1139118987Sphk * Initialize a new timecounter and possibly use it.
114095661Sphk */
114133690Sphkvoid
114258377Sphktc_init(struct timecounter *tc)
114333690Sphk{
1144122610Sphk	u_int u;
1145159669Sdwmalone	struct sysctl_oid *tc_root;
114633690Sphk
1147119716Sphk	u = tc->tc_frequency / tc->tc_counter_mask;
1148122610Sphk	/* XXX: We need some margin here, 10% is a guess */
1149122610Sphk	u *= 11;
1150122610Sphk	u /= 10;
1151119716Sphk	if (u > hz && tc->tc_quality >= 0) {
1152119716Sphk		tc->tc_quality = -2000;
1153119716Sphk		if (bootverbose) {
1154119716Sphk			printf("Timecounter \"%s\" frequency %ju Hz",
1155122610Sphk			    tc->tc_name, (uintmax_t)tc->tc_frequency);
1156119716Sphk			printf(" -- Insufficient hz, needs at least %u\n", u);
1157119716Sphk		}
1158119716Sphk	} else if (tc->tc_quality >= 0 || bootverbose) {
1159122610Sphk		printf("Timecounter \"%s\" frequency %ju Hz quality %d\n",
1160122610Sphk		    tc->tc_name, (uintmax_t)tc->tc_frequency,
1161118987Sphk		    tc->tc_quality);
1162119716Sphk	}
1163102933Sphk
116495530Sphk	tc->tc_next = timecounters;
116595530Sphk	timecounters = tc;
1166122610Sphk	/*
1167159669Sdwmalone	 * Set up sysctl tree for this counter.
1168159669Sdwmalone	 */
1169159669Sdwmalone	tc_root = SYSCTL_ADD_NODE(NULL,
1170159669Sdwmalone	    SYSCTL_STATIC_CHILDREN(_kern_timecounter_tc), OID_AUTO, tc->tc_name,
1171159669Sdwmalone	    CTLFLAG_RW, 0, "timecounter description");
1172159669Sdwmalone	SYSCTL_ADD_UINT(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO,
1173159669Sdwmalone	    "mask", CTLFLAG_RD, &(tc->tc_counter_mask), 0,
1174159669Sdwmalone	    "mask for implemented bits");
1175159669Sdwmalone	SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO,
1176159669Sdwmalone	    "counter", CTLTYPE_UINT | CTLFLAG_RD, tc, sizeof(*tc),
1177159669Sdwmalone	    sysctl_kern_timecounter_get, "IU", "current timecounter value");
1178159669Sdwmalone	SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO,
1179217616Smdf	    "frequency", CTLTYPE_U64 | CTLFLAG_RD, tc, sizeof(*tc),
1180170289Sdwmalone	     sysctl_kern_timecounter_freq, "QU", "timecounter frequency");
1181159669Sdwmalone	SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO,
1182159669Sdwmalone	    "quality", CTLFLAG_RD, &(tc->tc_quality), 0,
1183159669Sdwmalone	    "goodness of time counter");
1184159669Sdwmalone	/*
1185122610Sphk	 * Never automatically use a timecounter with negative quality.
1186122610Sphk	 * Even though we run on the dummy counter, switching here may be
1187122610Sphk	 * worse since this timecounter may not be monotonous.
1188122610Sphk	 */
1189118987Sphk	if (tc->tc_quality < 0)
1190118987Sphk		return;
1191118987Sphk	if (tc->tc_quality < timecounter->tc_quality)
1192118987Sphk		return;
1193122610Sphk	if (tc->tc_quality == timecounter->tc_quality &&
1194122610Sphk	    tc->tc_frequency < timecounter->tc_frequency)
1195122610Sphk		return;
1196122610Sphk	(void)tc->tc_get_timecount(tc);
1197122610Sphk	(void)tc->tc_get_timecount(tc);
119833690Sphk	timecounter = tc;
119933690Sphk}
120033690Sphk
120195821Sphk/* Report the frequency of the current timecounter. */
1202209390Seduint64_t
120395530Sphktc_getfrequency(void)
120495530Sphk{
120595530Sphk
120695661Sphk	return (timehands->th_counter->tc_frequency);
120795530Sphk}
120895530Sphk
120995821Sphk/*
1210116756Simp * Step our concept of UTC.  This is done by modifying our estimate of
1211124812Sphk * when we booted.
1212124812Sphk * XXX: not locked.
121395661Sphk */
121433690Sphkvoid
121558377Sphktc_setclock(struct timespec *ts)
121633690Sphk{
1217156270Sphk	struct timespec tbef, taft;
1218124812Sphk	struct bintime bt, bt2;
121933690Sphk
1220155534Sphk	cpu_tick_calibrate(1);
1221156270Sphk	nanotime(&tbef);
1222156270Sphk	timespec2bintime(ts, &bt);
1223124812Sphk	binuptime(&bt2);
1224124812Sphk	bintime_sub(&bt, &bt2);
1225124812Sphk	bintime_add(&bt2, &boottimebin);
1226124812Sphk	boottimebin = bt;
1227124812Sphk	bintime2timeval(&bt, &boottime);
122895821Sphk
122995821Sphk	/* XXX fiddle all the little crinkly bits around the fiords... */
123058377Sphk	tc_windup();
1231156270Sphk	nanotime(&taft);
1232124812Sphk	if (timestepwarnings) {
1233156270Sphk		log(LOG_INFO,
1234156270Sphk		    "Time stepped from %jd.%09ld to %jd.%09ld (%jd.%09ld)\n",
1235156270Sphk		    (intmax_t)tbef.tv_sec, tbef.tv_nsec,
1236156270Sphk		    (intmax_t)taft.tv_sec, taft.tv_nsec,
1237124842Sphk		    (intmax_t)ts->tv_sec, ts->tv_nsec);
1238124812Sphk	}
1239155534Sphk	cpu_tick_calibrate(1);
124033690Sphk}
124133690Sphk
124295821Sphk/*
124395821Sphk * Initialize the next struct timehands in the ring and make
124495661Sphk * it the active timehands.  Along the way we might switch to a different
124595661Sphk * timecounter and/or do seconds processing in NTP.  Slightly magic.
124695661Sphk */
124748887Sbdestatic void
124858377Sphktc_windup(void)
124933690Sphk{
125095821Sphk	struct bintime bt;
125195661Sphk	struct timehands *th, *tho;
1252209390Sed	uint64_t scale;
125395821Sphk	u_int delta, ncount, ogen;
125490362Sphk	int i;
1255116841Simp	time_t t;
125633690Sphk
125795821Sphk	/*
125895661Sphk	 * Make the next timehands a copy of the current one, but do not
125995661Sphk	 * overwrite the generation or next pointer.  While we update
126095661Sphk	 * the contents, the generation must be zero.
126195661Sphk	 */
126295661Sphk	tho = timehands;
126395661Sphk	th = tho->th_next;
126495661Sphk	ogen = th->th_generation;
126595661Sphk	th->th_generation = 0;
126695821Sphk	bcopy(tho, th, offsetof(struct timehands, th_generation));
126795661Sphk
126895821Sphk	/*
126995661Sphk	 * Capture a timecounter delta on the current timecounter and if
127095661Sphk	 * changing timecounters, a counter value from the new timecounter.
127195661Sphk	 * Update the offset fields accordingly.
127295661Sphk	 */
127395661Sphk	delta = tc_delta(th);
127495661Sphk	if (th->th_counter != timecounter)
127595530Sphk		ncount = timecounter->tc_get_timecount(timecounter);
127695821Sphk	else
127795821Sphk		ncount = 0;
1278227723Slstewart#ifdef FFCLOCK
1279227723Slstewart	ffclock_windup(delta);
1280227723Slstewart#endif
128195661Sphk	th->th_offset_count += delta;
128295661Sphk	th->th_offset_count &= th->th_counter->tc_counter_mask;
1283215665Scperciva	while (delta > th->th_counter->tc_frequency) {
1284215665Scperciva		/* Eat complete unadjusted seconds. */
1285215665Scperciva		delta -= th->th_counter->tc_frequency;
1286215665Scperciva		th->th_offset.sec++;
1287215665Scperciva	}
1288215665Scperciva	if ((delta > th->th_counter->tc_frequency / 2) &&
1289215732Scperciva	    (th->th_scale * delta < ((uint64_t)1 << 63))) {
1290215665Scperciva		/* The product th_scale * delta just barely overflows. */
1291215665Scperciva		th->th_offset.sec++;
1292215665Scperciva	}
129395661Sphk	bintime_addx(&th->th_offset, th->th_scale * delta);
129495661Sphk
129595821Sphk	/*
129695661Sphk	 * Hardware latching timecounters may not generate interrupts on
129795661Sphk	 * PPS events, so instead we poll them.  There is a finite risk that
129895661Sphk	 * the hardware might capture a count which is later than the one we
129995661Sphk	 * got above, and therefore possibly in the next NTP second which might
130095661Sphk	 * have a different rate than the current NTP second.  It doesn't
130195661Sphk	 * matter in practice.
130237382Sphk	 */
130395661Sphk	if (tho->th_counter->tc_poll_pps)
130495661Sphk		tho->th_counter->tc_poll_pps(tho->th_counter);
130595661Sphk
1306119183Simp	/*
1307119183Simp	 * Deal with NTP second processing.  The for loop normally
1308119183Simp	 * iterates at most once, but in extreme situations it might
1309119183Simp	 * keep NTP sane if timeouts are not run for several seconds.
1310119183Simp	 * At boot, the time step can be large when the TOD hardware
1311119183Simp	 * has been read, so on really large steps, we call
1312119183Simp	 * ntp_update_second only twice.  We need to call it twice in
1313119183Simp	 * case we missed a leap second.
1314116841Simp	 */
1315116841Simp	bt = th->th_offset;
1316116841Simp	bintime_add(&bt, &boottimebin);
1317119160Simp	i = bt.sec - tho->th_microtime.tv_sec;
1318119160Simp	if (i > LARGE_STEP)
1319119160Simp		i = 2;
1320119160Simp	for (; i > 0; i--) {
1321116841Simp		t = bt.sec;
1322116841Simp		ntp_update_second(&th->th_adjustment, &bt.sec);
1323116841Simp		if (bt.sec != t)
1324116841Simp			boottimebin.sec += bt.sec - t;
1325116841Simp	}
1326119183Simp	/* Update the UTC timestamps used by the get*() functions. */
1327119183Simp	/* XXX shouldn't do this here.  Should force non-`get' versions. */
1328119183Simp	bintime2timeval(&bt, &th->th_microtime);
1329119183Simp	bintime2timespec(&bt, &th->th_nanotime);
133095661Sphk
133195661Sphk	/* Now is a good time to change timecounters. */
133295661Sphk	if (th->th_counter != timecounter) {
1333224042Sjkim#ifndef __arm__
1334224042Sjkim		if ((timecounter->tc_flags & TC_FLAGS_C3STOP) != 0)
1335224042Sjkim			cpu_disable_deep_sleep++;
1336224042Sjkim		if ((th->th_counter->tc_flags & TC_FLAGS_C3STOP) != 0)
1337224042Sjkim			cpu_disable_deep_sleep--;
1338224042Sjkim#endif
133995661Sphk		th->th_counter = timecounter;
134095661Sphk		th->th_offset_count = ncount;
1341212603Smav		tc_min_ticktock_freq = max(1, timecounter->tc_frequency /
1342212603Smav		    (((uint64_t)timecounter->tc_counter_mask + 1) / 3));
1343227723Slstewart#ifdef FFCLOCK
1344227723Slstewart		ffclock_change_tc(th);
1345227723Slstewart#endif
134695551Sphk	}
134734618Sphk
1348210226Strasz	/*-
134995661Sphk	 * Recalculate the scaling factor.  We want the number of 1/2^64
135095661Sphk	 * fractions of a second per period of the hardware counter, taking
135195661Sphk	 * into account the th_adjustment factor which the NTP PLL/adjtime(2)
135295661Sphk	 * processing provides us with.
135395661Sphk	 *
135495661Sphk	 * The th_adjustment is nanoseconds per second with 32 bit binary
1355117148Sphk	 * fraction and we want 64 bit binary fraction of second:
135695661Sphk	 *
135795661Sphk	 *	 x = a * 2^32 / 10^9 = a * 4.294967296
135895661Sphk	 *
135995661Sphk	 * The range of th_adjustment is +/- 5000PPM so inside a 64bit int
1360155534Sphk	 * we can only multiply by about 850 without overflowing, that
1361155534Sphk	 * leaves no suitably precise fractions for multiply before divide.
136295661Sphk	 *
136395661Sphk	 * Divide before multiply with a fraction of 2199/512 results in a
136495661Sphk	 * systematic undercompensation of 10PPM of th_adjustment.  On a
136595661Sphk	 * 5000PPM adjustment this is a 0.05PPM error.  This is acceptable.
136695661Sphk 	 *
136795661Sphk	 * We happily sacrifice the lowest of the 64 bits of our result
136895661Sphk	 * to the goddess of code clarity.
136995821Sphk	 *
137095661Sphk	 */
1371209390Sed	scale = (uint64_t)1 << 63;
137295661Sphk	scale += (th->th_adjustment / 1024) * 2199;
137395661Sphk	scale /= th->th_counter->tc_frequency;
137495661Sphk	th->th_scale = scale * 2;
137595661Sphk
137695821Sphk	/*
137795821Sphk	 * Now that the struct timehands is again consistent, set the new
137895661Sphk	 * generation number, making sure to not make it zero.
137995661Sphk	 */
138095661Sphk	if (++ogen == 0)
138195821Sphk		ogen = 1;
138295661Sphk	th->th_generation = ogen;
138395661Sphk
138495821Sphk	/* Go live with the new struct timehands. */
1385227747Slstewart#ifdef FFCLOCK
1386227747Slstewart	switch (sysclock_active) {
1387227747Slstewart	case SYSCLOCK_FBCK:
1388227747Slstewart#endif
1389227747Slstewart		time_second = th->th_microtime.tv_sec;
1390227747Slstewart		time_uptime = th->th_offset.sec;
1391227747Slstewart#ifdef FFCLOCK
1392227747Slstewart		break;
1393227747Slstewart	case SYSCLOCK_FFWD:
1394227747Slstewart		time_second = fftimehands->tick_time_lerp.sec;
1395227747Slstewart		time_uptime = fftimehands->tick_time_lerp.sec - ffclock_boottime.sec;
1396227747Slstewart		break;
1397227747Slstewart	}
1398227747Slstewart#endif
1399227747Slstewart
140095661Sphk	timehands = th;
1401237474Skib	timekeep_push_vdso();
140233690Sphk}
140333690Sphk
140495821Sphk/* Report or change the active timecounter hardware. */
140548887Sbdestatic int
140662573Sphksysctl_kern_timecounter_hardware(SYSCTL_HANDLER_ARGS)
140748887Sbde{
140848887Sbde	char newname[32];
140948887Sbde	struct timecounter *newtc, *tc;
141048887Sbde	int error;
141144666Sphk
141295530Sphk	tc = timecounter;
1413105354Srobert	strlcpy(newname, tc->tc_name, sizeof(newname));
1414105354Srobert
141548887Sbde	error = sysctl_handle_string(oidp, &newname[0], sizeof(newname), req);
141695821Sphk	if (error != 0 || req->newptr == NULL ||
141795821Sphk	    strcmp(newname, tc->tc_name) == 0)
141895821Sphk		return (error);
141995530Sphk	for (newtc = timecounters; newtc != NULL; newtc = newtc->tc_next) {
142095821Sphk		if (strcmp(newname, newtc->tc_name) != 0)
142195530Sphk			continue;
142295821Sphk
142395530Sphk		/* Warm up new timecounter. */
142495530Sphk		(void)newtc->tc_get_timecount(newtc);
142595530Sphk		(void)newtc->tc_get_timecount(newtc);
142695821Sphk
142795530Sphk		timecounter = newtc;
1428237474Skib		timekeep_push_vdso();
142995530Sphk		return (0);
143048887Sbde	}
143195530Sphk	return (EINVAL);
143248887Sbde}
143348887Sbde
143448887SbdeSYSCTL_PROC(_kern_timecounter, OID_AUTO, hardware, CTLTYPE_STRING | CTLFLAG_RW,
1435215283Sbrucec    0, 0, sysctl_kern_timecounter_hardware, "A",
1436215283Sbrucec    "Timecounter hardware selected");
143748887Sbde
1438118987Sphk
1439118987Sphk/* Report or change the active timecounter hardware. */
1440118987Sphkstatic int
1441118987Sphksysctl_kern_timecounter_choice(SYSCTL_HANDLER_ARGS)
1442118987Sphk{
1443118987Sphk	char buf[32], *spc;
1444118987Sphk	struct timecounter *tc;
1445118987Sphk	int error;
1446118987Sphk
1447118987Sphk	spc = "";
1448118987Sphk	error = 0;
1449118987Sphk	for (tc = timecounters; error == 0 && tc != NULL; tc = tc->tc_next) {
1450118987Sphk		sprintf(buf, "%s%s(%d)",
1451118987Sphk		    spc, tc->tc_name, tc->tc_quality);
1452118987Sphk		error = SYSCTL_OUT(req, buf, strlen(buf));
1453118987Sphk		spc = " ";
1454118987Sphk	}
1455118987Sphk	return (error);
1456118987Sphk}
1457118987Sphk
1458118987SphkSYSCTL_PROC(_kern_timecounter, OID_AUTO, choice, CTLTYPE_STRING | CTLFLAG_RD,
1459215281Sbrucec    0, 0, sysctl_kern_timecounter_choice, "A", "Timecounter hardware detected");
1460118987Sphk
146195821Sphk/*
146295661Sphk * RFC 2783 PPS-API implementation.
146395661Sphk */
146448887Sbde
1465246845Sianstatic int
1466246845Sianpps_fetch(struct pps_fetch_args *fapi, struct pps_state *pps)
1467246845Sian{
1468246845Sian	int err, timo;
1469246845Sian	pps_seq_t aseq, cseq;
1470246845Sian	struct timeval tv;
1471246845Sian
1472246845Sian	if (fapi->tsformat && fapi->tsformat != PPS_TSFMT_TSPEC)
1473246845Sian		return (EINVAL);
1474246845Sian
1475246845Sian	/*
1476246845Sian	 * If no timeout is requested, immediately return whatever values were
1477246845Sian	 * most recently captured.  If timeout seconds is -1, that's a request
1478246845Sian	 * to block without a timeout.  WITNESS won't let us sleep forever
1479246845Sian	 * without a lock (we really don't need a lock), so just repeatedly
1480246845Sian	 * sleep a long time.
1481246845Sian	 */
1482246845Sian	if (fapi->timeout.tv_sec || fapi->timeout.tv_nsec) {
1483246845Sian		if (fapi->timeout.tv_sec == -1)
1484246845Sian			timo = 0x7fffffff;
1485246845Sian		else {
1486246845Sian			tv.tv_sec = fapi->timeout.tv_sec;
1487246845Sian			tv.tv_usec = fapi->timeout.tv_nsec / 1000;
1488246845Sian			timo = tvtohz(&tv);
1489246845Sian		}
1490246845Sian		aseq = pps->ppsinfo.assert_sequence;
1491246845Sian		cseq = pps->ppsinfo.clear_sequence;
1492246845Sian		while (aseq == pps->ppsinfo.assert_sequence &&
1493246845Sian		    cseq == pps->ppsinfo.clear_sequence) {
1494246845Sian			err = tsleep(pps, PCATCH, "ppsfch", timo);
1495246845Sian			if (err == EWOULDBLOCK && fapi->timeout.tv_sec == -1) {
1496246845Sian				continue;
1497246845Sian			} else if (err != 0) {
1498246845Sian				return (err);
1499246845Sian			}
1500246845Sian		}
1501246845Sian	}
1502246845Sian
1503246845Sian	pps->ppsinfo.current_mode = pps->ppsparam.mode;
1504246845Sian	fapi->pps_info_buf = pps->ppsinfo;
1505246845Sian
1506246845Sian	return (0);
1507246845Sian}
1508246845Sian
150944666Sphkint
151044666Sphkpps_ioctl(u_long cmd, caddr_t data, struct pps_state *pps)
151133690Sphk{
151252061Sjhay	pps_params_t *app;
151352061Sjhay	struct pps_fetch_args *fapi;
1514227789Slstewart#ifdef FFCLOCK
1515227789Slstewart	struct pps_fetch_ffc_args *fapi_ffc;
1516227789Slstewart#endif
151752097Speter#ifdef PPS_SYNC
151852061Sjhay	struct pps_kcbind_args *kapi;
151952097Speter#endif
152034618Sphk
1521133714Sphk	KASSERT(pps != NULL, ("NULL pps pointer in pps_ioctl"));
152252061Sjhay	switch (cmd) {
152352061Sjhay	case PPS_IOC_CREATE:
152452061Sjhay		return (0);
152552061Sjhay	case PPS_IOC_DESTROY:
152652061Sjhay		return (0);
152752061Sjhay	case PPS_IOC_SETPARAMS:
152852061Sjhay		app = (pps_params_t *)data;
152952061Sjhay		if (app->mode & ~pps->ppscap)
153052061Sjhay			return (EINVAL);
1531227789Slstewart#ifdef FFCLOCK
1532227789Slstewart		/* Ensure only a single clock is selected for ffc timestamp. */
1533227789Slstewart		if ((app->mode & PPS_TSCLK_MASK) == PPS_TSCLK_MASK)
1534227789Slstewart			return (EINVAL);
1535227789Slstewart#endif
153695661Sphk		pps->ppsparam = *app;
153752061Sjhay		return (0);
153852061Sjhay	case PPS_IOC_GETPARAMS:
153952061Sjhay		app = (pps_params_t *)data;
154052061Sjhay		*app = pps->ppsparam;
154152061Sjhay		app->api_version = PPS_API_VERS_1;
154252061Sjhay		return (0);
154352061Sjhay	case PPS_IOC_GETCAP:
154452061Sjhay		*(int*)data = pps->ppscap;
154552061Sjhay		return (0);
154652061Sjhay	case PPS_IOC_FETCH:
154752061Sjhay		fapi = (struct pps_fetch_args *)data;
1548246845Sian		return (pps_fetch(fapi, pps));
1549227789Slstewart#ifdef FFCLOCK
1550227789Slstewart	case PPS_IOC_FETCH_FFCOUNTER:
1551227789Slstewart		fapi_ffc = (struct pps_fetch_ffc_args *)data;
1552227789Slstewart		if (fapi_ffc->tsformat && fapi_ffc->tsformat !=
1553227789Slstewart		    PPS_TSFMT_TSPEC)
1554227789Slstewart			return (EINVAL);
1555227789Slstewart		if (fapi_ffc->timeout.tv_sec || fapi_ffc->timeout.tv_nsec)
1556227789Slstewart			return (EOPNOTSUPP);
1557227789Slstewart		pps->ppsinfo_ffc.current_mode = pps->ppsparam.mode;
1558227789Slstewart		fapi_ffc->pps_info_buf_ffc = pps->ppsinfo_ffc;
1559227789Slstewart		/* Overwrite timestamps if feedback clock selected. */
1560227789Slstewart		switch (pps->ppsparam.mode & PPS_TSCLK_MASK) {
1561227789Slstewart		case PPS_TSCLK_FBCK:
1562227789Slstewart			fapi_ffc->pps_info_buf_ffc.assert_timestamp =
1563227789Slstewart			    pps->ppsinfo.assert_timestamp;
1564227789Slstewart			fapi_ffc->pps_info_buf_ffc.clear_timestamp =
1565227789Slstewart			    pps->ppsinfo.clear_timestamp;
1566227789Slstewart			break;
1567227789Slstewart		case PPS_TSCLK_FFWD:
1568227789Slstewart			break;
1569227789Slstewart		default:
1570227789Slstewart			break;
1571227789Slstewart		}
1572227789Slstewart		return (0);
1573227789Slstewart#endif /* FFCLOCK */
157452061Sjhay	case PPS_IOC_KCBIND:
157552061Sjhay#ifdef PPS_SYNC
157652061Sjhay		kapi = (struct pps_kcbind_args *)data;
157752061Sjhay		/* XXX Only root should be able to do this */
157852061Sjhay		if (kapi->tsformat && kapi->tsformat != PPS_TSFMT_TSPEC)
157952061Sjhay			return (EINVAL);
158052061Sjhay		if (kapi->kernel_consumer != PPS_KC_HARDPPS)
158152061Sjhay			return (EINVAL);
158252061Sjhay		if (kapi->edge & ~pps->ppscap)
158352061Sjhay			return (EINVAL);
158452061Sjhay		pps->kcmode = kapi->edge;
158552061Sjhay		return (0);
158652061Sjhay#else
158752061Sjhay		return (EOPNOTSUPP);
158852061Sjhay#endif
158952061Sjhay	default:
1590144152Sphk		return (ENOIOCTL);
159152061Sjhay	}
159233690Sphk}
159333690Sphk
159444666Sphkvoid
159544666Sphkpps_init(struct pps_state *pps)
159633690Sphk{
1597246845Sian	pps->ppscap |= PPS_TSFMT_TSPEC | PPS_CANWAIT;
159844666Sphk	if (pps->ppscap & PPS_CAPTUREASSERT)
159944666Sphk		pps->ppscap |= PPS_OFFSETASSERT;
160044666Sphk	if (pps->ppscap & PPS_CAPTURECLEAR)
160144666Sphk		pps->ppscap |= PPS_OFFSETCLEAR;
1602227789Slstewart#ifdef FFCLOCK
1603227789Slstewart	pps->ppscap |= PPS_TSCLK_MASK;
1604227789Slstewart#endif
160533690Sphk}
160633690Sphk
160744666Sphkvoid
160895523Sphkpps_capture(struct pps_state *pps)
160944666Sphk{
161095661Sphk	struct timehands *th;
161195523Sphk
1612133714Sphk	KASSERT(pps != NULL, ("NULL pps pointer in pps_capture"));
161395661Sphk	th = timehands;
161495661Sphk	pps->capgen = th->th_generation;
161595661Sphk	pps->capth = th;
1616227789Slstewart#ifdef FFCLOCK
1617227789Slstewart	pps->capffth = fftimehands;
1618227789Slstewart#endif
161995661Sphk	pps->capcount = th->th_counter->tc_get_timecount(th->th_counter);
162095661Sphk	if (pps->capgen != th->th_generation)
162195661Sphk		pps->capgen = 0;
162295523Sphk}
162395523Sphk
162495523Sphkvoid
162595523Sphkpps_event(struct pps_state *pps, int event)
162695523Sphk{
162795821Sphk	struct bintime bt;
162844666Sphk	struct timespec ts, *tsp, *osp;
162995661Sphk	u_int tcount, *pcount;
163044666Sphk	int foff, fhard;
163195821Sphk	pps_seq_t *pseq;
1632227789Slstewart#ifdef FFCLOCK
1633227789Slstewart	struct timespec *tsp_ffc;
1634227789Slstewart	pps_seq_t *pseq_ffc;
1635227789Slstewart	ffcounter *ffcount;
1636227789Slstewart#endif
163733690Sphk
1638133714Sphk	KASSERT(pps != NULL, ("NULL pps pointer in pps_event"));
163995821Sphk	/* If the timecounter was wound up underneath us, bail out. */
164095821Sphk	if (pps->capgen == 0 || pps->capgen != pps->capth->th_generation)
164195523Sphk		return;
164295523Sphk
164395821Sphk	/* Things would be easier with arrays. */
164444666Sphk	if (event == PPS_CAPTUREASSERT) {
164544666Sphk		tsp = &pps->ppsinfo.assert_timestamp;
164644666Sphk		osp = &pps->ppsparam.assert_offset;
164744666Sphk		foff = pps->ppsparam.mode & PPS_OFFSETASSERT;
164852061Sjhay		fhard = pps->kcmode & PPS_CAPTUREASSERT;
164944666Sphk		pcount = &pps->ppscount[0];
165044666Sphk		pseq = &pps->ppsinfo.assert_sequence;
1651227789Slstewart#ifdef FFCLOCK
1652227789Slstewart		ffcount = &pps->ppsinfo_ffc.assert_ffcount;
1653227789Slstewart		tsp_ffc = &pps->ppsinfo_ffc.assert_timestamp;
1654227789Slstewart		pseq_ffc = &pps->ppsinfo_ffc.assert_sequence;
1655227789Slstewart#endif
165644666Sphk	} else {
165744666Sphk		tsp = &pps->ppsinfo.clear_timestamp;
165844666Sphk		osp = &pps->ppsparam.clear_offset;
165944666Sphk		foff = pps->ppsparam.mode & PPS_OFFSETCLEAR;
166052061Sjhay		fhard = pps->kcmode & PPS_CAPTURECLEAR;
166144666Sphk		pcount = &pps->ppscount[1];
166244666Sphk		pseq = &pps->ppsinfo.clear_sequence;
1663227789Slstewart#ifdef FFCLOCK
1664227789Slstewart		ffcount = &pps->ppsinfo_ffc.clear_ffcount;
1665227789Slstewart		tsp_ffc = &pps->ppsinfo_ffc.clear_timestamp;
1666227789Slstewart		pseq_ffc = &pps->ppsinfo_ffc.clear_sequence;
1667227789Slstewart#endif
166844666Sphk	}
166941415Sphk
167095821Sphk	/*
167195661Sphk	 * If the timecounter changed, we cannot compare the count values, so
167295661Sphk	 * we have to drop the rest of the PPS-stuff until the next event.
167395661Sphk	 */
167495661Sphk	if (pps->ppstc != pps->capth->th_counter) {
167595661Sphk		pps->ppstc = pps->capth->th_counter;
167695523Sphk		*pcount = pps->capcount;
167795523Sphk		pps->ppscount[2] = pps->capcount;
167844666Sphk		return;
167944666Sphk	}
168041415Sphk
168195821Sphk	/* Convert the count to a timespec. */
168295661Sphk	tcount = pps->capcount - pps->capth->th_offset_count;
168395661Sphk	tcount &= pps->capth->th_counter->tc_counter_mask;
168495661Sphk	bt = pps->capth->th_offset;
168595661Sphk	bintime_addx(&bt, pps->capth->th_scale * tcount);
168697610Sphk	bintime_add(&bt, &boottimebin);
168790362Sphk	bintime2timespec(&bt, &ts);
168844666Sphk
168995821Sphk	/* If the timecounter was wound up underneath us, bail out. */
169095661Sphk	if (pps->capgen != pps->capth->th_generation)
169195523Sphk		return;
169295523Sphk
169395523Sphk	*pcount = pps->capcount;
169444666Sphk	(*pseq)++;
169544666Sphk	*tsp = ts;
169652061Sjhay
169744666Sphk	if (foff) {
169844666Sphk		timespecadd(tsp, osp);
169944666Sphk		if (tsp->tv_nsec < 0) {
170044666Sphk			tsp->tv_nsec += 1000000000;
170144666Sphk			tsp->tv_sec -= 1;
170244666Sphk		}
170344666Sphk	}
1704227789Slstewart
1705227789Slstewart#ifdef FFCLOCK
1706227789Slstewart	*ffcount = pps->capffth->tick_ffcount + tcount;
1707227789Slstewart	bt = pps->capffth->tick_time;
1708227789Slstewart	ffclock_convert_delta(tcount, pps->capffth->cest.period, &bt);
1709227789Slstewart	bintime_add(&bt, &pps->capffth->tick_time);
1710227789Slstewart	bintime2timespec(&bt, &ts);
1711227789Slstewart	(*pseq_ffc)++;
1712227789Slstewart	*tsp_ffc = ts;
1713227789Slstewart#endif
1714227789Slstewart
171544666Sphk#ifdef PPS_SYNC
171644666Sphk	if (fhard) {
1717209390Sed		uint64_t scale;
1718109392Sphk
171995821Sphk		/*
172095661Sphk		 * Feed the NTP PLL/FLL.
1721109391Sjhay		 * The FLL wants to know how many (hardware) nanoseconds
1722109391Sjhay		 * elapsed since the previous event.
172395661Sphk		 */
172495523Sphk		tcount = pps->capcount - pps->ppscount[2];
172595523Sphk		pps->ppscount[2] = pps->capcount;
172695661Sphk		tcount &= pps->capth->th_counter->tc_counter_mask;
1727209390Sed		scale = (uint64_t)1 << 63;
1728109391Sjhay		scale /= pps->capth->th_counter->tc_frequency;
1729109391Sjhay		scale *= 2;
173090362Sphk		bt.sec = 0;
173190362Sphk		bt.frac = 0;
1732109391Sjhay		bintime_addx(&bt, scale * tcount);
173390362Sphk		bintime2timespec(&bt, &ts);
173490362Sphk		hardpps(tsp, ts.tv_nsec + 1000000000 * ts.tv_sec);
173544666Sphk	}
173644666Sphk#endif
1737246845Sian
1738246845Sian	/* Wakeup anyone sleeping in pps_fetch().  */
1739246845Sian	wakeup(pps);
174044666Sphk}
174195497Sphk
174295821Sphk/*
174395497Sphk * Timecounters need to be updated every so often to prevent the hardware
174495497Sphk * counter from overflowing.  Updating also recalculates the cached values
174595497Sphk * used by the get*() family of functions, so their precision depends on
174695497Sphk * the update frequency.
174795497Sphk */
174895497Sphk
174995497Sphkstatic int tc_tick;
1750215283SbrucecSYSCTL_INT(_kern_timecounter, OID_AUTO, tick, CTLFLAG_RD, &tc_tick, 0,
1751215304Sbrucec    "Approximate number of hardclock ticks in a millisecond");
175295497Sphk
1753102926Sphkvoid
1754212603Smavtc_ticktock(int cnt)
175595497Sphk{
1756102926Sphk	static int count;
175795497Sphk
1758212603Smav	count += cnt;
1759212603Smav	if (count < tc_tick)
1760102926Sphk		return;
1761102926Sphk	count = 0;
176295497Sphk	tc_windup();
176395497Sphk}
176495497Sphk
1765247777Sdavidestatic void __inline
1766247777Sdavidetc_adjprecision(void)
1767247777Sdavide{
1768247777Sdavide	int t;
1769247777Sdavide
1770247777Sdavide	if (tc_timepercentage > 0) {
1771247777Sdavide		t = (99 + tc_timepercentage) / tc_timepercentage;
1772247777Sdavide		tc_precexp = fls(t + (t >> 1)) - 1;
1773247777Sdavide		FREQ2BT(hz / tc_tick, &bt_timethreshold);
1774247777Sdavide		FREQ2BT(hz, &bt_tickthreshold);
1775247777Sdavide		bintime_shift(&bt_timethreshold, tc_precexp);
1776247777Sdavide		bintime_shift(&bt_tickthreshold, tc_precexp);
1777247777Sdavide	} else {
1778247777Sdavide		tc_precexp = 31;
1779247777Sdavide		bt_timethreshold.sec = INT_MAX;
1780247777Sdavide		bt_timethreshold.frac = ~(uint64_t)0;
1781247777Sdavide		bt_tickthreshold = bt_timethreshold;
1782247777Sdavide	}
1783247777Sdavide	sbt_timethreshold = bttosbt(bt_timethreshold);
1784247777Sdavide	sbt_tickthreshold = bttosbt(bt_tickthreshold);
1785247777Sdavide}
1786247777Sdavide
1787247777Sdavidestatic int
1788247777Sdavidesysctl_kern_timecounter_adjprecision(SYSCTL_HANDLER_ARGS)
1789247777Sdavide{
1790247777Sdavide	int error, val;
1791247777Sdavide
1792247777Sdavide	val = tc_timepercentage;
1793247777Sdavide	error = sysctl_handle_int(oidp, &val, 0, req);
1794247777Sdavide	if (error != 0 || req->newptr == NULL)
1795247777Sdavide		return (error);
1796247777Sdavide	tc_timepercentage = val;
1797247777Sdavide	tc_adjprecision();
1798247777Sdavide	return (0);
1799247777Sdavide}
1800247777Sdavide
180195661Sphkstatic void
180295497Sphkinittimecounter(void *dummy)
180395497Sphk{
180495497Sphk	u_int p;
1805247777Sdavide	int tick_rate;
180695497Sphk
180795821Sphk	/*
180895821Sphk	 * Set the initial timeout to
180995821Sphk	 * max(1, <approx. number of hardclock ticks in a millisecond>).
181095821Sphk	 * People should probably not use the sysctl to set the timeout
181195821Sphk	 * to smaller than its inital value, since that value is the
181295821Sphk	 * smallest reasonable one.  If they want better timestamps they
181395821Sphk	 * should use the non-"get"* functions.
181495821Sphk	 */
181595497Sphk	if (hz > 1000)
181695497Sphk		tc_tick = (hz + 500) / 1000;
181795497Sphk	else
181895497Sphk		tc_tick = 1;
1819247777Sdavide	tc_adjprecision();
1820247777Sdavide	FREQ2BT(hz, &tick_bt);
1821247777Sdavide	tick_sbt = bttosbt(tick_bt);
1822247777Sdavide	tick_rate = hz / tc_tick;
1823247777Sdavide	FREQ2BT(tick_rate, &tc_tick_bt);
1824247777Sdavide	tc_tick_sbt = bttosbt(tc_tick_bt);
182595497Sphk	p = (tc_tick * 1000000) / hz;
182695497Sphk	printf("Timecounters tick every %d.%03u msec\n", p / 1000, p % 1000);
182795821Sphk
1828227723Slstewart#ifdef FFCLOCK
1829227723Slstewart	ffclock_init();
1830227723Slstewart#endif
183195976Sphk	/* warm up new timecounter (again) and get rolling. */
183295821Sphk	(void)timecounter->tc_get_timecount(timecounter);
183395821Sphk	(void)timecounter->tc_get_timecount(timecounter);
1834212958Smav	tc_windup();
183595497Sphk}
183695497Sphk
1837177253SrwatsonSYSINIT(timecounter, SI_SUB_CLOCKS, SI_ORDER_SECOND, inittimecounter, NULL);
1838155444Sphk
1839155534Sphk/* Cpu tick handling -------------------------------------------------*/
1840155534Sphk
1841155534Sphkstatic int cpu_tick_variable;
1842155534Sphkstatic uint64_t	cpu_tick_frequency;
1843155534Sphk
1844156413Sjhbstatic uint64_t
1845155444Sphktc_cpu_ticks(void)
1846155444Sphk{
1847155444Sphk	static uint64_t base;
1848155444Sphk	static unsigned last;
1849155534Sphk	unsigned u;
1850155444Sphk	struct timecounter *tc;
1851155444Sphk
1852155444Sphk	tc = timehands->th_counter;
1853155444Sphk	u = tc->tc_get_timecount(tc) & tc->tc_counter_mask;
1854155444Sphk	if (u < last)
1855156271Sphk		base += (uint64_t)tc->tc_counter_mask + 1;
1856155444Sphk	last = u;
1857155444Sphk	return (u + base);
1858155444Sphk}
1859155444Sphk
1860212541Smavvoid
1861212541Smavcpu_tick_calibration(void)
1862212541Smav{
1863212541Smav	static time_t last_calib;
1864212541Smav
1865212541Smav	if (time_uptime != last_calib && !(time_uptime & 0xf)) {
1866212541Smav		cpu_tick_calibrate(0);
1867212541Smav		last_calib = time_uptime;
1868212541Smav	}
1869212541Smav}
1870212541Smav
1871155534Sphk/*
1872176351Simp * This function gets called every 16 seconds on only one designated
1873212541Smav * CPU in the system from hardclock() via cpu_tick_calibration()().
1874155534Sphk *
1875155534Sphk * Whenever the real time clock is stepped we get called with reset=1
1876155534Sphk * to make sure we handle suspend/resume and similar events correctly.
1877155534Sphk */
1878155534Sphk
1879155534Sphkstatic void
1880155534Sphkcpu_tick_calibrate(int reset)
1881155534Sphk{
1882155534Sphk	static uint64_t c_last;
1883155534Sphk	uint64_t c_this, c_delta;
1884155534Sphk	static struct bintime  t_last;
1885155534Sphk	struct bintime t_this, t_delta;
1886156205Sphk	uint32_t divi;
1887155534Sphk
1888155534Sphk	if (reset) {
1889155534Sphk		/* The clock was stepped, abort & reset */
1890155534Sphk		t_last.sec = 0;
1891155534Sphk		return;
1892155534Sphk	}
1893155534Sphk
1894155534Sphk	/* we don't calibrate fixed rate cputicks */
1895155534Sphk	if (!cpu_tick_variable)
1896155534Sphk		return;
1897155534Sphk
1898155534Sphk	getbinuptime(&t_this);
1899155534Sphk	c_this = cpu_ticks();
1900155534Sphk	if (t_last.sec != 0) {
1901155534Sphk		c_delta = c_this - c_last;
1902155534Sphk		t_delta = t_this;
1903155534Sphk		bintime_sub(&t_delta, &t_last);
1904155534Sphk		/*
1905209900Smav		 * Headroom:
1906209900Smav		 * 	2^(64-20) / 16[s] =
1907209900Smav		 * 	2^(44) / 16[s] =
1908209900Smav		 * 	17.592.186.044.416 / 16 =
1909209900Smav		 * 	1.099.511.627.776 [Hz]
1910155534Sphk		 */
1911209900Smav		divi = t_delta.sec << 20;
1912209900Smav		divi |= t_delta.frac >> (64 - 20);
1913209900Smav		c_delta <<= 20;
1914209900Smav		c_delta /= divi;
1915209900Smav		if (c_delta > cpu_tick_frequency) {
1916209900Smav			if (0 && bootverbose)
1917209900Smav				printf("cpu_tick increased to %ju Hz\n",
1918209900Smav				    c_delta);
1919209900Smav			cpu_tick_frequency = c_delta;
1920155534Sphk		}
1921155534Sphk	}
1922155534Sphk	c_last = c_this;
1923155534Sphk	t_last = t_this;
1924155534Sphk}
1925155534Sphk
1926155534Sphkvoid
1927155534Sphkset_cputicker(cpu_tick_f *func, uint64_t freq, unsigned var)
1928155534Sphk{
1929155534Sphk
1930155534Sphk	if (func == NULL) {
1931155534Sphk		cpu_ticks = tc_cpu_ticks;
1932155534Sphk	} else {
1933155534Sphk		cpu_tick_frequency = freq;
1934155534Sphk		cpu_tick_variable = var;
1935155534Sphk		cpu_ticks = func;
1936155534Sphk	}
1937155534Sphk}
1938155534Sphk
1939155534Sphkuint64_t
1940155534Sphkcpu_tickrate(void)
1941155534Sphk{
1942155534Sphk
1943155534Sphk	if (cpu_ticks == tc_cpu_ticks)
1944155534Sphk		return (tc_getfrequency());
1945155534Sphk	return (cpu_tick_frequency);
1946155534Sphk}
1947155534Sphk
1948155534Sphk/*
1949155534Sphk * We need to be slightly careful converting cputicks to microseconds.
1950155534Sphk * There is plenty of margin in 64 bits of microseconds (half a million
1951155534Sphk * years) and in 64 bits at 4 GHz (146 years), but if we do a multiply
1952155534Sphk * before divide conversion (to retain precision) we find that the
1953155534Sphk * margin shrinks to 1.5 hours (one millionth of 146y).
1954160964Syar * With a three prong approach we never lose significant bits, no
1955155534Sphk * matter what the cputick rate and length of timeinterval is.
1956155534Sphk */
1957155534Sphk
1958155534Sphkuint64_t
1959155534Sphkcputick2usec(uint64_t tick)
1960155534Sphk{
1961155534Sphk
1962155534Sphk	if (tick > 18446744073709551LL)		/* floor(2^64 / 1000) */
1963155534Sphk		return (tick / (cpu_tickrate() / 1000000LL));
1964155534Sphk	else if (tick > 18446744073709LL)	/* floor(2^64 / 1000000) */
1965155534Sphk		return ((tick * 1000LL) / (cpu_tickrate() / 1000LL));
1966155534Sphk	else
1967155534Sphk		return ((tick * 1000000LL) / cpu_tickrate());
1968155534Sphk}
1969155534Sphk
1970155534Sphkcpu_tick_f	*cpu_ticks = tc_cpu_ticks;
1971237433Skib
1972237433Skibstatic int vdso_th_enable = 1;
1973237433Skibstatic int
1974237433Skibsysctl_fast_gettime(SYSCTL_HANDLER_ARGS)
1975237433Skib{
1976237433Skib	int old_vdso_th_enable, error;
1977237433Skib
1978237433Skib	old_vdso_th_enable = vdso_th_enable;
1979237433Skib	error = sysctl_handle_int(oidp, &old_vdso_th_enable, 0, req);
1980237433Skib	if (error != 0)
1981237433Skib		return (error);
1982237433Skib	vdso_th_enable = old_vdso_th_enable;
1983237474Skib	timekeep_push_vdso();
1984237433Skib	return (0);
1985237433Skib}
1986237433SkibSYSCTL_PROC(_kern_timecounter, OID_AUTO, fast_gettime,
1987237433Skib    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
1988237433Skib    NULL, 0, sysctl_fast_gettime, "I", "Enable fast time of day");
1989237433Skib
1990237433Skibuint32_t
1991237433Skibtc_fill_vdso_timehands(struct vdso_timehands *vdso_th)
1992237433Skib{
1993237433Skib	struct timehands *th;
1994237433Skib	uint32_t enabled;
1995237433Skib
1996237474Skib	th = timehands;
1997237474Skib	vdso_th->th_algo = VDSO_TH_ALGO_1;
1998237474Skib	vdso_th->th_scale = th->th_scale;
1999237474Skib	vdso_th->th_offset_count = th->th_offset_count;
2000237474Skib	vdso_th->th_counter_mask = th->th_counter->tc_counter_mask;
2001237474Skib	vdso_th->th_offset = th->th_offset;
2002237474Skib	vdso_th->th_boottime = boottimebin;
2003237474Skib	enabled = cpu_fill_vdso_timehands(vdso_th);
2004237433Skib	if (!vdso_th_enable)
2005237433Skib		enabled = 0;
2006237433Skib	return (enabled);
2007237433Skib}
2008237433Skib
2009237433Skib#ifdef COMPAT_FREEBSD32
2010237433Skibuint32_t
2011237433Skibtc_fill_vdso_timehands32(struct vdso_timehands32 *vdso_th32)
2012237433Skib{
2013237433Skib	struct timehands *th;
2014237433Skib	uint32_t enabled;
2015237433Skib
2016237474Skib	th = timehands;
2017237474Skib	vdso_th32->th_algo = VDSO_TH_ALGO_1;
2018237474Skib	*(uint64_t *)&vdso_th32->th_scale[0] = th->th_scale;
2019237474Skib	vdso_th32->th_offset_count = th->th_offset_count;
2020237474Skib	vdso_th32->th_counter_mask = th->th_counter->tc_counter_mask;
2021237474Skib	vdso_th32->th_offset.sec = th->th_offset.sec;
2022237474Skib	*(uint64_t *)&vdso_th32->th_offset.frac[0] = th->th_offset.frac;
2023237474Skib	vdso_th32->th_boottime.sec = boottimebin.sec;
2024237474Skib	*(uint64_t *)&vdso_th32->th_boottime.frac[0] = boottimebin.frac;
2025237474Skib	enabled = cpu_fill_vdso_timehands32(vdso_th32);
2026237433Skib	if (!vdso_th_enable)
2027237433Skib		enabled = 0;
2028237433Skib	return (enabled);
2029237433Skib}
2030237433Skib#endif
2031