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