kern_tc.c revision 95523
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 95523 2002-04-26 20:24:28Z 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
315static void
316switch_timecounter(struct timecounter *newtc)
317{
318	int s;
319	struct timecounter *tc;
320
321	s = splclock();
322	tc = timecounter;
323	if (newtc->tc_tweak == tc->tc_tweak) {
324		splx(s);
325		return;
326	}
327	newtc = newtc->tc_tweak->tc_next;
328	binuptime(&newtc->tc_offset);
329	newtc->tc_offset_count = newtc->tc_get_timecount(newtc);
330	tc_setscales(newtc);
331	newtc->tc_generation = 0;
332	timecounter = newtc;
333	tc_windup();
334	splx(s);
335}
336
337static void
338tc_windup(void)
339{
340	struct timecounter *tc, *tco;
341	struct bintime bt;
342	unsigned ogen, delta;
343	int i;
344
345	tco = timecounter;
346	tc = tco->tc_next;
347	ogen = tc->tc_generation;
348	tc->tc_generation = 0;
349	bcopy(tco, tc, __offsetof(struct timecounter, tc_generation));
350	delta = tc_delta(tc);
351	tc->tc_offset_count += delta;
352	tc->tc_offset_count &= tc->tc_counter_mask;
353	bintime_addx(&tc->tc_offset, tc->tc_scale * delta);
354	/*
355	 * We may be inducing a tiny error here, the tc_poll_pps() may
356	 * process a latched count which happens after the tc_delta()
357	 * in sync_other_counter(), which would extend the previous
358	 * counters parameters into the domain of this new one.
359	 * Since the timewindow is very small for this, the error is
360	 * going to be only a few weenieseconds (as Dave Mills would
361	 * say), so lets just not talk more about it, OK ?
362	 */
363	if (tco->tc_poll_pps)
364		tco->tc_poll_pps(tco);
365	for (i = tc->tc_offset.sec - tco->tc_offset.sec; i > 0; i--) {
366		ntp_update_second(tc);	/* XXX only needed if xntpd runs */
367		tc_setscales(tc);
368	}
369
370	bt = tc->tc_offset;
371	bintime_add(&bt, &boottimebin);
372	bintime2timeval(&bt, &tc->tc_microtime);
373	bintime2timespec(&bt, &tc->tc_nanotime);
374	ogen++;
375	if (ogen == 0)
376		ogen++;
377	tc->tc_generation = ogen;
378	time_second = tc->tc_microtime.tv_sec;
379	timecounter = tc;
380}
381
382static int
383sysctl_kern_timecounter_hardware(SYSCTL_HANDLER_ARGS)
384{
385	char newname[32];
386	struct timecounter *newtc, *tc;
387	int error;
388
389	tc = timecounter->tc_tweak;
390	strncpy(newname, tc->tc_name, sizeof(newname));
391	error = sysctl_handle_string(oidp, &newname[0], sizeof(newname), req);
392	if (error == 0 && req->newptr != NULL &&
393	    strcmp(newname, tc->tc_name) != 0) {
394		for (newtc = tc->tc_avail; newtc != tc;
395		    newtc = newtc->tc_avail) {
396			if (strcmp(newname, newtc->tc_name) == 0) {
397				/* Warm up new timecounter. */
398				(void)newtc->tc_get_timecount(newtc);
399
400				switch_timecounter(newtc);
401				return (0);
402			}
403		}
404		return (EINVAL);
405	}
406	return (error);
407}
408
409SYSCTL_PROC(_kern_timecounter, OID_AUTO, hardware, CTLTYPE_STRING | CTLFLAG_RW,
410    0, 0, sysctl_kern_timecounter_hardware, "A", "");
411
412
413int
414pps_ioctl(u_long cmd, caddr_t data, struct pps_state *pps)
415{
416	pps_params_t *app;
417	struct pps_fetch_args *fapi;
418#ifdef PPS_SYNC
419	struct pps_kcbind_args *kapi;
420#endif
421
422	switch (cmd) {
423	case PPS_IOC_CREATE:
424		return (0);
425	case PPS_IOC_DESTROY:
426		return (0);
427	case PPS_IOC_SETPARAMS:
428		app = (pps_params_t *)data;
429		if (app->mode & ~pps->ppscap)
430			return (EINVAL);
431		pps->ppsparam = *app;
432		return (0);
433	case PPS_IOC_GETPARAMS:
434		app = (pps_params_t *)data;
435		*app = pps->ppsparam;
436		app->api_version = PPS_API_VERS_1;
437		return (0);
438	case PPS_IOC_GETCAP:
439		*(int*)data = pps->ppscap;
440		return (0);
441	case PPS_IOC_FETCH:
442		fapi = (struct pps_fetch_args *)data;
443		if (fapi->tsformat && fapi->tsformat != PPS_TSFMT_TSPEC)
444			return (EINVAL);
445		if (fapi->timeout.tv_sec || fapi->timeout.tv_nsec)
446			return (EOPNOTSUPP);
447		pps->ppsinfo.current_mode = pps->ppsparam.mode;
448		fapi->pps_info_buf = pps->ppsinfo;
449		return (0);
450	case PPS_IOC_KCBIND:
451#ifdef PPS_SYNC
452		kapi = (struct pps_kcbind_args *)data;
453		/* XXX Only root should be able to do this */
454		if (kapi->tsformat && kapi->tsformat != PPS_TSFMT_TSPEC)
455			return (EINVAL);
456		if (kapi->kernel_consumer != PPS_KC_HARDPPS)
457			return (EINVAL);
458		if (kapi->edge & ~pps->ppscap)
459			return (EINVAL);
460		pps->kcmode = kapi->edge;
461		return (0);
462#else
463		return (EOPNOTSUPP);
464#endif
465	default:
466		return (ENOTTY);
467	}
468}
469
470void
471pps_init(struct pps_state *pps)
472{
473	pps->ppscap |= PPS_TSFMT_TSPEC;
474	if (pps->ppscap & PPS_CAPTUREASSERT)
475		pps->ppscap |= PPS_OFFSETASSERT;
476	if (pps->ppscap & PPS_CAPTURECLEAR)
477		pps->ppscap |= PPS_OFFSETCLEAR;
478}
479
480void
481pps_capture(struct pps_state *pps)
482{
483	struct timecounter *tc;
484
485	tc = timecounter;
486	pps->captc = tc;
487	pps->capgen = tc->tc_generation;
488	pps->capcount = tc->tc_get_timecount(tc);
489}
490
491void
492pps_event(struct pps_state *pps, int event)
493{
494	struct timespec ts, *tsp, *osp;
495	unsigned tcount, *pcount;
496	struct bintime bt;
497	int foff, fhard;
498	pps_seq_t	*pseq;
499
500	/* If the timecounter were wound up, bail. */
501	if (pps->capgen != pps->capgen)
502		return;
503
504	/* Things would be easier with arrays... */
505	if (event == PPS_CAPTUREASSERT) {
506		tsp = &pps->ppsinfo.assert_timestamp;
507		osp = &pps->ppsparam.assert_offset;
508		foff = pps->ppsparam.mode & PPS_OFFSETASSERT;
509		fhard = pps->kcmode & PPS_CAPTUREASSERT;
510		pcount = &pps->ppscount[0];
511		pseq = &pps->ppsinfo.assert_sequence;
512	} else {
513		tsp = &pps->ppsinfo.clear_timestamp;
514		osp = &pps->ppsparam.clear_offset;
515		foff = pps->ppsparam.mode & PPS_OFFSETCLEAR;
516		fhard = pps->kcmode & PPS_CAPTURECLEAR;
517		pcount = &pps->ppscount[1];
518		pseq = &pps->ppsinfo.clear_sequence;
519	}
520
521	/* The timecounter changed: bail */
522	if (!pps->ppstc ||
523	    pps->ppstc->tc_name != pps->captc->tc_name ||
524	    pps->captc->tc_name != timecounter->tc_name) {
525		pps->ppstc = pps->captc;
526		*pcount = pps->capcount;
527#ifdef PPS_SYNC
528		pps->ppscount[2] = pps->capcount;
529#endif
530		return;
531	}
532
533	/* Nothing really happened */
534	if (*pcount == pps->capcount)
535		return;
536
537	/* Convert the count to timespec */
538	tcount = pps->capcount - pps->captc->tc_offset_count;
539	tcount &= pps->captc->tc_counter_mask;
540	bt = pps->captc->tc_offset;
541	bintime_addx(&bt, pps->captc->tc_scale * tcount);
542	bintime2timespec(&bt, &ts);
543
544	/* If the timecounter were wound up, bail. */
545	if (pps->capgen != pps->capgen)
546		return;
547
548	*pcount = pps->capcount;
549	(*pseq)++;
550	*tsp = ts;
551
552	if (foff) {
553		timespecadd(tsp, osp);
554		if (tsp->tv_nsec < 0) {
555			tsp->tv_nsec += 1000000000;
556			tsp->tv_sec -= 1;
557		}
558	}
559#ifdef PPS_SYNC
560	if (fhard) {
561		/* magic, at its best... */
562		tcount = pps->capcount - pps->ppscount[2];
563		pps->ppscount[2] = pps->capcount;
564		tcount &= pps->captc->tc_counter_mask;
565		bt.sec = 0;
566		bt.frac = 0;
567		bintime_addx(&bt, pps->captc->tc_scale * tcount);
568		bintime2timespec(&bt, &ts);
569		hardpps(tsp, ts.tv_nsec + 1000000000 * ts.tv_sec);
570	}
571#endif
572}
573
574/*-
575 * Timecounters need to be updated every so often to prevent the hardware
576 * counter from overflowing.  Updating also recalculates the cached values
577 * used by the get*() family of functions, so their precision depends on
578 * the update frequency.
579 * Don't update faster than approx once per millisecond, if people want
580 * better timestamps they should use the non-"get" functions.
581 */
582
583static int tc_tick;
584SYSCTL_INT(_kern_timecounter, OID_AUTO, tick, CTLFLAG_RD, &tick, 0, "");
585
586static void
587tc_ticktock(void *dummy)
588{
589
590	tc_windup();
591	timeout(tc_ticktock, NULL, tc_tick);
592}
593
594static void
595inittimecounter(void *dummy)
596{
597	u_int p;
598
599	if (hz > 1000)
600		tc_tick = (hz + 500) / 1000;
601	else
602		tc_tick = 1;
603	p = (tc_tick * 1000000) / hz;
604	printf("Timecounters tick every %d.%03u msec\n", p / 1000, p % 1000);
605	tc_ticktock(NULL);
606}
607
608SYSINIT(timecounter, SI_SUB_CLOCKS, SI_ORDER_FIRST, inittimecounter, NULL)
609