1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/types.h>
7 #include "../../../util/debug.h"
8 #include "../../../util/tsc.h"
13 unsigned int low
, high
;
15 asm volatile("rdtsc" : "=a" (low
), "=d" (high
));
17 return low
| ((u64
)high
) << 32;
21 * Derive the TSC frequency in Hz from the /proc/cpuinfo, for example:
23 * model name : Intel(R) Xeon(R) Gold 6154 CPU @ 3.00GHz
25 * will return 3000000000.
27 static u64
cpuinfo_tsc_freq(void)
34 cpuinfo
= fopen("/proc/cpuinfo", "r");
36 pr_err("Failed to read /proc/cpuinfo for TSC frequency\n");
39 while (getline(&line
, &len
, cpuinfo
) > 0) {
40 if (!strncmp(line
, "model name", 10)) {
41 char *pos
= strstr(line
+ 11, " @ ");
44 if (pos
&& sscanf(pos
, " @ %lfGHz", &float_result
) == 1) {
45 float_result
*= 1000000000;
46 result
= (u64
)float_result
;
53 pr_err("Failed to find TSC frequency in /proc/cpuinfo\n");
60 u64
arch_get_tsc_freq(void)
62 unsigned int a
, b
, c
, d
, lvl
;
71 get_cpuid_0(vendor
, &lvl
);
72 if (!strstr(vendor
, "Intel"))
76 * Don't support Time Stamp Counter and
77 * Nominal Core Crystal Clock Information Leaf.
80 tsc
= cpuinfo_tsc_freq();
84 cpuid(0x15, 0, &a
, &b
, &c
, &d
);
85 /* TSC frequency is not enumerated */
87 tsc
= cpuinfo_tsc_freq();
91 tsc
= (u64
)c
* (u64
)b
/ (u64
)a
;