1*5fecf5d8SWill Auld #include "libcflat.h" 2*5fecf5d8SWill Auld #include "processor.h" 3*5fecf5d8SWill Auld 4*5fecf5d8SWill Auld #define IA32_TSC_ADJUST 0x3b 5*5fecf5d8SWill Auld 6*5fecf5d8SWill Auld int main() 7*5fecf5d8SWill Auld { 8*5fecf5d8SWill Auld u64 t1, t2, t3, t4, t5; 9*5fecf5d8SWill Auld u64 est_delta_time; 10*5fecf5d8SWill Auld bool pass = true; 11*5fecf5d8SWill Auld 12*5fecf5d8SWill Auld if (cpuid(7).b & (1 << 1)) { // IA32_TSC_ADJUST Feature is enabled? 13*5fecf5d8SWill Auld if ( rdmsr(IA32_TSC_ADJUST) != 0x0) { 14*5fecf5d8SWill Auld printf("failure: IA32_TSC_ADJUST msr was incorrectly" 15*5fecf5d8SWill Auld " initialized\n"); 16*5fecf5d8SWill Auld pass = false; 17*5fecf5d8SWill Auld } 18*5fecf5d8SWill Auld t3 = 100000000000ull; 19*5fecf5d8SWill Auld t1 = rdtsc(); 20*5fecf5d8SWill Auld wrmsr(IA32_TSC_ADJUST, t3); 21*5fecf5d8SWill Auld t2 = rdtsc(); 22*5fecf5d8SWill Auld if (rdmsr(IA32_TSC_ADJUST) != t3) { 23*5fecf5d8SWill Auld printf("failure: IA32_TSC_ADJUST msr read / write" 24*5fecf5d8SWill Auld " incorrect\n"); 25*5fecf5d8SWill Auld pass = false; 26*5fecf5d8SWill Auld } 27*5fecf5d8SWill Auld if (t2 - t1 < t3) { 28*5fecf5d8SWill Auld printf("failure: TSC did not adjust for IA32_TSC_ADJUST" 29*5fecf5d8SWill Auld " value\n"); 30*5fecf5d8SWill Auld pass = false; 31*5fecf5d8SWill Auld } 32*5fecf5d8SWill Auld t3 = 0x0; 33*5fecf5d8SWill Auld wrmsr(IA32_TSC_ADJUST, t3); 34*5fecf5d8SWill Auld if (rdmsr(IA32_TSC_ADJUST) != t3) { 35*5fecf5d8SWill Auld printf("failure: IA32_TSC_ADJUST msr read / write" 36*5fecf5d8SWill Auld " incorrect\n"); 37*5fecf5d8SWill Auld pass = false; 38*5fecf5d8SWill Auld } 39*5fecf5d8SWill Auld t4 = 100000000000ull; 40*5fecf5d8SWill Auld t1 = rdtsc(); 41*5fecf5d8SWill Auld wrtsc(t4); 42*5fecf5d8SWill Auld t2 = rdtsc(); 43*5fecf5d8SWill Auld t5 = rdmsr(IA32_TSC_ADJUST); 44*5fecf5d8SWill Auld // est of time between reading tsc and writing tsc, 45*5fecf5d8SWill Auld // (based on IA32_TSC_ADJUST msr value) should be small 46*5fecf5d8SWill Auld est_delta_time = t4 - t5 - t1; 47*5fecf5d8SWill Auld if (est_delta_time > 2 * (t2 - t4)) { 48*5fecf5d8SWill Auld // arbitray 2x latency (wrtsc->rdtsc) threshold 49*5fecf5d8SWill Auld printf("failure: IA32_TSC_ADJUST msr incorrectly" 50*5fecf5d8SWill Auld " adjusted on tsc write\n"); 51*5fecf5d8SWill Auld pass = false; 52*5fecf5d8SWill Auld } 53*5fecf5d8SWill Auld if (pass) printf("success: IA32_TSC_ADJUST enabled and" 54*5fecf5d8SWill Auld " working correctly\n"); 55*5fecf5d8SWill Auld } 56*5fecf5d8SWill Auld else { 57*5fecf5d8SWill Auld printf("success: IA32_TSC_ADJUST feature not enabled\n"); 58*5fecf5d8SWill Auld } 59*5fecf5d8SWill Auld return pass?0:1; 60*5fecf5d8SWill Auld } 61