acrn-hypervisor/hypervisor/arch/x86/tsc_deadline_timer.c
Liang Yi 3547c9cd23 hv/mod_timer: make timer into an arch-independent module
x86/timer.[ch] was moved to the common directory largely unchanged.

x86 specific code now resides in x86/tsc_deadline_timer.c and its
interface was defined in hw/hw_timer.h. The interface defines two
functions: init_hw_timer() and set_hw_timeout() that provides HW
specific initialization and timer interrupt source.

Other than these two functions, the timer module is largely arch
agnostic.

Tracked-On: #5920
Signed-off-by: Rong Liu <rong2.liu@intel.com>
Reviewed-by: Jason Chen CJ <jason.cj.chen@intel.com>
2021-05-18 16:43:28 +08:00

51 lines
1.1 KiB
C

/*
* Copyright (C) 2021 Intel Corporation.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <types.h>
#include <softirq.h>
#include <irq.h>
#include <logmsg.h>
#include <asm/cpu.h>
#include <asm/msr.h>
#include <asm/irq.h>
#include <asm/apicreg.h>
#include <hw/hw_timer.h>
/* run in interrupt context */
static void timer_expired_handler(__unused uint32_t irq, __unused void *data)
{
fire_softirq(SOFTIRQ_TIMER);
}
void set_hw_timeout(uint64_t timeout)
{
msr_write(MSR_IA32_TSC_DEADLINE, timeout);
}
void init_hw_timer(void)
{
int32_t retval = 0;
if (get_pcpu_id() == BSP_CPU_ID) {
retval = request_irq(TIMER_IRQ, (irq_action_t)timer_expired_handler, NULL, IRQF_NONE);
if (retval < 0) {
pr_err("Timer setup failed");
}
}
if (retval >= 0) {
uint32_t val = TIMER_VECTOR;
val |= APIC_LVTT_TM_TSCDLT; /* TSC deadline and unmask */
msr_write(MSR_IA32_EXT_APIC_LVT_TIMER, val);
/* SDM 10.5.4.1: In x2APIC mode, the processor ensures the
ordering of this write and any subsequent WRMSR to the
deadline; no fencing is required. */
/* disarm timer */
msr_write(MSR_IA32_TSC_DEADLINE, 0UL);
}
}