1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #ifndef CPU_X86_TSC_H 4 #define CPU_X86_TSC_H 5 6 #include <stdint.h> 7 8 #if CONFIG(TSC_SYNC_MFENCE) 9 #define TSC_SYNC "mfence\n" 10 #elif CONFIG(TSC_SYNC_LFENCE) 11 #define TSC_SYNC "lfence\n" 12 #else 13 #define TSC_SYNC 14 #endif 15 16 struct tsc_struct { 17 unsigned int lo; 18 unsigned int hi; 19 }; 20 typedef struct tsc_struct tsc_t; 21 rdtsc(void)22static inline tsc_t rdtsc(void) 23 { 24 tsc_t res; 25 asm volatile ( 26 TSC_SYNC 27 "rdtsc" 28 : "=a" (res.lo), "=d"(res.hi) /* outputs */ 29 ); 30 return res; 31 } 32 33 /* Simple 32- to 64-bit multiplication. Uses 16-bit words to avoid overflow. 34 * This code is used to prevent use of libgcc's umoddi3. 35 */ multiply_to_tsc(tsc_t * const tsc,const u32 a,const u32 b)36static inline void multiply_to_tsc(tsc_t *const tsc, const u32 a, const u32 b) 37 { 38 tsc->lo = (a & 0xffff) * (b & 0xffff); 39 tsc->hi = ((tsc->lo >> 16) 40 + ((a & 0xffff) * (b >> 16)) 41 + ((b & 0xffff) * (a >> 16))); 42 tsc->lo = ((tsc->hi & 0xffff) << 16) | (tsc->lo & 0xffff); 43 tsc->hi = ((a >> 16) * (b >> 16)) + (tsc->hi >> 16); 44 } 45 tsc_to_uint64(tsc_t tstamp)46static inline uint64_t tsc_to_uint64(tsc_t tstamp) 47 { 48 return (((uint64_t)tstamp.hi) << 32) + tstamp.lo; 49 } 50 rdtscll(void)51static inline unsigned long long rdtscll(void) 52 { 53 return tsc_to_uint64(rdtsc()); 54 } 55 56 /* Provided by CPU/chipset code for the TSC rate in MHz. */ 57 unsigned long tsc_freq_mhz(void); 58 tsc_constant_rate(void)59static inline int tsc_constant_rate(void) 60 { 61 return !CONFIG(UNKNOWN_TSC_RATE); 62 } 63 64 #endif /* CPU_X86_TSC_H */ 65