xref: /freebsd/sys/kern/kern_tc.c (revision c17d43407fe04133a94055b0dbc7ea8965654a9f)
1 /*
2  * ----------------------------------------------------------------------------
3  * "THE BEER-WARE LICENSE" (Revision 42):
4  * <phk@FreeBSD.ORG> wrote this file.  As long as you retain this notice you
5  * can do whatever you want with this stuff. If we meet some day, and you think
6  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
7  * ----------------------------------------------------------------------------
8  *
9  * $FreeBSD$
10  */
11 
12 #include "opt_ntp.h"
13 
14 #include <sys/param.h>
15 #include <sys/timetc.h>
16 #include <sys/malloc.h>
17 #include <sys/kernel.h>
18 #include <sys/sysctl.h>
19 #include <sys/systm.h>
20 #include <sys/timex.h>
21 #include <sys/timepps.h>
22 
23 /*
24  * Number of timecounters used to implement stable storage
25  */
26 #ifndef NTIMECOUNTER
27 #define NTIMECOUNTER	hz
28 #endif
29 
30 static MALLOC_DEFINE(M_TIMECOUNTER, "timecounter",
31 	"Timecounter stable storage");
32 
33 static void tco_setscales(struct timecounter *tc);
34 static __inline unsigned tco_delta(struct timecounter *tc);
35 
36 time_t time_second;
37 
38 struct	bintime boottimebin;
39 struct	timeval boottime;
40 SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime, CTLFLAG_RD,
41     &boottime, timeval, "System boottime");
42 
43 SYSCTL_NODE(_kern, OID_AUTO, timecounter, CTLFLAG_RW, 0, "");
44 
45 static unsigned nbintime;
46 static unsigned nbinuptime;
47 static unsigned nmicrotime;
48 static unsigned nnanotime;
49 static unsigned ngetmicrotime;
50 static unsigned ngetnanotime;
51 static unsigned nmicrouptime;
52 static unsigned nnanouptime;
53 static unsigned ngetmicrouptime;
54 static unsigned ngetnanouptime;
55 SYSCTL_INT(_kern_timecounter, OID_AUTO, nbintime, CTLFLAG_RD, &nbintime, 0, "");
56 SYSCTL_INT(_kern_timecounter, OID_AUTO, nbinuptime, CTLFLAG_RD, &nbinuptime, 0, "");
57 SYSCTL_INT(_kern_timecounter, OID_AUTO, nmicrotime, CTLFLAG_RD, &nmicrotime, 0, "");
58 SYSCTL_INT(_kern_timecounter, OID_AUTO, nnanotime, CTLFLAG_RD, &nnanotime, 0, "");
59 SYSCTL_INT(_kern_timecounter, OID_AUTO, nmicrouptime, CTLFLAG_RD, &nmicrouptime, 0, "");
60 SYSCTL_INT(_kern_timecounter, OID_AUTO, nnanouptime, CTLFLAG_RD, &nnanouptime, 0, "");
61 SYSCTL_INT(_kern_timecounter, OID_AUTO, ngetmicrotime, CTLFLAG_RD, &ngetmicrotime, 0, "");
62 SYSCTL_INT(_kern_timecounter, OID_AUTO, ngetnanotime, CTLFLAG_RD, &ngetnanotime, 0, "");
63 SYSCTL_INT(_kern_timecounter, OID_AUTO, ngetmicrouptime, CTLFLAG_RD, &ngetmicrouptime, 0, "");
64 SYSCTL_INT(_kern_timecounter, OID_AUTO, ngetnanouptime, CTLFLAG_RD, &ngetnanouptime, 0, "");
65 
66 /*
67  * Implement a dummy timecounter which we can use until we get a real one
68  * in the air.  This allows the console and other early stuff to use
69  * timeservices.
70  */
71 
72 static unsigned
73 dummy_get_timecount(struct timecounter *tc)
74 {
75 	static unsigned now;
76 
77 	if (tc->tc_generation == 0)
78 		tc->tc_generation++;
79 	return (++now);
80 }
81 
82 static struct timecounter dummy_timecounter = {
83 	dummy_get_timecount,
84 	0,
85 	~0u,
86 	1000000,
87 	"dummy"
88 };
89 
90 struct timecounter *volatile timecounter = &dummy_timecounter;
91 
92 static __inline unsigned
93 tco_delta(struct timecounter *tc)
94 {
95 
96 	return ((tc->tc_get_timecount(tc) - tc->tc_offset_count) &
97 	    tc->tc_counter_mask);
98 }
99 
100 /*
101  * We have eight functions for looking at the clock, four for
102  * microseconds and four for nanoseconds.  For each there is fast
103  * but less precise version "get{nano|micro}[up]time" which will
104  * return a time which is up to 1/HZ previous to the call, whereas
105  * the raw version "{nano|micro}[up]time" will return a timestamp
106  * which is as precise as possible.  The "up" variants return the
107  * time relative to system boot, these are well suited for time
108  * interval measurements.
109  */
110 
111 void
112 binuptime(struct bintime *bt)
113 {
114 	struct timecounter *tc;
115 	unsigned gen;
116 
117 	nbinuptime++;
118 	do {
119 		tc = timecounter;
120 		gen = tc->tc_generation;
121 		*bt = tc->tc_offset;
122 		bintime_addx(bt, tc->tc_scale * tco_delta(tc));
123 	} while (gen == 0 || gen != tc->tc_generation);
124 }
125 
126 void
127 bintime(struct bintime *bt)
128 {
129 
130 	nbintime++;
131 	binuptime(bt);
132 	bintime_add(bt, &boottimebin);
133 }
134 
135 void
136 getmicrotime(struct timeval *tvp)
137 {
138 	struct timecounter *tc;
139 	unsigned gen;
140 
141 	ngetmicrotime++;
142 	do {
143 		tc = timecounter;
144 		gen = tc->tc_generation;
145 		*tvp = tc->tc_microtime;
146 	} while (gen == 0 || gen != tc->tc_generation);
147 }
148 
149 void
150 getnanotime(struct timespec *tsp)
151 {
152 	struct timecounter *tc;
153 	unsigned gen;
154 
155 	ngetnanotime++;
156 	do {
157 		tc = timecounter;
158 		gen = tc->tc_generation;
159 		*tsp = tc->tc_nanotime;
160 	} while (gen == 0 || gen != tc->tc_generation);
161 }
162 
163 void
164 microtime(struct timeval *tv)
165 {
166 	struct bintime bt;
167 
168 	nmicrotime++;
169 	bintime(&bt);
170 	bintime2timeval(&bt, tv);
171 }
172 
173 void
174 nanotime(struct timespec *ts)
175 {
176 	struct bintime bt;
177 
178 	nnanotime++;
179 	bintime(&bt);
180 	bintime2timespec(&bt, ts);
181 }
182 
183 void
184 getmicrouptime(struct timeval *tvp)
185 {
186 	struct timecounter *tc;
187 	unsigned gen;
188 
189 	ngetmicrouptime++;
190 	do {
191 		tc = timecounter;
192 		gen = tc->tc_generation;
193 		bintime2timeval(&tc->tc_offset, tvp);
194 	} while (gen == 0 || gen != tc->tc_generation);
195 }
196 
197 void
198 getnanouptime(struct timespec *tsp)
199 {
200 	struct timecounter *tc;
201 	unsigned gen;
202 
203 	ngetnanouptime++;
204 	do {
205 		tc = timecounter;
206 		gen = tc->tc_generation;
207 		bintime2timespec(&tc->tc_offset, tsp);
208 	} while (gen == 0 || gen != tc->tc_generation);
209 }
210 
211 void
212 microuptime(struct timeval *tv)
213 {
214 	struct bintime bt;
215 
216 	nmicrouptime++;
217 	binuptime(&bt);
218 	bintime2timeval(&bt, tv);
219 }
220 
221 void
222 nanouptime(struct timespec *ts)
223 {
224 	struct bintime bt;
225 
226 	nnanouptime++;
227 	binuptime(&bt);
228 	bintime2timespec(&bt, ts);
229 }
230 
231 static void
232 tco_setscales(struct timecounter *tc)
233 {
234 	u_int64_t scale;
235 
236 	/* Sacrifice the lower bit to the deity for code clarity */
237 	scale = 1ULL << 63;
238 	/*
239 	 * We get nanoseconds with 32 bit binary fraction and want
240 	 * 64 bit binary fraction: x = a * 2^32 / 10^9 = a * 4.294967296
241 	 * The range is +/- 500PPM so we can multiply by about 8500
242 	 * without overflowing.  4398/1024 = is very close to ideal.
243 	 */
244 	scale += (tc->tc_adjustment * 4398) >> 10;
245 	scale /= tc->tc_tweak->tc_frequency;
246 	tc->tc_scale = scale * 2;
247 }
248 
249 void
250 tc_update(struct timecounter *tc)
251 {
252 	tco_setscales(tc);
253 }
254 
255 void
256 tc_init(struct timecounter *tc)
257 {
258 	struct timecounter *t1, *t2, *t3;
259 	int i;
260 
261 	tc->tc_adjustment = 0;
262 	tc->tc_tweak = tc;
263 	tco_setscales(tc);
264 	tc->tc_offset_count = tc->tc_get_timecount(tc);
265 	if (timecounter == &dummy_timecounter)
266 		tc->tc_avail = tc;
267 	else {
268 		tc->tc_avail = timecounter->tc_tweak->tc_avail;
269 		timecounter->tc_tweak->tc_avail = tc;
270 	}
271 	MALLOC(t1, struct timecounter *, sizeof *t1, M_TIMECOUNTER, M_WAITOK | M_ZERO);
272 	tc->tc_next = t1;
273 	*t1 = *tc;
274 	t2 = t1;
275 	t3 = NULL;
276 	for (i = 1; i < NTIMECOUNTER; i++) {
277 		MALLOC(t3, struct timecounter *, sizeof *t3,
278 		    M_TIMECOUNTER, M_WAITOK | M_ZERO);
279 		*t3 = *tc;
280 		t3->tc_next = t2;
281 		t2 = t3;
282 	}
283 	t1->tc_next = t3;
284 	tc = t1;
285 
286 	printf("Timecounter \"%s\"  frequency %lu Hz\n",
287 	    tc->tc_name, (u_long)tc->tc_frequency);
288 
289 	/* XXX: For now always start using the counter. */
290 	tc->tc_offset_count = tc->tc_get_timecount(tc);
291 	binuptime(&tc->tc_offset);
292 	timecounter = tc;
293 	tc_windup();
294 }
295 
296 void
297 tc_setclock(struct timespec *ts)
298 {
299 	struct timespec ts2;
300 
301 	nanouptime(&ts2);
302 	boottime.tv_sec = ts->tv_sec - ts2.tv_sec;
303 	boottime.tv_usec = (ts->tv_nsec - ts2.tv_nsec) / 1000;
304 	if (boottime.tv_usec < 0) {
305 		boottime.tv_usec += 1000000;
306 		boottime.tv_sec--;
307 	}
308 	timeval2bintime(&boottime, &boottimebin);
309 	/* fiddle all the little crinkly bits around the fiords... */
310 	tc_windup();
311 }
312 
313 static void
314 switch_timecounter(struct timecounter *newtc)
315 {
316 	int s;
317 	struct timecounter *tc;
318 
319 	s = splclock();
320 	tc = timecounter;
321 	if (newtc->tc_tweak == tc->tc_tweak) {
322 		splx(s);
323 		return;
324 	}
325 	newtc = newtc->tc_tweak->tc_next;
326 	binuptime(&newtc->tc_offset);
327 	newtc->tc_offset_count = newtc->tc_get_timecount(newtc);
328 	tco_setscales(newtc);
329 	newtc->tc_generation = 0;
330 	timecounter = newtc;
331 	tc_windup();
332 	splx(s);
333 }
334 
335 void
336 tc_windup(void)
337 {
338 	struct timecounter *tc, *tco;
339 	struct bintime bt;
340 	struct timeval tvt;
341 	unsigned ogen, delta;
342 	int i;
343 
344 	tco = timecounter;
345 	tc = tco->tc_next;
346 	ogen = tc->tc_generation;
347 	tc->tc_generation = 0;
348 	bcopy(tco, tc, __offsetof(struct timecounter, tc_generation));
349 	delta = tco_delta(tc);
350 	tc->tc_offset_count += delta;
351 	tc->tc_offset_count &= tc->tc_counter_mask;
352 	bintime_addx(&tc->tc_offset, tc->tc_scale * delta);
353 	/*
354 	 * We may be inducing a tiny error here, the tc_poll_pps() may
355 	 * process a latched count which happens after the tco_delta()
356 	 * in sync_other_counter(), which would extend the previous
357 	 * counters parameters into the domain of this new one.
358 	 * Since the timewindow is very small for this, the error is
359 	 * going to be only a few weenieseconds (as Dave Mills would
360 	 * say), so lets just not talk more about it, OK ?
361 	 */
362 	if (tco->tc_poll_pps)
363 		tco->tc_poll_pps(tco);
364 	if (timedelta != 0) {
365 		tvt = boottime;
366 		tvt.tv_usec += tickdelta;
367 		if (tvt.tv_usec >= 1000000) {
368 			tvt.tv_sec++;
369 			tvt.tv_usec -= 1000000;
370 		} else if (tvt.tv_usec < 0) {
371 			tvt.tv_sec--;
372 			tvt.tv_usec += 1000000;
373 		}
374 		boottime = tvt;
375 		timeval2bintime(&boottime, &boottimebin);
376 		timedelta -= tickdelta;
377 	}
378 	for (i = tc->tc_offset.sec - tco->tc_offset.sec; i > 0; i--) {
379 		ntp_update_second(tc);	/* XXX only needed if xntpd runs */
380 		tco_setscales(tc);
381 	}
382 
383 	bt = tc->tc_offset;
384 	bintime_add(&bt, &boottimebin);
385 	bintime2timeval(&bt, &tc->tc_microtime);
386 	bintime2timespec(&bt, &tc->tc_nanotime);
387 	ogen++;
388 	if (ogen == 0)
389 		ogen++;
390 	tc->tc_generation = ogen;
391 	time_second = tc->tc_microtime.tv_sec;
392 	timecounter = tc;
393 }
394 
395 static int
396 sysctl_kern_timecounter_hardware(SYSCTL_HANDLER_ARGS)
397 {
398 	char newname[32];
399 	struct timecounter *newtc, *tc;
400 	int error;
401 
402 	tc = timecounter->tc_tweak;
403 	strncpy(newname, tc->tc_name, sizeof(newname));
404 	error = sysctl_handle_string(oidp, &newname[0], sizeof(newname), req);
405 	if (error == 0 && req->newptr != NULL &&
406 	    strcmp(newname, tc->tc_name) != 0) {
407 		for (newtc = tc->tc_avail; newtc != tc;
408 		    newtc = newtc->tc_avail) {
409 			if (strcmp(newname, newtc->tc_name) == 0) {
410 				/* Warm up new timecounter. */
411 				(void)newtc->tc_get_timecount(newtc);
412 
413 				switch_timecounter(newtc);
414 				return (0);
415 			}
416 		}
417 		return (EINVAL);
418 	}
419 	return (error);
420 }
421 
422 SYSCTL_PROC(_kern_timecounter, OID_AUTO, hardware, CTLTYPE_STRING | CTLFLAG_RW,
423     0, 0, sysctl_kern_timecounter_hardware, "A", "");
424 
425 
426 int
427 pps_ioctl(u_long cmd, caddr_t data, struct pps_state *pps)
428 {
429 	pps_params_t *app;
430 	struct pps_fetch_args *fapi;
431 #ifdef PPS_SYNC
432 	struct pps_kcbind_args *kapi;
433 #endif
434 
435 	switch (cmd) {
436 	case PPS_IOC_CREATE:
437 		return (0);
438 	case PPS_IOC_DESTROY:
439 		return (0);
440 	case PPS_IOC_SETPARAMS:
441 		app = (pps_params_t *)data;
442 		if (app->mode & ~pps->ppscap)
443 			return (EINVAL);
444 		pps->ppsparam = *app;
445 		return (0);
446 	case PPS_IOC_GETPARAMS:
447 		app = (pps_params_t *)data;
448 		*app = pps->ppsparam;
449 		app->api_version = PPS_API_VERS_1;
450 		return (0);
451 	case PPS_IOC_GETCAP:
452 		*(int*)data = pps->ppscap;
453 		return (0);
454 	case PPS_IOC_FETCH:
455 		fapi = (struct pps_fetch_args *)data;
456 		if (fapi->tsformat && fapi->tsformat != PPS_TSFMT_TSPEC)
457 			return (EINVAL);
458 		if (fapi->timeout.tv_sec || fapi->timeout.tv_nsec)
459 			return (EOPNOTSUPP);
460 		pps->ppsinfo.current_mode = pps->ppsparam.mode;
461 		fapi->pps_info_buf = pps->ppsinfo;
462 		return (0);
463 	case PPS_IOC_KCBIND:
464 #ifdef PPS_SYNC
465 		kapi = (struct pps_kcbind_args *)data;
466 		/* XXX Only root should be able to do this */
467 		if (kapi->tsformat && kapi->tsformat != PPS_TSFMT_TSPEC)
468 			return (EINVAL);
469 		if (kapi->kernel_consumer != PPS_KC_HARDPPS)
470 			return (EINVAL);
471 		if (kapi->edge & ~pps->ppscap)
472 			return (EINVAL);
473 		pps->kcmode = kapi->edge;
474 		return (0);
475 #else
476 		return (EOPNOTSUPP);
477 #endif
478 	default:
479 		return (ENOTTY);
480 	}
481 }
482 
483 void
484 pps_init(struct pps_state *pps)
485 {
486 	pps->ppscap |= PPS_TSFMT_TSPEC;
487 	if (pps->ppscap & PPS_CAPTUREASSERT)
488 		pps->ppscap |= PPS_OFFSETASSERT;
489 	if (pps->ppscap & PPS_CAPTURECLEAR)
490 		pps->ppscap |= PPS_OFFSETCLEAR;
491 }
492 
493 void
494 pps_event(struct pps_state *pps, struct timecounter *tc, unsigned count, int event)
495 {
496 	struct timespec ts, *tsp, *osp;
497 	unsigned tcount, *pcount;
498 	struct bintime bt;
499 	int foff, fhard;
500 	pps_seq_t	*pseq;
501 
502 	/* Things would be easier with arrays... */
503 	if (event == PPS_CAPTUREASSERT) {
504 		tsp = &pps->ppsinfo.assert_timestamp;
505 		osp = &pps->ppsparam.assert_offset;
506 		foff = pps->ppsparam.mode & PPS_OFFSETASSERT;
507 		fhard = pps->kcmode & PPS_CAPTUREASSERT;
508 		pcount = &pps->ppscount[0];
509 		pseq = &pps->ppsinfo.assert_sequence;
510 	} else {
511 		tsp = &pps->ppsinfo.clear_timestamp;
512 		osp = &pps->ppsparam.clear_offset;
513 		foff = pps->ppsparam.mode & PPS_OFFSETCLEAR;
514 		fhard = pps->kcmode & PPS_CAPTURECLEAR;
515 		pcount = &pps->ppscount[1];
516 		pseq = &pps->ppsinfo.clear_sequence;
517 	}
518 
519 	/* The timecounter changed: bail */
520 	if (!pps->ppstc ||
521 	    pps->ppstc->tc_name != tc->tc_name ||
522 	    tc->tc_name != timecounter->tc_name) {
523 		pps->ppstc = tc;
524 		*pcount = count;
525 		return;
526 	}
527 
528 	/* Nothing really happened */
529 	if (*pcount == count)
530 		return;
531 
532 	*pcount = count;
533 
534 	/* Convert the count to timespec */
535 	tcount = count - tc->tc_offset_count;
536 	tcount &= tc->tc_counter_mask;
537 	bt = tc->tc_offset;
538 	bintime_addx(&bt, tc->tc_scale * tcount);
539 	bintime2timespec(&bt, &ts);
540 
541 	(*pseq)++;
542 	*tsp = ts;
543 
544 	if (foff) {
545 		timespecadd(tsp, osp);
546 		if (tsp->tv_nsec < 0) {
547 			tsp->tv_nsec += 1000000000;
548 			tsp->tv_sec -= 1;
549 		}
550 	}
551 #ifdef PPS_SYNC
552 	if (fhard) {
553 		/* magic, at its best... */
554 		tcount = count - pps->ppscount[2];
555 		pps->ppscount[2] = count;
556 		tcount &= tc->tc_counter_mask;
557 		bt.sec = 0;
558 		bt.frac = 0;
559 		bintime_addx(&bt, tc->tc_scale * tcount);
560 		bintime2timespec(&bt, &ts);
561 		hardpps(tsp, ts.tv_nsec + 1000000000 * ts.tv_sec);
562 	}
563 #endif
564 }
565