x86/tsc: fetch frequency from CPUID when running on Xen
Introduce a helper to fetch the TSC frequency from CPUID when running under Xen. Since the TSC can also be initialized early when running as a Xen guest pull out the call to tsc_init() from the early_clock_source_init() handlers and place it in clock_init(), as otherwise all handlers would call tsc_init() anyway. Reviewed by: markj Sponsored by: Citrix Systems R&D Differential revision: https://reviews.freebsd.org/D34581
This commit is contained in:
parent
8b1f5965d9
commit
1ca34862dc
@ -1167,7 +1167,6 @@ static void
|
|||||||
native_clock_source_init(void)
|
native_clock_source_init(void)
|
||||||
{
|
{
|
||||||
i8254_init();
|
i8254_init();
|
||||||
tsc_init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -208,7 +208,6 @@ static void
|
|||||||
i386_clock_source_init(void)
|
i386_clock_source_init(void)
|
||||||
{
|
{
|
||||||
i8254_init();
|
i8254_init();
|
||||||
tsc_init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -129,6 +129,7 @@ clock_init(void)
|
|||||||
mtx_init(&clock_lock, "clk", NULL, MTX_SPIN | MTX_NOPROFILE);
|
mtx_init(&clock_lock, "clk", NULL, MTX_SPIN | MTX_NOPROFILE);
|
||||||
/* Init the clock in order to use DELAY */
|
/* Init the clock in order to use DELAY */
|
||||||
init_ops.early_clock_source_init();
|
init_ops.early_clock_source_init();
|
||||||
|
tsc_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -147,6 +147,21 @@ tsc_freq_vmware(void)
|
|||||||
tsc_early_calib_exact = 1;
|
tsc_early_calib_exact = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tsc_freq_xen(void)
|
||||||
|
{
|
||||||
|
u_int regs[4];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Must run *after* generic tsc_freq_cpuid_vm, so that when Xen is
|
||||||
|
* emulating Viridian support the Viridian leaf is used instead.
|
||||||
|
*/
|
||||||
|
KASSERT(hv_high >= 0x40000003, ("Invalid max hypervisor leaf on Xen"));
|
||||||
|
cpuid_count(0x40000003, 0, regs);
|
||||||
|
tsc_freq = (uint64_t)(regs[2]) * 1000;
|
||||||
|
tsc_early_calib_exact = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate TSC frequency using information from the CPUID leaf 0x15 'Time
|
* Calculate TSC frequency using information from the CPUID leaf 0x15 'Time
|
||||||
* Stamp Counter and Nominal Core Crystal Clock'. If leaf 0x15 is not
|
* Stamp Counter and Nominal Core Crystal Clock'. If leaf 0x15 is not
|
||||||
@ -358,6 +373,12 @@ probe_tsc_freq_early(void)
|
|||||||
printf(
|
printf(
|
||||||
"Early TSC frequency %juHz derived from VMWare hypercall\n",
|
"Early TSC frequency %juHz derived from VMWare hypercall\n",
|
||||||
(uintmax_t)tsc_freq);
|
(uintmax_t)tsc_freq);
|
||||||
|
} else if (vm_guest == VM_GUEST_XEN) {
|
||||||
|
tsc_freq_xen();
|
||||||
|
if (bootverbose)
|
||||||
|
printf(
|
||||||
|
"Early TSC frequency %juHz derived from Xen CPUID\n",
|
||||||
|
(uintmax_t)tsc_freq);
|
||||||
} else if (tsc_freq_cpuid(&tsc_freq)) {
|
} else if (tsc_freq_cpuid(&tsc_freq)) {
|
||||||
/*
|
/*
|
||||||
* If possible, use the value obtained from CPUID as the initial
|
* If possible, use the value obtained from CPUID as the initial
|
||||||
|
Loading…
x
Reference in New Issue
Block a user