blob: 0e9679235eafe3cdc25c6185f86da4aadd371a76 [file] [log] [blame]
#include "libcflat.h"
#include "processor.h"
#define IA32_TSC_ADJUST 0x3b
int main()
{
u64 t1, t2, t3, t4, t5;
u64 est_delta_time;
bool pass = true;
if (cpuid(7).b & (1 << 1)) { // IA32_TSC_ADJUST Feature is enabled?
if ( rdmsr(IA32_TSC_ADJUST) != 0x0) {
printf("failure: IA32_TSC_ADJUST msr was incorrectly"
" initialized\n");
pass = false;
}
t3 = 100000000000ull;
t1 = rdtsc();
wrmsr(IA32_TSC_ADJUST, t3);
t2 = rdtsc();
if (rdmsr(IA32_TSC_ADJUST) != t3) {
printf("failure: IA32_TSC_ADJUST msr read / write"
" incorrect\n");
pass = false;
}
if (t2 - t1 < t3) {
printf("failure: TSC did not adjust for IA32_TSC_ADJUST"
" value\n");
pass = false;
}
t3 = 0x0;
wrmsr(IA32_TSC_ADJUST, t3);
if (rdmsr(IA32_TSC_ADJUST) != t3) {
printf("failure: IA32_TSC_ADJUST msr read / write"
" incorrect\n");
pass = false;
}
t4 = 100000000000ull;
t1 = rdtsc();
wrtsc(t4);
t2 = rdtsc();
t5 = rdmsr(IA32_TSC_ADJUST);
// est of time between reading tsc and writing tsc,
// (based on IA32_TSC_ADJUST msr value) should be small
est_delta_time = t4 - t5 - t1;
if (est_delta_time > 2 * (t2 - t4)) {
// arbitray 2x latency (wrtsc->rdtsc) threshold
printf("failure: IA32_TSC_ADJUST msr incorrectly"
" adjusted on tsc write\n");
pass = false;
}
if (pass) printf("success: IA32_TSC_ADJUST enabled and"
" working correctly\n");
}
else {
printf("success: IA32_TSC_ADJUST feature not enabled\n");
}
return pass?0:1;
}