xref: /kvm-unit-tests/x86/tsc.c (revision 7db17e21adeedeba0f421f4c23f13934577f0264)
1 #include "libcflat.h"
2 #include "processor.h"
3 
4 #define CPUID_80000001_EDX_RDTSCP	    (1 << 27)
5 int check_cpuid_80000001_edx(unsigned int bit)
6 {
7     return (cpuid(0x80000001).d & bit) != 0;
8 }
9 
10 #define CPUID_7_0_ECX_RDPID		    (1 << 22)
11 int check_cpuid_7_0_ecx(unsigned int bit)
12 {
13     return (cpuid_indexed(7, 0).c & bit) != 0;
14 }
15 
16 void test_wrtsc(u64 t1)
17 {
18 	u64 t2;
19 
20 	wrtsc(t1);
21 	t2 = rdtsc();
22 	printf("rdtsc after wrtsc(%" PRId64 "): %" PRId64 "\n", t1, t2);
23 }
24 
25 void test_rdtscp(u64 aux)
26 {
27        u32 ecx;
28 
29        wrmsr(MSR_TSC_AUX, aux);
30        rdtscp(&ecx);
31        report("Test RDTSCP %" PRIu64, ecx == aux, aux);
32 }
33 
34 void test_rdpid(u64 aux)
35 {
36        u32 eax;
37 
38        wrmsr(MSR_TSC_AUX, aux);
39        asm (".byte 0xf3, 0x0f, 0xc7, 0xf8" : "=a" (eax));
40        report("Test rdpid %%eax %d", eax == aux, aux);
41 }
42 
43 int main(void)
44 {
45 	u64 t1, t2;
46 
47 	t1 = rdtsc();
48 	t2 = rdtsc();
49 	printf("rdtsc latency %u\n", (unsigned)(t2 - t1));
50 
51 	test_wrtsc(0);
52 	test_wrtsc(100000000000ull);
53 
54 	if (check_cpuid_80000001_edx(CPUID_80000001_EDX_RDTSCP)) {
55 		test_rdtscp(0);
56 		test_rdtscp(10);
57 		test_rdtscp(0x100);
58 	} else
59 		printf("rdtscp not supported\n");
60 
61 	if (check_cpuid_7_0_ecx(CPUID_7_0_ECX_RDPID)) {
62 		test_rdpid(0);
63 		test_rdpid(10);
64 		test_rdpid(0x100);
65 	} else
66 		printf("rdpid not supported\n");
67 	return report_summary();
68 }
69