diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 1eb340c..b021955 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -57,6 +57,7 @@ class perf_power_bundle: public perf_bundle static class abstract_cpu * new_package(int package, int cpu, char * vendor, int family, int model) { + uint64_t msr; class abstract_cpu *ret = NULL; class cpudevice *cpudev; char packagename[128]; @@ -71,15 +72,19 @@ static class abstract_cpu * new_package(int package, int cpu, char * vendor, int case 0x25: /* Westmere */ case 0x27: /* Medfield Atom*/ case 0x2C: /* Westmere */ - ret = new class nhm_package; + if (read_msr(cpu, MSR_APERF, &msr) >= 0) + ret = new class nhm_package; break; case 0x2A: /* SNB */ case 0x2D: /* SNB Xeon */ case 0x3A: /* IVB */ case 0x3C: case 0x3D: /* IVB Xeon */ - has_c2c7_res = 1; - ret = new class nhm_package; + if (read_msr(cpu, MSR_PKG_C7_RESIDENCY, &msr) >= 0) + { + has_c2c7_res = 1; + ret = new class nhm_package; + } break; } } @@ -99,6 +104,7 @@ static class abstract_cpu * new_package(int package, int cpu, char * vendor, int static class abstract_cpu * new_core(int core, int cpu, char * vendor, int family, int model) { + uint64_t msr; class abstract_cpu *ret = NULL; if (strcmp(vendor, "GenuineIntel") == 0) { @@ -116,7 +122,8 @@ static class abstract_cpu * new_core(int core, int cpu, char * vendor, int famil case 0x3A: /* IVB */ case 0x3C: case 0x3D: /* IVB Xeon */ - ret = new class nhm_core; + if (read_msr(cpu, MSR_APERF, &msr) >= 0) + ret = new class nhm_core; } } @@ -142,6 +149,7 @@ static class abstract_cpu * new_i965_gpu(void) static class abstract_cpu * new_cpu(int number, char * vendor, int family, int model) { + uint64_t msr; class abstract_cpu * ret = NULL; if (strcmp(vendor, "GenuineIntel") == 0) { @@ -159,7 +167,8 @@ static class abstract_cpu * new_cpu(int number, char * vendor, int family, int m case 0x3A: /* IVB */ case 0x3C: case 0x3D: /* IVB Xeon */ - ret = new class nhm_cpu; + if (read_msr(number, MSR_APERF, &msr) >= 0) + ret = new class nhm_cpu; } } diff --git a/src/cpu/intel_cpus.cpp b/src/cpu/intel_cpus.cpp index 2b78d31..8d5f51a 100644 --- a/src/cpu/intel_cpus.cpp +++ b/src/cpu/intel_cpus.cpp @@ -49,30 +49,15 @@ static uint64_t get_msr(int cpu, uint64_t offset) { ssize_t retval; uint64_t msr; - int fd; - char msr_path[256]; - fd = sprintf(msr_path, "/dev/cpu/%d/msr", cpu); - - if (access(msr_path, R_OK) != 0){ - fd = sprintf(msr_path, "/dev/msr%d", cpu); - - if (access(msr_path, R_OK) != 0){ - fprintf(stderr, _("msr reg not found")); - exit(-2); - } - } - - fd = open(msr_path, O_RDONLY); - - retval = pread(fd, &msr, sizeof msr, offset); - if (retval != sizeof msr) { + retval = read_msr(cpu, offset, &msr); + if (retval < 0) { reset_display(); - fprintf(stderr, _("pread cpu%d 0x%llx : "), cpu, (unsigned long long)offset); + fprintf(stderr, _("read_msr cpu%d 0x%llx : "), cpu, (unsigned long long)offset); fprintf(stderr, "%s\n", strerror(errno)); exit(-2); } - close(fd); + return msr; } diff --git a/src/lib.cpp b/src/lib.cpp index 723517a..6993088 100644 --- a/src/lib.cpp +++ b/src/lib.cpp @@ -56,6 +56,7 @@ extern "C" { #include #include #include +#include static int kallsyms_read = 0; @@ -450,3 +451,36 @@ int get_user_input(char *buf, unsigned sz) /* to distinguish between getnstr error and empty line */ return ret || strlen(buf); } + +int read_msr(int cpu, uint64_t offset, uint64_t *value) +{ + ssize_t retval; + uint64_t msr; + int fd; + char msr_path[256]; + + sprintf(msr_path, "/dev/cpu/%d/msr", cpu); + + if (access(msr_path, R_OK) != 0){ + sprintf(msr_path, "/dev/msr%d", cpu); + + if (access(msr_path, R_OK) != 0){ + fprintf(stderr, + _("Model-specific registers (MSR)\ + not found (try enabling CONFIG_X86_MSR).\n")); + return -1; + } + } + + fd = open(msr_path, O_RDONLY); + if (fd < 0) + return -1; + retval = pread(fd, &msr, sizeof msr, offset); + close(fd); + if (retval != sizeof msr) { + return -1; + } + *value = msr; + + return retval; +} diff --git a/src/lib.h b/src/lib.h index de2de5a..1c9ca42 100644 --- a/src/lib.h +++ b/src/lib.h @@ -74,5 +74,6 @@ typedef void (*callback)(const char*); extern void process_directory(const char *d_name, callback fn); extern int utf_ok; extern int get_user_input(char *buf, unsigned sz); +extern int read_msr(int cpu, uint64_t offset, uint64_t *value); #endif