| 569 | #endif /* SMP */ |
| 570 | |
| 571 | static void |
| 572 | init_TSC_tc(void) |
| 573 | { |
| 574 | uint64_t max_freq; |
| 575 | int shift; |
| 576 | |
| 577 | if ((cpu_feature & CPUID_TSC) == 0 || tsc_disabled) |
| 578 | return; |
| 579 | |
| 580 | /* |
| 581 | * Limit timecounter frequency to fit in an int and prevent it from |
| 582 | * overflowing too fast. |
| 583 | */ |
| 584 | max_freq = UINT_MAX; |
| 585 | |
| 586 | /* |
| 587 | * We can not use the TSC if we support APM. Precise timekeeping |
| 588 | * on an APM'ed machine is at best a fools pursuit, since |
| 589 | * any and all of the time spent in various SMM code can't |
| 590 | * be reliably accounted for. Reading the RTC is your only |
| 591 | * source of reliable time info. The i8254 loses too, of course, |
| 592 | * but we need to have some kind of time... |
| 593 | * We don't know at this point whether APM is going to be used |
| 594 | * or not, nor when it might be activated. Play it safe. |
| 595 | */ |
| 596 | if (power_pm_get_type() == POWER_PM_TYPE_APM) { |
| 597 | tsc_timecounter.tc_quality = -1000; |
| 598 | if (bootverbose) |
| 599 | printf("TSC timecounter disabled: APM enabled.\n"); |
| 600 | goto init; |
| 601 | } |
| 602 | |
| 603 | /* |
| 604 | * Intel CPUs without a C-state invariant TSC can stop the TSC |
| 605 | * in either C2 or C3. Disable use of C2 and C3 while using |
| 606 | * the TSC as the timecounter. The timecounter can be changed |
| 607 | * to enable C2 and C3. |
| 608 | * |
| 609 | * Note that the TSC is used as the cputicker for computing |
| 610 | * thread runtime regardless of the timecounter setting, so |
| 611 | * using an alternate timecounter and enabling C2 or C3 can |
| 612 | * result incorrect runtimes for kernel idle threads (but not |
| 613 | * for any non-idle threads). |
| 614 | */ |
| 615 | if (cpu_vendor_id == CPU_VENDOR_INTEL && |
| 616 | (amd_pminfo & AMDPM_TSC_INVARIANT) == 0) { |
| 617 | tsc_timecounter.tc_flags |= TC_FLAGS_C2STOP; |
| 618 | if (bootverbose) |
| 619 | printf("TSC timecounter disables C2 and C3.\n"); |
| 620 | } |
| 621 | |
| 622 | /* |
| 623 | * We can not use the TSC in SMP mode unless the TSCs on all CPUs |
| 624 | * are synchronized. If the user is sure that the system has |
| 625 | * synchronized TSCs, set kern.timecounter.smp_tsc tunable to a |
| 626 | * non-zero value. The TSC seems unreliable in virtualized SMP |
| 627 | * environments, so it is set to a negative quality in those cases. |
| 628 | */ |
nothing calls this directly
no test coverage detected