kern_tc.c revision 95529
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: head/sys/kern/kern_tc.c 95529 2002-04-26 21:31:44Z phk $
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
30static MALLOC_DEFINE(M_TIMECOUNTER, "timecounter",
31	"Timecounter stable storage");
32
33time_t time_second;
34
35struct	bintime boottimebin;
36struct	timeval boottime;
37SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime, CTLFLAG_RD,
38    &boottime, timeval, "System boottime");
39
40SYSCTL_NODE(_kern, OID_AUTO, timecounter, CTLFLAG_RW, 0, "");
41
42#define TC_STATS(foo) \
43	static unsigned foo; \
44	SYSCTL_INT(_kern_timecounter, OID_AUTO, foo, CTLFLAG_RD, & foo, 0, "")
45
46TC_STATS(nbinuptime);    TC_STATS(nnanouptime);    TC_STATS(nmicrouptime);
47TC_STATS(nbintime);      TC_STATS(nnanotime);      TC_STATS(nmicrotime);
48TC_STATS(ngetbinuptime); TC_STATS(ngetnanouptime); TC_STATS(ngetmicrouptime);
49TC_STATS(ngetbintime);   TC_STATS(ngetnanotime);   TC_STATS(ngetmicrotime);
50
51#undef TC_STATS
52
53static void tc_windup(void);
54
55/*
56 * Implement a dummy timecounter which we can use until we get a real one
57 * in the air.  This allows the console and other early stuff to use
58 * timeservices.
59 */
60
61static unsigned
62dummy_get_timecount(struct timecounter *tc)
63{
64	static unsigned now;
65
66	if (tc->tc_generation == 0)
67		tc->tc_generation = 1;
68	return (++now);
69}
70
71static struct timecounter dummy_timecounter = {
72	dummy_get_timecount,
73	0,
74	~0u,
75	1000000,
76	"dummy"
77};
78
79struct timecounter *volatile timecounter = &dummy_timecounter;
80
81static __inline unsigned
82tc_delta(struct timecounter *tc)
83{
84
85	return ((tc->tc_get_timecount(tc) - tc->tc_offset_count) &
86	    tc->tc_counter_mask);
87}
88
89void
90binuptime(struct bintime *bt)
91{
92	struct timecounter *tc;
93	unsigned gen;
94
95	nbinuptime++;
96	do {
97		tc = timecounter;
98		gen = tc->tc_generation;
99		*bt = tc->tc_offset;
100		bintime_addx(bt, tc->tc_scale * tc_delta(tc));
101	} while (gen == 0 || gen != tc->tc_generation);
102}
103
104void
105nanouptime(struct timespec *ts)
106{
107	struct bintime bt;
108
109	nnanouptime++;
110	binuptime(&bt);
111	bintime2timespec(&bt, ts);
112}
113
114void
115microuptime(struct timeval *tv)
116{
117	struct bintime bt;
118
119	nmicrouptime++;
120	binuptime(&bt);
121	bintime2timeval(&bt, tv);
122}
123
124void
125bintime(struct bintime *bt)
126{
127
128	nbintime++;
129	binuptime(bt);
130	bintime_add(bt, &boottimebin);
131}
132
133void
134nanotime(struct timespec *ts)
135{
136	struct bintime bt;
137
138	nnanotime++;
139	bintime(&bt);
140	bintime2timespec(&bt, ts);
141}
142
143void
144microtime(struct timeval *tv)
145{
146	struct bintime bt;
147
148	nmicrotime++;
149	bintime(&bt);
150	bintime2timeval(&bt, tv);
151}
152
153void
154getbinuptime(struct bintime *bt)
155{
156	struct timecounter *tc;
157	unsigned gen;
158
159	ngetbinuptime++;
160	do {
161		tc = timecounter;
162		gen = tc->tc_generation;
163		*bt = tc->tc_offset;
164	} while (gen == 0 || gen != tc->tc_generation);
165}
166
167void
168getnanouptime(struct timespec *tsp)
169{
170	struct timecounter *tc;
171	unsigned gen;
172
173	ngetnanouptime++;
174	do {
175		tc = timecounter;
176		gen = tc->tc_generation;
177		bintime2timespec(&tc->tc_offset, tsp);
178	} while (gen == 0 || gen != tc->tc_generation);
179}
180
181void
182getmicrouptime(struct timeval *tvp)
183{
184	struct timecounter *tc;
185	unsigned gen;
186
187	ngetmicrouptime++;
188	do {
189		tc = timecounter;
190		gen = tc->tc_generation;
191		bintime2timeval(&tc->tc_offset, tvp);
192	} while (gen == 0 || gen != tc->tc_generation);
193}
194
195void
196getbintime(struct bintime *bt)
197{
198	struct timecounter *tc;
199	unsigned gen;
200
201	ngetbintime++;
202	do {
203		tc = timecounter;
204		gen = tc->tc_generation;
205		*bt = tc->tc_offset;
206	} while (gen == 0 || gen != tc->tc_generation);
207	bintime_add(bt, &boottimebin);
208}
209
210void
211getnanotime(struct timespec *tsp)
212{
213	struct timecounter *tc;
214	unsigned gen;
215
216	ngetnanotime++;
217	do {
218		tc = timecounter;
219		gen = tc->tc_generation;
220		*tsp = tc->tc_nanotime;
221	} while (gen == 0 || gen != tc->tc_generation);
222}
223
224void
225getmicrotime(struct timeval *tvp)
226{
227	struct timecounter *tc;
228	unsigned gen;
229
230	ngetmicrotime++;
231	do {
232		tc = timecounter;
233		gen = tc->tc_generation;
234		*tvp = tc->tc_microtime;
235	} while (gen == 0 || gen != tc->tc_generation);
236}
237
238static void
239tc_setscales(struct timecounter *tc)
240{
241	u_int64_t scale;
242
243	/* Sacrifice the lower bit to the deity for code clarity */
244	scale = 1ULL << 63;
245	/*
246	 * We get nanoseconds with 32 bit binary fraction and want
247	 * 64 bit binary fraction: x = a * 2^32 / 10^9 = a * 4.294967296
248	 * The range is +/- 5000PPM so we can only multiply by about 850
249	 * without overflowing.  The best suitable fraction is 2199/512.
250	 * Divide by 2 times 512 to match the temporary lower precision.
251	 */
252	scale += (tc->tc_adjustment / 1024) * 2199;
253	scale /= tc->tc_tweak->tc_frequency;
254	tc->tc_scale = scale * 2;
255}
256
257void
258tc_init(struct timecounter *tc)
259{
260	struct timecounter *t1, *t2, *t3;
261	int i;
262
263	tc->tc_adjustment = 0;
264	tc->tc_tweak = tc;
265	tc_setscales(tc);
266	tc->tc_offset_count = tc->tc_get_timecount(tc);
267	if (timecounter == &dummy_timecounter)
268		tc->tc_avail = tc;
269	else {
270		tc->tc_avail = timecounter->tc_tweak->tc_avail;
271		timecounter->tc_tweak->tc_avail = tc;
272	}
273	MALLOC(t1, struct timecounter *, sizeof *t1, M_TIMECOUNTER, M_WAITOK | M_ZERO);
274	tc->tc_next = t1;
275	*t1 = *tc;
276	t2 = t1;
277	t3 = NULL;
278	for (i = 1; i < NTIMECOUNTER; i++) {
279		MALLOC(t3, struct timecounter *, sizeof *t3,
280		    M_TIMECOUNTER, M_WAITOK | M_ZERO);
281		*t3 = *tc;
282		t3->tc_next = t2;
283		t2 = t3;
284	}
285	t1->tc_next = t3;
286	tc = t1;
287
288	printf("Timecounter \"%s\"  frequency %lu Hz\n",
289	    tc->tc_name, (u_long)tc->tc_frequency);
290
291	/* XXX: For now always start using the counter. */
292	tc->tc_offset_count = tc->tc_get_timecount(tc);
293	binuptime(&tc->tc_offset);
294	timecounter = tc;
295	tc_windup();
296}
297
298void
299tc_setclock(struct timespec *ts)
300{
301	struct timespec ts2;
302
303	nanouptime(&ts2);
304	boottime.tv_sec = ts->tv_sec - ts2.tv_sec;
305	boottime.tv_usec = (ts->tv_nsec - ts2.tv_nsec) / 1000;
306	if (boottime.tv_usec < 0) {
307		boottime.tv_usec += 1000000;
308		boottime.tv_sec--;
309	}
310	timeval2bintime(&boottime, &boottimebin);
311	/* fiddle all the little crinkly bits around the fiords... */
312	tc_windup();
313}
314
315u_int32_t
316tc_getfrequency(void)
317{
318
319	return (timecounter->tc_frequency);
320}
321
322static void
323switch_timecounter(struct timecounter *newtc)
324{
325	int s;
326	struct timecounter *tc;
327
328	s = splclock();
329	tc = timecounter;
330	if (newtc->tc_tweak == tc->tc_tweak) {
331		splx(s);
332		return;
333	}
334	newtc = newtc->tc_tweak->tc_next;
335	binuptime(&newtc->tc_offset);
336	newtc->tc_offset_count = newtc->tc_get_timecount(newtc);
337	tc_setscales(newtc);
338	newtc->tc_generation = 0;
339	timecounter = newtc;
340	tc_windup();
341	splx(s);
342}
343
344static void
345tc_windup(void)
346{
347	struct timecounter *tc, *tco;
348	struct bintime bt;
349	unsigned ogen, delta;
350	int i;
351
352	tco = timecounter;
353	tc = tco->tc_next;
354	ogen = tc->tc_generation;
355	tc->tc_generation = 0;
356	bcopy(tco, tc, __offsetof(struct timecounter, tc_generation));
357	delta = tc_delta(tc);
358	tc->tc_offset_count += delta;
359	tc->tc_offset_count &= tc->tc_counter_mask;
360	bintime_addx(&tc->tc_offset, tc->tc_scale * delta);
361	/*
362	 * We may be inducing a tiny error here, the tc_poll_pps() may
363	 * process a latched count which happens after the tc_delta()
364	 * in sync_other_counter(), which would extend the previous
365	 * counters parameters into the domain of this new one.
366	 * Since the timewindow is very small for this, the error is
367	 * going to be only a few weenieseconds (as Dave Mills would
368	 * say), so lets just not talk more about it, OK ?
369	 */
370	if (tco->tc_poll_pps)
371		tco->tc_poll_pps(tco);
372	for (i = tc->tc_offset.sec - tco->tc_offset.sec; i > 0; i--)
373		ntp_update_second(&tc->tc_adjustment, &tc->tc_offset.sec);
374	tc_setscales(tc);
375
376	bt = tc->tc_offset;
377	bintime_add(&bt, &boottimebin);
378	bintime2timeval(&bt, &tc->tc_microtime);
379	bintime2timespec(&bt, &tc->tc_nanotime);
380	ogen++;
381	if (ogen == 0)
382		ogen++;
383	tc->tc_generation = ogen;
384	time_second = tc->tc_microtime.tv_sec;
385	timecounter = tc;
386}
387
388static int
389sysctl_kern_timecounter_hardware(SYSCTL_HANDLER_ARGS)
390{
391	char newname[32];
392	struct timecounter *newtc, *tc;
393	int error;
394
395	tc = timecounter->tc_tweak;
396	strncpy(newname, tc->tc_name, sizeof(newname));
397	error = sysctl_handle_string(oidp, &newname[0], sizeof(newname), req);
398	if (error == 0 && req->newptr != NULL &&
399	    strcmp(newname, tc->tc_name) != 0) {
400		for (newtc = tc->tc_avail; newtc != tc;
401		    newtc = newtc->tc_avail) {
402			if (strcmp(newname, newtc->tc_name) == 0) {
403				/* Warm up new timecounter. */
404				(void)newtc->tc_get_timecount(newtc);
405
406				switch_timecounter(newtc);
407				return (0);
408			}
409		}
410		return (EINVAL);
411	}
412	return (error);
413}
414
415SYSCTL_PROC(_kern_timecounter, OID_AUTO, hardware, CTLTYPE_STRING | CTLFLAG_RW,
416    0, 0, sysctl_kern_timecounter_hardware, "A", "");
417
418
419int
420pps_ioctl(u_long cmd, caddr_t data, struct pps_state *pps)
421{
422	pps_params_t *app;
423	struct pps_fetch_args *fapi;
424#ifdef PPS_SYNC
425	struct pps_kcbind_args *kapi;
426#endif
427
428	switch (cmd) {
429	case PPS_IOC_CREATE:
430		return (0);
431	case PPS_IOC_DESTROY:
432		return (0);
433	case PPS_IOC_SETPARAMS:
434		app = (pps_params_t *)data;
435		if (app->mode & ~pps->ppscap)
436			return (EINVAL);
437		pps->ppsparam = *app;
438		return (0);
439	case PPS_IOC_GETPARAMS:
440		app = (pps_params_t *)data;
441		*app = pps->ppsparam;
442		app->api_version = PPS_API_VERS_1;
443		return (0);
444	case PPS_IOC_GETCAP:
445		*(int*)data = pps->ppscap;
446		return (0);
447	case PPS_IOC_FETCH:
448		fapi = (struct pps_fetch_args *)data;
449		if (fapi->tsformat && fapi->tsformat != PPS_TSFMT_TSPEC)
450			return (EINVAL);
451		if (fapi->timeout.tv_sec || fapi->timeout.tv_nsec)
452			return (EOPNOTSUPP);
453		pps->ppsinfo.current_mode = pps->ppsparam.mode;
454		fapi->pps_info_buf = pps->ppsinfo;
455		return (0);
456	case PPS_IOC_KCBIND:
457#ifdef PPS_SYNC
458		kapi = (struct pps_kcbind_args *)data;
459		/* XXX Only root should be able to do this */
460		if (kapi->tsformat && kapi->tsformat != PPS_TSFMT_TSPEC)
461			return (EINVAL);
462		if (kapi->kernel_consumer != PPS_KC_HARDPPS)
463			return (EINVAL);
464		if (kapi->edge & ~pps->ppscap)
465			return (EINVAL);
466		pps->kcmode = kapi->edge;
467		return (0);
468#else
469		return (EOPNOTSUPP);
470#endif
471	default:
472		return (ENOTTY);
473	}
474}
475
476void
477pps_init(struct pps_state *pps)
478{
479	pps->ppscap |= PPS_TSFMT_TSPEC;
480	if (pps->ppscap & PPS_CAPTUREASSERT)
481		pps->ppscap |= PPS_OFFSETASSERT;
482	if (pps->ppscap & PPS_CAPTURECLEAR)
483		pps->ppscap |= PPS_OFFSETCLEAR;
484}
485
486void
487pps_capture(struct pps_state *pps)
488{
489	struct timecounter *tc;
490
491	tc = timecounter;
492	pps->captc = tc;
493	pps->capgen = tc->tc_generation;
494	pps->capcount = tc->tc_get_timecount(tc);
495}
496
497void
498pps_event(struct pps_state *pps, int event)
499{
500	struct timespec ts, *tsp, *osp;
501	unsigned tcount, *pcount;
502	struct bintime bt;
503	int foff, fhard;
504	pps_seq_t	*pseq;
505
506	/* If the timecounter were wound up, bail. */
507	if (pps->capgen != pps->capgen)
508		return;
509
510	/* Things would be easier with arrays... */
511	if (event == PPS_CAPTUREASSERT) {
512		tsp = &pps->ppsinfo.assert_timestamp;
513		osp = &pps->ppsparam.assert_offset;
514		foff = pps->ppsparam.mode & PPS_OFFSETASSERT;
515		fhard = pps->kcmode & PPS_CAPTUREASSERT;
516		pcount = &pps->ppscount[0];
517		pseq = &pps->ppsinfo.assert_sequence;
518	} else {
519		tsp = &pps->ppsinfo.clear_timestamp;
520		osp = &pps->ppsparam.clear_offset;
521		foff = pps->ppsparam.mode & PPS_OFFSETCLEAR;
522		fhard = pps->kcmode & PPS_CAPTURECLEAR;
523		pcount = &pps->ppscount[1];
524		pseq = &pps->ppsinfo.clear_sequence;
525	}
526
527	/* The timecounter changed: bail */
528	if (!pps->ppstc ||
529	    pps->ppstc->tc_name != pps->captc->tc_name ||
530	    pps->captc->tc_name != timecounter->tc_name) {
531		pps->ppstc = pps->captc;
532		*pcount = pps->capcount;
533#ifdef PPS_SYNC
534		pps->ppscount[2] = pps->capcount;
535#endif
536		return;
537	}
538
539	/* Nothing really happened */
540	if (*pcount == pps->capcount)
541		return;
542
543	/* Convert the count to timespec */
544	tcount = pps->capcount - pps->captc->tc_offset_count;
545	tcount &= pps->captc->tc_counter_mask;
546	bt = pps->captc->tc_offset;
547	bintime_addx(&bt, pps->captc->tc_scale * tcount);
548	bintime2timespec(&bt, &ts);
549
550	/* If the timecounter were wound up, bail. */
551	if (pps->capgen != pps->capgen)
552		return;
553
554	*pcount = pps->capcount;
555	(*pseq)++;
556	*tsp = ts;
557
558	if (foff) {
559		timespecadd(tsp, osp);
560		if (tsp->tv_nsec < 0) {
561			tsp->tv_nsec += 1000000000;
562			tsp->tv_sec -= 1;
563		}
564	}
565#ifdef PPS_SYNC
566	if (fhard) {
567		/* magic, at its best... */
568		tcount = pps->capcount - pps->ppscount[2];
569		pps->ppscount[2] = pps->capcount;
570		tcount &= pps->captc->tc_counter_mask;
571		bt.sec = 0;
572		bt.frac = 0;
573		bintime_addx(&bt, pps->captc->tc_scale * tcount);
574		bintime2timespec(&bt, &ts);
575		hardpps(tsp, ts.tv_nsec + 1000000000 * ts.tv_sec);
576	}
577#endif
578}
579
580/*-
581 * Timecounters need to be updated every so often to prevent the hardware
582 * counter from overflowing.  Updating also recalculates the cached values
583 * used by the get*() family of functions, so their precision depends on
584 * the update frequency.
585 * Don't update faster than approx once per millisecond, if people want
586 * better timestamps they should use the non-"get" functions.
587 */
588
589static int tc_tick;
590SYSCTL_INT(_kern_timecounter, OID_AUTO, tick, CTLFLAG_RD, &tick, 0, "");
591
592static void
593tc_ticktock(void *dummy)
594{
595
596	tc_windup();
597	timeout(tc_ticktock, NULL, tc_tick);
598}
599
600static void
601inittimecounter(void *dummy)
602{
603	u_int p;
604
605	if (hz > 1000)
606		tc_tick = (hz + 500) / 1000;
607	else
608		tc_tick = 1;
609	p = (tc_tick * 1000000) / hz;
610	printf("Timecounters tick every %d.%03u msec\n", p / 1000, p % 1000);
611	tc_ticktock(NULL);
612}
613
614SYSINIT(timecounter, SI_SUB_CLOCKS, SI_ORDER_FIRST, inittimecounter, NULL)
615