Timer

Because ACRN is a flexible, lightweight reference hypervisor, we provide limited timer management services:

  • Only the lapic tsc-deadline timer is supported as the clock source.

  • A timer can only be added on the logical CPU for a process or thread. Timer scheduling or timer migrating is not supported.

How It Works

When the system boots, we check that the hardware supports lapic tsc-deadline timer by checking CPUID.01H:ECX.TSC_Deadline[bit 24]. If support is missing, we output an error message and panic the hypervisor. If supported, we register the timer interrupt callback that raises a timer softirq on each logical CPU and sets the lapic timer mode to tsc-deadline timer mode by writing the local APIC LVT register.

Data Structures and APIs

Interfaces Design

void initialize_timer(struct hv_timer *timer, timer_handle_t func, void *priv_data, uint64_t fire_tsc, uint64_t period_in_cycle)

Initialize a timer structure.

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

Parameters
  • [in] timer: Pointer to timer.

  • [in] func: irq callback if time reached.

  • [in] priv_data: func private data.

  • [in] fire_tsc: tsc deadline to interrupt.

  • [in] period_in_cycle: period of the periodic timer in unit of TSC cycles.

bool timer_expired(const struct hv_timer *timer, uint64_t now, uint64_t *delta)

Check a timer whether expired.

Parameters
  • [in] timer: Pointer to timer.

  • [in] now: to compare.

  • [in] delta: Pointer to return the delta (timeout - now) if timer is not expired.

Return Value
  • true: if the timer is expired, false otherwise.

bool timer_is_started(const struct hv_timer *timer)

Check if a timer is active (in the timer list) or not.

Parameters
  • [in] timer: Pointer to timer.

Return Value
  • true: if the timer is in timer list, false otherwise.

int32_t add_timer(struct hv_timer *timer)

Add a timer.

Remark

Don’t call it in the timer callback function or interrupt content.

Parameters
  • [in] timer: Pointer to timer.

Return Value
  • 0: on success

  • -EINVAL: timer has an invalid value

void del_timer(struct hv_timer *timer)

Delete a timer.

Return

None

Remark

Don’t call it in the timer callback function or interrupt content.

Parameters
  • [in] timer: Pointer to timer.

void timer_init(void)

Initialize timer.

Return

None

void calibrate_tsc(void)

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

uint64_t cpu_ticks(void)

Read current CPU tick count.

Remark

On x86, this is the Time Stamp Counter (TSC) value of the current logical CPU.

Return

CPU ticks

uint32_t cpu_tickrate(void)

Get CPU tick frequency in KHz.

Remark

On x86, this is the Time Stamp Counter (TSC) frequency of the current logical CPU.

Return

CPU frequency (KHz)

uint64_t us_to_ticks(uint32_t us)

Convert micro seconds to CPU ticks.

Return

CPU ticks

Parameters
  • [in] us: micro seconds to convert

uint64_t ticks_to_us(uint64_t ticks)

Convert CPU cycles to micro seconds.

Return

microsecond

Parameters
  • [in] ticks: CPU ticks to convert

uint64_t ticks_to_ms(uint64_t ticks)

Convert CPU cycles to milli seconds.

Return

millisecond

Parameters
  • [in] ticks: CPU ticks to convert

void udelay(uint32_t us)

Busy wait a few micro seconds.

Parameters
  • [in] us: micro seconds to delay.

Return Value
  • None: