199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * Copyright(c) 2010-2014 Intel Corporation. 399a2dd95SBruce Richardson * Copyright(c) 2013 6WIND S.A. 499a2dd95SBruce Richardson */ 599a2dd95SBruce Richardson 699a2dd95SBruce Richardson #ifndef _RTE_CYCLES_H_ 799a2dd95SBruce Richardson #define _RTE_CYCLES_H_ 899a2dd95SBruce Richardson 999a2dd95SBruce Richardson /** 1099a2dd95SBruce Richardson * @file 1199a2dd95SBruce Richardson * 1299a2dd95SBruce Richardson * Simple Time Reference Functions (Cycles and HPET). 1399a2dd95SBruce Richardson */ 1499a2dd95SBruce Richardson 1599a2dd95SBruce Richardson #include <stdint.h> 1699a2dd95SBruce Richardson #include <rte_debug.h> 1799a2dd95SBruce Richardson #include <rte_atomic.h> 1899a2dd95SBruce Richardson 19*719834a6SMattias Rönnblom #ifdef __cplusplus 20*719834a6SMattias Rönnblom extern "C" { 21*719834a6SMattias Rönnblom #endif 22*719834a6SMattias Rönnblom 2399a2dd95SBruce Richardson #define MS_PER_S 1000 2499a2dd95SBruce Richardson #define US_PER_S 1000000 2599a2dd95SBruce Richardson #define NS_PER_S 1000000000 2699a2dd95SBruce Richardson 2799a2dd95SBruce Richardson enum timer_source { 2899a2dd95SBruce Richardson EAL_TIMER_TSC = 0, 2999a2dd95SBruce Richardson EAL_TIMER_HPET 3099a2dd95SBruce Richardson }; 3199a2dd95SBruce Richardson extern enum timer_source eal_timer_source; 3299a2dd95SBruce Richardson 3399a2dd95SBruce Richardson /** 3499a2dd95SBruce Richardson * Get the measured frequency of the RDTSC counter 3599a2dd95SBruce Richardson * 3699a2dd95SBruce Richardson * @return 3799a2dd95SBruce Richardson * The TSC frequency for this lcore 3899a2dd95SBruce Richardson */ 3999a2dd95SBruce Richardson uint64_t 4099a2dd95SBruce Richardson rte_get_tsc_hz(void); 4199a2dd95SBruce Richardson 4299a2dd95SBruce Richardson /** 4399a2dd95SBruce Richardson * Return the number of TSC cycles since boot 4499a2dd95SBruce Richardson * 4599a2dd95SBruce Richardson * @return 4699a2dd95SBruce Richardson * the number of cycles 4799a2dd95SBruce Richardson */ 4899a2dd95SBruce Richardson static inline uint64_t 4999a2dd95SBruce Richardson rte_get_tsc_cycles(void); 5099a2dd95SBruce Richardson 5199a2dd95SBruce Richardson #ifdef RTE_LIBEAL_USE_HPET 5299a2dd95SBruce Richardson /** 5399a2dd95SBruce Richardson * Return the number of HPET cycles since boot 5499a2dd95SBruce Richardson * 5599a2dd95SBruce Richardson * This counter is global for all execution units. The number of 5699a2dd95SBruce Richardson * cycles in one second can be retrieved using rte_get_hpet_hz(). 5799a2dd95SBruce Richardson * 5899a2dd95SBruce Richardson * @return 5999a2dd95SBruce Richardson * the number of cycles 6099a2dd95SBruce Richardson */ 6199a2dd95SBruce Richardson uint64_t 6299a2dd95SBruce Richardson rte_get_hpet_cycles(void); 6399a2dd95SBruce Richardson 6499a2dd95SBruce Richardson /** 6599a2dd95SBruce Richardson * Get the number of HPET cycles in one second. 6699a2dd95SBruce Richardson * 6799a2dd95SBruce Richardson * @return 6899a2dd95SBruce Richardson * The number of cycles in one second. 6999a2dd95SBruce Richardson */ 7099a2dd95SBruce Richardson uint64_t 7199a2dd95SBruce Richardson rte_get_hpet_hz(void); 7299a2dd95SBruce Richardson 7399a2dd95SBruce Richardson /** 7499a2dd95SBruce Richardson * Initialise the HPET for use. This must be called before the rte_get_hpet_hz 7599a2dd95SBruce Richardson * and rte_get_hpet_cycles APIs are called. If this function does not succeed, 7699a2dd95SBruce Richardson * then the HPET functions are unavailable and should not be called. 7799a2dd95SBruce Richardson * 7899a2dd95SBruce Richardson * @param make_default 7999a2dd95SBruce Richardson * If set, the hpet timer becomes the default timer whose values are 8099a2dd95SBruce Richardson * returned by the rte_get_timer_hz/cycles API calls 8199a2dd95SBruce Richardson * 8299a2dd95SBruce Richardson * @return 8399a2dd95SBruce Richardson * 0 on success, 8499a2dd95SBruce Richardson * -1 on error, and the make_default parameter is ignored. 8599a2dd95SBruce Richardson */ 8699a2dd95SBruce Richardson int rte_eal_hpet_init(int make_default); 8799a2dd95SBruce Richardson 8899a2dd95SBruce Richardson #endif 8999a2dd95SBruce Richardson 9099a2dd95SBruce Richardson /** 9199a2dd95SBruce Richardson * Get the number of cycles since boot from the default timer. 9299a2dd95SBruce Richardson * 9399a2dd95SBruce Richardson * @return 9499a2dd95SBruce Richardson * The number of cycles 9599a2dd95SBruce Richardson */ 9699a2dd95SBruce Richardson static inline uint64_t 9799a2dd95SBruce Richardson rte_get_timer_cycles(void) 9899a2dd95SBruce Richardson { 9999a2dd95SBruce Richardson #ifdef RTE_LIBEAL_USE_HPET 10099a2dd95SBruce Richardson switch(eal_timer_source) { 10199a2dd95SBruce Richardson case EAL_TIMER_TSC: 10299a2dd95SBruce Richardson #endif 10399a2dd95SBruce Richardson return rte_get_tsc_cycles(); 10499a2dd95SBruce Richardson #ifdef RTE_LIBEAL_USE_HPET 10599a2dd95SBruce Richardson case EAL_TIMER_HPET: 10699a2dd95SBruce Richardson return rte_get_hpet_cycles(); 10799a2dd95SBruce Richardson default: rte_panic("Invalid timer source specified\n"); 10899a2dd95SBruce Richardson } 10999a2dd95SBruce Richardson #endif 11099a2dd95SBruce Richardson } 11199a2dd95SBruce Richardson 11299a2dd95SBruce Richardson /** 11399a2dd95SBruce Richardson * Get the number of cycles in one second for the default timer. 11499a2dd95SBruce Richardson * 11599a2dd95SBruce Richardson * @return 11699a2dd95SBruce Richardson * The number of cycles in one second. 11799a2dd95SBruce Richardson */ 11899a2dd95SBruce Richardson static inline uint64_t 11999a2dd95SBruce Richardson rte_get_timer_hz(void) 12099a2dd95SBruce Richardson { 12199a2dd95SBruce Richardson #ifdef RTE_LIBEAL_USE_HPET 12299a2dd95SBruce Richardson switch(eal_timer_source) { 12399a2dd95SBruce Richardson case EAL_TIMER_TSC: 12499a2dd95SBruce Richardson #endif 12599a2dd95SBruce Richardson return rte_get_tsc_hz(); 12699a2dd95SBruce Richardson #ifdef RTE_LIBEAL_USE_HPET 12799a2dd95SBruce Richardson case EAL_TIMER_HPET: 12899a2dd95SBruce Richardson return rte_get_hpet_hz(); 12999a2dd95SBruce Richardson default: rte_panic("Invalid timer source specified\n"); 13099a2dd95SBruce Richardson } 13199a2dd95SBruce Richardson #endif 13299a2dd95SBruce Richardson } 13399a2dd95SBruce Richardson /** 13499a2dd95SBruce Richardson * Wait at least us microseconds. 13599a2dd95SBruce Richardson * This function can be replaced with user-defined function. 13699a2dd95SBruce Richardson * @see rte_delay_us_callback_register 13799a2dd95SBruce Richardson * 13899a2dd95SBruce Richardson * @param us 13999a2dd95SBruce Richardson * The number of microseconds to wait. 14099a2dd95SBruce Richardson */ 14199a2dd95SBruce Richardson extern void 14299a2dd95SBruce Richardson (*rte_delay_us)(unsigned int us); 14399a2dd95SBruce Richardson 14499a2dd95SBruce Richardson /** 14599a2dd95SBruce Richardson * Wait at least ms milliseconds. 14699a2dd95SBruce Richardson * 14799a2dd95SBruce Richardson * @param ms 14899a2dd95SBruce Richardson * The number of milliseconds to wait. 14999a2dd95SBruce Richardson */ 15099a2dd95SBruce Richardson static inline void 15199a2dd95SBruce Richardson rte_delay_ms(unsigned ms) 15299a2dd95SBruce Richardson { 15399a2dd95SBruce Richardson rte_delay_us(ms * 1000); 15499a2dd95SBruce Richardson } 15599a2dd95SBruce Richardson 15699a2dd95SBruce Richardson /** 15799a2dd95SBruce Richardson * Blocking delay function. 15899a2dd95SBruce Richardson * 15999a2dd95SBruce Richardson * @param us 16099a2dd95SBruce Richardson * Number of microseconds to wait. 16199a2dd95SBruce Richardson */ 16299a2dd95SBruce Richardson void rte_delay_us_block(unsigned int us); 16399a2dd95SBruce Richardson 16499a2dd95SBruce Richardson /** 16599a2dd95SBruce Richardson * Delay function that uses system sleep. 16699a2dd95SBruce Richardson * Does not block the CPU core. 16799a2dd95SBruce Richardson * 16899a2dd95SBruce Richardson * @param us 16999a2dd95SBruce Richardson * Number of microseconds to wait. 17099a2dd95SBruce Richardson */ 17196c3a928SStephen Hemminger void rte_delay_us_sleep(unsigned int us); 17299a2dd95SBruce Richardson 17399a2dd95SBruce Richardson /** 17499a2dd95SBruce Richardson * Replace rte_delay_us with user defined function. 17599a2dd95SBruce Richardson * 17699a2dd95SBruce Richardson * @param userfunc 17799a2dd95SBruce Richardson * User function which replaces rte_delay_us. rte_delay_us_block restores 17899a2dd95SBruce Richardson * builtin block delay function. 17999a2dd95SBruce Richardson */ 18099a2dd95SBruce Richardson void rte_delay_us_callback_register(void(*userfunc)(unsigned int)); 18199a2dd95SBruce Richardson 182*719834a6SMattias Rönnblom #ifdef __cplusplus 183*719834a6SMattias Rönnblom } 184*719834a6SMattias Rönnblom #endif 185*719834a6SMattias Rönnblom 18699a2dd95SBruce Richardson #endif /* _RTE_CYCLES_H_ */ 187