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