[PATCH 1/2] aperf: Add cpuid support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add cpuid() helpers blatantly stolen from the kernel sources and
use that for checking for aperf/mperf support instead of accessing
"/dev/cpu/%d/cpuid" which requires the module to be enabled on the
target system.

Signed-off-by: Borislav Petkov <borislav.petkov@xxxxxxx>
---
 utils/aperf.c |   25 +++++-----------------
 utils/cpuid.h |   63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 19 deletions(-)
 create mode 100644 utils/cpuid.h

diff --git a/utils/aperf.c b/utils/aperf.c
index 8ecff2c..1d58d00 100644
--- a/utils/aperf.c
+++ b/utils/aperf.c
@@ -54,6 +54,7 @@
 #include <string.h>
 
 #include "cpufreq.h"
+#include "cpuid.h"
 
 #define MSR_IA32_APERF 0x000000E8
 #define MSR_IA32_MPERF 0x000000E7
@@ -101,27 +102,13 @@ static unsigned int count_cpus(void)
 	return (ret+1);
 }
 
-static int has_mperf_aperf_support(int cpu)
+static int cpu_has_effective_freq()
 {
-	int fd;
-	char msr_file_name[64];
-	uint32_t words[4];
-	int support;
+	/* largest base level */
+	if (cpuid_eax(0) < 6)
+		return 0;
 
-	sprintf(msr_file_name, "/dev/cpu/%d/cpuid", cpu);
-	fd = open(msr_file_name, O_RDONLY);
-	if (fd < 0)
-		return -1;
-	if (lseek(fd, 6, SEEK_CUR) == -1)
-		goto err;
-	if (read(fd, words, 16) != 16)
-		goto err;
-	support = words[2] & 0x1;
-	close(fd);
-	return support;
- err:
-	close(fd);
-	return -1;
+	return cpuid_ecx(6) & 0x1;
 }
 
 /*
diff --git a/utils/cpuid.h b/utils/cpuid.h
new file mode 100644
index 0000000..2bac69a
--- /dev/null
+++ b/utils/cpuid.h
@@ -0,0 +1,63 @@
+#ifndef _CPUFREQ_CPUID_H
+#define _CPUFREQ_CPUID_H
+
+static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
+				unsigned int *ecx, unsigned int *edx)
+{
+	/* ecx is often an input as well as an output. */
+	asm volatile("cpuid"
+	    : "=a" (*eax),
+	      "=b" (*ebx),
+	      "=c" (*ecx),
+	      "=d" (*edx)
+	    : "0" (*eax), "2" (*ecx));
+}
+static inline void cpuid(unsigned int op,
+			 unsigned int *eax, unsigned int *ebx,
+			 unsigned int *ecx, unsigned int *edx)
+{
+	*eax = op;
+	*ecx = 0;
+	__cpuid(eax, ebx, ecx, edx);
+}
+
+/*
+ * CPUID functions returning a single datum
+ */
+static inline unsigned int cpuid_eax(unsigned int op)
+{
+	unsigned int eax, ebx, ecx, edx;
+
+	cpuid(op, &eax, &ebx, &ecx, &edx);
+
+	return eax;
+}
+
+static inline unsigned int cpuid_ebx(unsigned int op)
+{
+	unsigned int eax, ebx, ecx, edx;
+
+	cpuid(op, &eax, &ebx, &ecx, &edx);
+
+	return ebx;
+}
+
+static inline unsigned int cpuid_ecx(unsigned int op)
+{
+	unsigned int eax, ebx, ecx, edx;
+
+	cpuid(op, &eax, &ebx, &ecx, &edx);
+
+	return ecx;
+}
+
+static inline unsigned int cpuid_edx(unsigned int op)
+{
+	unsigned int eax, ebx, ecx, edx;
+
+	cpuid(op, &eax, &ebx, &ecx, &edx);
+
+	return edx;
+}
+
+#endif /* _CPUFREQ_CPUID_H */
-- 
1.7.0

-- 
Regards/Gruss,
Boris.

--
Advanced Micro Devices, Inc.
Operating Systems Research Center
--
To unsubscribe from this list: send the line "unsubscribe cpufreq" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Devel]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Forum]     [Linux SCSI]

  Powered by Linux