mirror of
				https://github.com/projectacrn/acrn-hypervisor.git
				synced 2025-11-04 03:28:59 +00:00 
			
		
		
		
	Since we restore BAR values when writing Command Register if necessary. We don't need to trap FLR and do the BAR restore then. Tracked-On: #3475 Signed-off-by: Li Fei1 <fei1.li@intel.com>
		
			
				
	
	
		
			184 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			184 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Copyright (C) 2018 Intel Corporation. All rights reserved.
 | 
						|
 *
 | 
						|
 * SPDX-License-Identifier: BSD-3-Clause
 | 
						|
 */
 | 
						|
 | 
						|
#ifndef TIMER_H
 | 
						|
#define TIMER_H
 | 
						|
 | 
						|
#include <list.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,	/**< 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 */
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * @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 */
 | 
						|
};
 | 
						|
 | 
						|
/* External Interfaces */
 | 
						|
 | 
						|
#define CYCLES_PER_MS	us_to_ticks(1000U)
 | 
						|
 | 
						|
void udelay(uint32_t us);
 | 
						|
 | 
						|
/**
 | 
						|
 * @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.
 | 
						|
 *
 | 
						|
 * @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, int32_t mode, uint64_t period_in_cycle)
 | 
						|
{
 | 
						|
	if (timer != NULL) {
 | 
						|
		timer->func = func;
 | 
						|
		timer->priv_data = priv_data;
 | 
						|
		timer->fire_tsc = fire_tsc;
 | 
						|
		timer->mode = mode;
 | 
						|
		timer->period_in_cycle = period_in_cycle;
 | 
						|
		INIT_LIST_HEAD(&timer->node);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @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));
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief Check a timer whether in timer list.
 | 
						|
 *
 | 
						|
 * @param[in] timer Pointer to timer.
 | 
						|
 *
 | 
						|
 * @retval true if the timer is in timer list, false otherwise.
 | 
						|
 */
 | 
						|
static inline bool timer_is_started(const struct hv_timer *timer)
 | 
						|
{
 | 
						|
	return (!list_empty(&timer->node));
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @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.
 | 
						|
 */
 | 
						|
int32_t 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 Calibrate tsc.
 | 
						|
 *
 | 
						|
 * @return None
 | 
						|
 */
 | 
						|
void calibrate_tsc(void);
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief  Get tsc.
 | 
						|
 *
 | 
						|
 * @return tsc(KHz)
 | 
						|
 */
 | 
						|
uint32_t get_tsc_khz(void);
 | 
						|
 | 
						|
/**
 | 
						|
 * @}
 | 
						|
 */
 | 
						|
 | 
						|
#endif /* TIMER_H */
 |