hv:move several tsc APIs to timer.c

-- change 'tsc_khz' to static
-- move these APIs from rtl.h to timer.c
   us_to_ticks()
   ticks_to_us()
   ticks_to_ms()
   rdtsc()

Tracked-On: #1842
Signed-off-by: Mingqiang Chi <mingqiang.chi@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Mingqiang Chi 2019-03-07 14:03:10 +08:00 committed by wenlingz
parent 36f6a412b7
commit 55f52978db
5 changed files with 87 additions and 34 deletions

View File

@ -45,3 +45,17 @@ Interfaces Design
.. doxygenfunction:: calibrate_tsc
:project: Project ACRN
.. doxygenfunction:: us_to_ticks
:project: Project ACRN
.. doxygenfunction:: ticks_to_us
:project: Project ACRN
.. doxygenfunction:: ticks_to_ms
:project: Project ACRN
.. doxygenfunction:: rdtsc
:project: Project ACRN
.. doxygenfunction:: get_tsc_khz
:project: Project ACRN

View File

@ -139,7 +139,7 @@ static void init_vcpuid_entry(uint32_t leaf, uint32_t subleaf,
cpuid_subleaf(leaf, subleaf, &entry->eax, &entry->ebx, &entry->ecx, &entry->edx);
} else {
/* Use the tsc to derive the emulated 0x16U cpuid. */
entry->eax = (uint32_t) (tsc_khz / 1000U);
entry->eax = (uint32_t) (get_tsc_khz() / 1000U);
entry->ebx = entry->eax;
/* Bus frequency: hard coded to 100M */
entry->ecx = 100U;
@ -178,7 +178,7 @@ static void init_vcpuid_entry(uint32_t leaf, uint32_t subleaf,
* EBX, ECX, EDX: RESERVED (reserved fields are set to zero).
*/
case 0x40000010U:
entry->eax = tsc_khz;
entry->eax = get_tsc_khz();
entry->ebx = 0U;
entry->ecx = 0U;
entry->edx = 0U;

View File

@ -16,7 +16,15 @@
#define CAL_MS 10U
#define MIN_TIMER_PERIOD_US 500U
uint32_t tsc_khz = 0U;
static uint32_t tsc_khz = 0U;
uint64_t rdtsc(void)
{
uint32_t lo, hi;
asm volatile("rdtsc" : "=a" (lo), "=d" (hi));
return ((uint64_t)hi << 32U) | lo;
}
static void run_timer(const struct hv_timer *timer)
{
@ -283,3 +291,28 @@ void calibrate_tsc(void)
tsc_khz = (uint32_t)(tsc_hz / 1000UL);
printf("%s, tsc_khz=%lu\n", __func__, tsc_khz);
}
uint32_t get_tsc_khz(void)
{
return tsc_khz;
}
/**
* Frequency of TSC in KHz (where 1KHz = 1000Hz). Only valid after
* calibrate_tsc() returns.
*/
uint64_t us_to_ticks(uint32_t us)
{
return (((uint64_t)us * (uint64_t)tsc_khz) / 1000UL);
}
uint64_t ticks_to_us(uint64_t ticks)
{
return (ticks * 1000UL) / (uint64_t)tsc_khz;
}
uint64_t ticks_to_ms(uint64_t ticks)
{
return ticks / (uint64_t)tsc_khz;
}

View File

@ -8,7 +8,6 @@
#define TIMER_H
#include <list.h>
#include <rtl.h>
/**
* @brief Timer
@ -48,6 +47,36 @@ struct hv_timer {
/* External Interfaces */
#define CYCLES_PER_MS us_to_ticks(1000U)
/**
* @brief convert us to ticks.
*
* @return ticks
*/
uint64_t us_to_ticks(uint32_t us);
/**
* @brief convert ticks to us.
*
* @return microsecond
*/
uint64_t ticks_to_us(uint64_t ticks);
/**
* @brief convert ticks to ms.
*
* @return millisecond
*/
uint64_t ticks_to_ms(uint64_t ticks);
/**
* @brief read tsc.
*
* @return tsc value
*/
uint64_t rdtsc(void);
/**
* @brief Initialize a timer structure.
*
@ -138,6 +167,13 @@ void timer_init(void);
*/
void calibrate_tsc(void);
/**
* @brief Get tsc.
*
* @return tsc(KHz)
*/
uint32_t get_tsc_khz(void);
/**
* @}
*/

View File

@ -43,34 +43,4 @@ uint64_t strtoul_hex(const char *nptr);
char *strstr_s(const char *str1, size_t maxlen1,
const char *str2, size_t maxlen2);
/**
* Frequency of TSC in KHz (where 1KHz = 1000Hz). Only valid after
* calibrate_tsc() returns.
*/
extern uint32_t tsc_khz;
static inline uint64_t us_to_ticks(uint32_t us)
{
return (((uint64_t)us * (uint64_t)tsc_khz) / 1000UL);
}
#define CYCLES_PER_MS us_to_ticks(1000U)
static inline uint64_t ticks_to_us(uint64_t ticks)
{
return (ticks * 1000UL) / (uint64_t)tsc_khz;
}
static inline uint64_t ticks_to_ms(uint64_t ticks)
{
return ticks / (uint64_t)tsc_khz;
}
static inline uint64_t rdtsc(void)
{
uint32_t lo, hi;
asm volatile("rdtsc" : "=a" (lo), "=d" (hi));
return ((uint64_t)hi << 32U) | lo;
}
#endif /* RTL_H */