kern_tc.c revision 91290
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 91290 2002-02-26 09:16:27Z 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
33static void tco_setscales __P((struct timecounter *tc));
34static __inline unsigned tco_delta __P((struct timecounter *tc));
35
36time_t time_second;
37
38struct	bintime boottimebin;
39struct	timeval boottime;
40SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime, CTLFLAG_RD,
41    &boottime, timeval, "System boottime");
42
43SYSCTL_NODE(_kern, OID_AUTO, timecounter, CTLFLAG_RW, 0, "");
44
45static unsigned nbintime;
46static unsigned nbinuptime;
47static unsigned nmicrotime;
48static unsigned nnanotime;
49static unsigned ngetmicrotime;
50static unsigned ngetnanotime;
51static unsigned nmicrouptime;
52static unsigned nnanouptime;
53static unsigned ngetmicrouptime;
54static unsigned ngetnanouptime;
55SYSCTL_INT(_kern_timecounter, OID_AUTO, nbintime, CTLFLAG_RD, &nbintime, 0, "");
56SYSCTL_INT(_kern_timecounter, OID_AUTO, nbinuptime, CTLFLAG_RD, &nbinuptime, 0, "");
57SYSCTL_INT(_kern_timecounter, OID_AUTO, nmicrotime, CTLFLAG_RD, &nmicrotime, 0, "");
58SYSCTL_INT(_kern_timecounter, OID_AUTO, nnanotime, CTLFLAG_RD, &nnanotime, 0, "");
59SYSCTL_INT(_kern_timecounter, OID_AUTO, nmicrouptime, CTLFLAG_RD, &nmicrouptime, 0, "");
60SYSCTL_INT(_kern_timecounter, OID_AUTO, nnanouptime, CTLFLAG_RD, &nnanouptime, 0, "");
61SYSCTL_INT(_kern_timecounter, OID_AUTO, ngetmicrotime, CTLFLAG_RD, &ngetmicrotime, 0, "");
62SYSCTL_INT(_kern_timecounter, OID_AUTO, ngetnanotime, CTLFLAG_RD, &ngetnanotime, 0, "");
63SYSCTL_INT(_kern_timecounter, OID_AUTO, ngetmicrouptime, CTLFLAG_RD, &ngetmicrouptime, 0, "");
64SYSCTL_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
72static unsigned
73dummy_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
82static struct timecounter dummy_timecounter = {
83	dummy_get_timecount,
84	0,
85	~0u,
86	1000000,
87	"dummy"
88};
89
90struct timecounter *volatile timecounter = &dummy_timecounter;
91
92static __inline unsigned
93tco_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
111void
112binuptime(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
126void
127bintime(struct bintime *bt)
128{
129
130	nbintime++;
131	binuptime(bt);
132	bintime_add(bt, &boottimebin);
133}
134
135void
136getmicrotime(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
149void
150getnanotime(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
163void
164microtime(struct timeval *tv)
165{
166	struct bintime bt;
167
168	nmicrotime++;
169	bintime(&bt);
170	bintime2timeval(&bt, tv);
171}
172
173void
174nanotime(struct timespec *ts)
175{
176	struct bintime bt;
177
178	nnanotime++;
179	bintime(&bt);
180	bintime2timespec(&bt, ts);
181}
182
183void
184getmicrouptime(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
197void
198getnanouptime(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
211void
212microuptime(struct timeval *tv)
213{
214	struct bintime bt;
215
216	nmicrouptime++;
217	binuptime(&bt);
218	bintime2timeval(&bt, tv);
219}
220
221void
222nanouptime(struct timespec *ts)
223{
224	struct bintime bt;
225
226	nnanouptime++;
227	binuptime(&bt);
228	bintime2timespec(&bt, ts);
229}
230
231static void
232tco_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
249void
250tc_update(struct timecounter *tc)
251{
252	tco_setscales(tc);
253}
254
255void
256tc_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
296void
297tc_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
313static void
314switch_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
335void
336tc_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
395static int
396sysctl_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
422SYSCTL_PROC(_kern_timecounter, OID_AUTO, hardware, CTLTYPE_STRING | CTLFLAG_RW,
423    0, 0, sysctl_kern_timecounter_hardware, "A", "");
424
425
426int
427pps_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
483void
484pps_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
493void
494pps_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