Page MenuHomeFreeBSD

D33895.diff
No OneTemporary

D33895.diff

Index: sys/x86/x86/local_apic.c
===================================================================
--- sys/x86/x86/local_apic.c
+++ sys/x86/x86/local_apic.c
@@ -1002,6 +1002,35 @@
#endif
}
+static int
+lapic_calibrate_initcount_cpuid_vm(void)
+{
+ u_int regs[4];
+ uint64_t freq;
+
+ /* Get value from CPUID leaf if possible. */
+ if (vm_guest == VM_GUEST_NO)
+ return (false);
+ if (hv_high < 0x40000010)
+ return (false);
+ do_cpuid(0x40000010, regs);
+ freq = (uint64_t)(regs[1]) * 1000;
+
+ /* Pick timer divisor. */
+ lapic_timer_divisor = 2;
+ do {
+ if (freq / lapic_timer_divisor < APIC_TIMER_MAX_COUNT)
+ break;
+ lapic_timer_divisor <<= 1;
+ } while (lapic_timer_divisor <= 128);
+ if (lapic_timer_divisor > 128)
+ return (false);
+
+ /* Record divided frequency. */
+ count_freq = freq / lapic_timer_divisor;
+ return (true);
+}
+
static uint64_t
cb_lapic_getcount(void)
{
@@ -1014,6 +1043,9 @@
{
uint64_t freq;
+ if (lapic_calibrate_initcount_cpuid_vm())
+ goto done;
+
/* Calibrate the APIC timer frequency. */
lapic_timer_set_divisor(2);
lapic_timer_oneshot_nointr(la, APIC_TIMER_MAX_COUNT);
@@ -1031,6 +1063,7 @@
if (lapic_timer_divisor > 128)
panic("lapic: Divisor too big");
count_freq = freq * 2 / lapic_timer_divisor;
+done:
if (bootverbose) {
printf("lapic: Divisor %lu, Frequency %lu Hz\n",
lapic_timer_divisor, count_freq);

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 1, 7:16 PM (8 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29089934
Default Alt Text
D33895.diff (1 KB)

Event Timeline