blob: 66451ad711c71936100e47c503c14c718ef64aa8 [file] [log] [blame]
Eric Biedermanc84c1902004-10-14 20:13:01 +00001#ifndef CPU_X86_TSC_H
2#define CPU_X86_TSC_H
3
Stefan Reinauer0db68202012-08-07 14:44:51 -07004#if CONFIG_TSC_SYNC_MFENCE
5#define TSC_SYNC "mfence\n"
6#elif CONFIG_TSC_SYNC_LFENCE
7#define TSC_SYNC "lfence\n"
8#else
9#define TSC_SYNC
10#endif
11
Eric Biedermanc84c1902004-10-14 20:13:01 +000012struct tsc_struct {
13 unsigned lo;
14 unsigned hi;
15};
16typedef struct tsc_struct tsc_t;
17
Stefan Reinauer348a1ba2010-03-17 01:51:11 +000018static inline tsc_t rdtsc(void)
Eric Biedermanc84c1902004-10-14 20:13:01 +000019{
20 tsc_t res;
Stefan Reinauer0db68202012-08-07 14:44:51 -070021 asm volatile (
22 TSC_SYNC
Eric Biedermanc84c1902004-10-14 20:13:01 +000023 "rdtsc"
24 : "=a" (res.lo), "=d"(res.hi) /* outputs */
Stefan Reinauer0db68202012-08-07 14:44:51 -070025 );
Eric Biedermanc84c1902004-10-14 20:13:01 +000026 return res;
27}
28
Stefan Reinauer35b6bbb2010-03-28 21:26:54 +000029#if !defined(__ROMCC__)
Ronald G. Minnich5750fdd2013-05-08 17:08:55 +020030/* Simple 32- to 64-bit multiplication. Uses 16-bit words to avoid overflow.
31 * This code is used to prevent use of libgcc's umoddi3.
32 */
33static inline void multiply_to_tsc(tsc_t *const tsc, const u32 a, const u32 b)
34{
35 tsc->lo = (a & 0xffff) * (b & 0xffff);
36 tsc->hi = ((tsc->lo >> 16)
37 + ((a & 0xffff) * (b >> 16))
38 + ((b & 0xffff) * (a >> 16)));
39 tsc->lo = ((tsc->hi & 0xffff) << 16) | (tsc->lo & 0xffff);
40 tsc->hi = ((a >> 16) * (b >> 16)) + (tsc->hi >> 16);
41}
42
Stefan Reinauer35b6bbb2010-03-28 21:26:54 +000043/* Too many registers for ROMCC */
Eric Biedermanc84c1902004-10-14 20:13:01 +000044static inline unsigned long long rdtscll(void)
45{
46 unsigned long long val;
Stefan Reinauer0db68202012-08-07 14:44:51 -070047 asm volatile (
48 TSC_SYNC
49 "rdtsc"
50 : "=A" (val)
51 );
Eric Biedermanc84c1902004-10-14 20:13:01 +000052 return val;
53}
Eric Biedermanc84c1902004-10-14 20:13:01 +000054#endif
55
Aaron Durbin8e73b5d2013-05-01 15:27:09 -050056#if CONFIG_TSC_CONSTANT_RATE
57unsigned long tsc_freq_mhz(void);
58#endif
59
Eric Biedermanc84c1902004-10-14 20:13:01 +000060#endif /* CPU_X86_TSC_H */