mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-05-09 08:56:55 +00:00
On some platforms CPUID.0x15:ECX is zero and CPUID.0x16 can only return the TSC frequency in MHZ which is not accurate. For example the TSC frequency obtained by CPUID.0x16 is 2300 MHZ and the TSC frequency calibrated by HPET is 2303.998 MHZ which is much closer to the actual TSC frequency 2304.000 MHZ. This patch adds the support of using HPET to calibrate TSC when HPET is available and CPUID.0x15:ECX is zero. v3->v4: - move calc_tsc_by_hpet into hpet_calibrate_tsc v2->v3: - remove the NULL check in hpet_init - remove ""& 0xFFFFFFFFU" in tsc_read_hpet - add comment for the counter wrap in the low 32 bits in calc_tsc_by_hpet - use a dedicated function for hpet_calibrate_tsc v1->v2: - change native_calibrate_tsc_cpuid_0x15/0x16 to native_calculate_tsc_cpuid_0x15/0x16 - move hpet_init to BSP init - encapsulate both HPET and PIT calibration to one function - revise the commit message with an example" Tracked-On: #7876 Signed-off-by: Jian Jun Chen <jian.jun.chen@intel.com> Reviewed-by: Fei Li <fei1.li@intel.com>
52 lines
941 B
C
52 lines
941 B
C
/*
|
|
* Copyright (C) 2021 Intel Corporation.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#ifndef ARCH_X86_TSC_H
|
|
#define ARCH_X86_TSC_H
|
|
|
|
#include <types.h>
|
|
|
|
#define TSC_PER_MS ((uint64_t)get_tsc_khz())
|
|
|
|
/**
|
|
* @brief Read Time Stamp Counter (TSC).
|
|
*
|
|
* @return TSC value
|
|
*/
|
|
static inline uint64_t rdtsc(void)
|
|
{
|
|
uint32_t lo, hi;
|
|
|
|
asm volatile("rdtsc" : "=a" (lo), "=d" (hi));
|
|
return ((uint64_t)hi << 32U) | lo;
|
|
}
|
|
|
|
/**
|
|
* @brief Get Time Stamp Counter (TSC) frequency in KHz.
|
|
*
|
|
* @return TSC frequency in KHz
|
|
*/
|
|
uint32_t get_tsc_khz(void);
|
|
|
|
/**
|
|
* @brief Calibrate Time Stamp Counter (TSC) frequency.
|
|
*
|
|
* @remark Generic time related routines, e.g., cpu_tickrate(), us_to_ticks(),
|
|
* udelay(), etc., relies on this function being called earlier during system initialization.
|
|
*
|
|
* @return None
|
|
*/
|
|
void calibrate_tsc(void);
|
|
|
|
/**
|
|
* @brief Initialize HPET.
|
|
*
|
|
* @return None
|
|
*/
|
|
void hpet_init(void);
|
|
|
|
#endif /* ARCH_X86_TSC_H */
|