From 1bf984890b58556626ec06e791a0ff7eb40f68ca Mon Sep 17 00:00:00 2001 From: Jian Jun Chen Date: Tue, 6 Sep 2022 10:39:40 +0800 Subject: [PATCH] hv: tsc: start HPET counter before calibration HPET is used to calibrate the tsc frequency if system fails to get the accurate frequency from CPUID 0x15. But on some platforms (for example: the emulated ACRN on QEMU) HPET is not started by default, which causes the failure of calibration TSC by HPET. Tracked-On: #8113 Signed-off-by: Jian Jun Chen Reviewed-by: Zhao Yakui Acked-by: Eddie Dong --- hypervisor/arch/x86/tsc.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/hypervisor/arch/x86/tsc.c b/hypervisor/arch/x86/tsc.c index 1018f93c9..76d1a1c96 100644 --- a/hypervisor/arch/x86/tsc.c +++ b/hypervisor/arch/x86/tsc.c @@ -17,8 +17,11 @@ #define CAL_MS 10U #define HPET_PERIOD 0x004U +#define HPET_CFG 0x010U #define HPET_COUNTER 0x0F0U +#define HPET_CFG_ENABLE 0x001UL + static uint32_t tsc_khz; static void *hpet_hva; @@ -74,10 +77,19 @@ static uint64_t pit_calibrate_tsc(uint32_t cal_ms_arg) void hpet_init(void) { + uint64_t cfg; + hpet_hva = parse_hpet(); + if (hpet_hva != NULL) { + cfg = mmio_read64(hpet_hva + HPET_CFG); + if ((cfg & HPET_CFG_ENABLE) == 0UL) { + cfg |= HPET_CFG_ENABLE; + mmio_write64(cfg, hpet_hva + HPET_CFG); + } + } } -static inline bool is_hpet_enabled(void) +static inline bool is_hpet_capable(void) { return (hpet_hva != NULL); } @@ -131,7 +143,7 @@ static uint64_t pit_hpet_calibrate_tsc(uint32_t cal_ms_arg, uint64_t tsc_ref_hz) { uint64_t tsc_hz, delta; - if (is_hpet_enabled()) { + if (is_hpet_capable()) { tsc_hz = hpet_calibrate_tsc(cal_ms_arg); } else { tsc_hz = pit_calibrate_tsc(cal_ms_arg);