Only calibrate ICR read loop when not in x2APIC mode. Run-time

switching between LAPIC modes is not supported, and there is no need
to wait for IPI ack in x2APIC mode.  So the calibrated delay is only
needed for !x2APIC.

This saves around a second of boot time on the real hardware for
x2APIC.

Sponsored by:	The FreeBSD Foundation
This commit is contained in:
Konstantin Belousov 2016-05-26 09:09:11 +00:00
parent 06ca64ecf3
commit f159d7d6f0

View File

@ -525,19 +525,21 @@ native_lapic_init(vm_paddr_t addr)
*/
KASSERT((cpu_feature & CPUID_TSC) != 0 && tsc_freq != 0,
("TSC not initialized"));
r = rdtsc();
for (rx = 0; rx < LOOPS; rx++) {
(void)lapic_read_icr_lo();
ia32_pause();
}
r = rdtsc() - r;
r1 = tsc_freq * LOOPS;
r2 = r * 1000000;
lapic_ipi_wait_mult = r1 >= r2 ? r1 / r2 : 1;
if (bootverbose) {
printf("LAPIC: ipi_wait() us multiplier %ju (r %ju tsc %ju)\n",
(uintmax_t)lapic_ipi_wait_mult, (uintmax_t)r,
(uintmax_t)tsc_freq);
if (!x2apic_mode) {
r = rdtsc();
for (rx = 0; rx < LOOPS; rx++) {
(void)lapic_read_icr_lo();
ia32_pause();
}
r = rdtsc() - r;
r1 = tsc_freq * LOOPS;
r2 = r * 1000000;
lapic_ipi_wait_mult = r1 >= r2 ? r1 / r2 : 1;
if (bootverbose) {
printf("LAPIC: ipi_wait() us multiplier %ju (r %ju "
"tsc %ju)\n", (uintmax_t)lapic_ipi_wait_mult,
(uintmax_t)r, (uintmax_t)tsc_freq);
}
}
#undef LOOPS
#endif /* SMP */