mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-02 00:08:43 +00:00
doc: hv: add comments to timer APIs for documentation
This patch adds more comment to describe functions that are interfaces to the other modules in the hypervisor. The comments are in doxygen-style for document generation. Tracked-On: #1595 Signed-off-by: Li, Fei1 <fei1.li@intel.com>
This commit is contained in:
parent
2dbb0cbafc
commit
5fd6021dee
@ -808,6 +808,7 @@ INPUT = custom-doxygen/mainpage.md \
|
||||
../hypervisor/include/public/acrn_common.h \
|
||||
../hypervisor/include/public/acrn_hv_defs.h \
|
||||
../hypervisor/include/arch/x86/guest/vcpu.h \
|
||||
../hypervisor/include/arch/x86/timer.h \
|
||||
../hypervisor/arch/x86/trusty.c \
|
||||
../devicemodel/include/virtio.h \
|
||||
../hypervisor/include/arch/x86/ioapic.h \
|
||||
|
@ -24,37 +24,27 @@ tsc-deadline timer mode by writing the local APIC LVT register.
|
||||
Data Structures and APIs
|
||||
************************
|
||||
|
||||
.. note:: API link to hv_timer and per_cpu_timer structs in include/arch/x86/timer.h
|
||||
And to the function APIs there too.
|
||||
Interfaces Design
|
||||
=================
|
||||
|
||||
Before adding a timer, we must initialize the timer with
|
||||
*initialize_timer*. The processor generates a timer interrupt when the
|
||||
value of timer-stamp counter is greater than or equal to the *fire_tsc*
|
||||
field. If you want to add a periodic timer, you should also pass the
|
||||
period (unit in tsc cycles), otherwise, period_in_cycle will be ignored.
|
||||
When the timer interrupt is generated, it will call the callback
|
||||
function *func* with parameter *priv_data*.
|
||||
.. doxygenfunction:: initialize_timer
|
||||
:project: Project ACRN
|
||||
|
||||
The *initialize_timer* function only initialize the timer data
|
||||
structure; it will not program the ``IA32_TSC_DEADLINE_MSR`` to generate
|
||||
the timer interrupt. If you want to generate a timer interrupt, you must
|
||||
call *add_timer* to add the timer to the *per_cpu_timer* timer_list. In
|
||||
return, we will chose the nearest expired timer on the timer_list and
|
||||
program ``IA32_TSC_DEADLINE_MSR`` by writing its value to fire_ts. Then
|
||||
when the fire_tsc expires, it raises the interrupt whose callback raises
|
||||
a softirq. We will handle the software interrupt before the VM reenters
|
||||
the guest. (Currently, the hypervisor only uses the timer for the
|
||||
console).
|
||||
.. doxygenfunction:: timer_expired
|
||||
:project: Project ACRN
|
||||
|
||||
The timer softirq handler will check each expired timer on its
|
||||
timer_list. Before calling the expired timer callback handler, it will
|
||||
remove the timer from its logical cpu timer_list. After calling the
|
||||
timer callback handler, it will re-add the timer to the timer_list if
|
||||
it's a periodic timer. If you want to modify a timer before it expires,
|
||||
you should call del_timer to remove the timer from the timer_list, then
|
||||
call add_timer again after updating the timer fields.
|
||||
.. doxygenfunction:: add_timer
|
||||
:project: Project ACRN
|
||||
|
||||
.. note::
|
||||
.. doxygenfunction:: del_timer
|
||||
:project: Project ACRN
|
||||
|
||||
.. doxygenfunction:: timer_init
|
||||
:project: Project ACRN
|
||||
|
||||
.. doxygenfunction:: check_tsc
|
||||
:project: Project ACRN
|
||||
|
||||
.. doxygenfunction:: calibrate_tsc
|
||||
:project: Project ACRN
|
||||
|
||||
Only call initialize_timer only once for each timer.
|
||||
Don't call add_timer or del_timer in the timer callback function.
|
||||
|
@ -7,36 +7,62 @@
|
||||
#ifndef TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
/**
|
||||
* @brief Timer
|
||||
*
|
||||
* @defgroup timer ACRN Timer
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef void (*timer_handle_t)(void *data);
|
||||
|
||||
/**
|
||||
* @brief Definition of timer tick mode
|
||||
*/
|
||||
enum tick_mode {
|
||||
TICK_MODE_ONESHOT = 0,
|
||||
TICK_MODE_PERIODIC,
|
||||
TICK_MODE_ONESHOT = 0, /**< one-shot mode */
|
||||
TICK_MODE_PERIODIC, /**< periodic mode */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Definition of timers for per-cpu
|
||||
*/
|
||||
struct per_cpu_timers {
|
||||
struct list_head timer_list; /* it's for runtime active timer list */
|
||||
struct list_head timer_list; /**< it's for runtime active timer list */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Definition of timer
|
||||
*/
|
||||
struct hv_timer {
|
||||
struct list_head node; /* link all timers */
|
||||
enum tick_mode mode; /* timer mode: one-shot or periodic */
|
||||
uint64_t fire_tsc; /* tsc deadline to interrupt */
|
||||
uint64_t period_in_cycle; /* period of the periodic timer in unit of TSC cycles */
|
||||
timer_handle_t func; /* callback if time reached */
|
||||
void *priv_data; /* func private data */
|
||||
struct list_head node; /**< link all timers */
|
||||
enum tick_mode mode; /**< timer mode: one-shot or periodic */
|
||||
uint64_t fire_tsc; /**< tsc deadline to interrupt */
|
||||
uint64_t period_in_cycle; /**< period of the periodic timer in unit of TSC cycles */
|
||||
timer_handle_t func; /**< callback if time reached */
|
||||
void *priv_data; /**< func private data */
|
||||
};
|
||||
|
||||
/*
|
||||
* Don't initialize a timer twice if it has been add to the timer list
|
||||
* after call add_timer. If u want, delete the timer from the list first.
|
||||
/* External Interfaces */
|
||||
|
||||
/**
|
||||
* @brief Initialize a timer structure.
|
||||
*
|
||||
* @param[in] timer Pointer to timer.
|
||||
* @param[in] func irq callback if time reached.
|
||||
* @param[in] priv_data func private data.
|
||||
* @param[in] fire_tsc tsc deadline to interrupt.
|
||||
* @param[in] mode timer mode.
|
||||
* @param[in] period_in_cycle period of the periodic timer in unit of TSC cycles.
|
||||
*
|
||||
* @remark Don't initialize a timer twice if it has been added to the timer list
|
||||
* after calling add_timer. If you want to, delete the timer from the list first.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void initialize_timer(struct hv_timer *timer,
|
||||
timer_handle_t func,
|
||||
void *priv_data,
|
||||
uint64_t fire_tsc,
|
||||
int mode,
|
||||
uint64_t period_in_cycle)
|
||||
timer_handle_t func, void *priv_data,
|
||||
uint64_t fire_tsc, int mode, uint64_t period_in_cycle)
|
||||
{
|
||||
if (timer != NULL) {
|
||||
timer->func = func;
|
||||
@ -48,19 +74,62 @@ static inline void initialize_timer(struct hv_timer *timer,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check a timer whether expired.
|
||||
*
|
||||
* @param[in] timer Pointer to timer.
|
||||
*
|
||||
* @retval true if the timer is expired, false otherwise.
|
||||
*/
|
||||
static inline bool timer_expired(const struct hv_timer *timer)
|
||||
{
|
||||
return ((timer->fire_tsc == 0UL) || (rdtsc() >= timer->fire_tsc));
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't call add_timer/del_timer in the timer callback function.
|
||||
/**
|
||||
* @brief Add a timer.
|
||||
*
|
||||
* @param[in] timer Pointer to timer.
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -EINVAL timer has an invalid value
|
||||
*
|
||||
* @remark Don't call it in the timer callback function or interrupt content.
|
||||
*/
|
||||
int add_timer(struct hv_timer *timer);
|
||||
|
||||
/**
|
||||
* @brief Delete a timer.
|
||||
*
|
||||
* @param[in] timer Pointer to timer.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @remark Don't call it in the timer callback function or interrupt content.
|
||||
*/
|
||||
void del_timer(struct hv_timer *timer);
|
||||
|
||||
/**
|
||||
* @brief Initialize timer.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void timer_init(void);
|
||||
|
||||
/**
|
||||
* @brief Check tsc to make sure rdtsc is enabled.
|
||||
*/
|
||||
void check_tsc(void);
|
||||
|
||||
/**
|
||||
* @brief Calibrate tsc.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void calibrate_tsc(void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* TIMER_H */
|
||||
|
Loading…
Reference in New Issue
Block a user