diff options
Diffstat (limited to 'tools/power/cpupower/utils/helpers/msr.c')
-rw-r--r-- | tools/power/cpupower/utils/helpers/msr.c | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/tools/power/cpupower/utils/helpers/msr.c b/tools/power/cpupower/utils/helpers/msr.c new file mode 100644 index 00000000000..93d48bd56e5 --- /dev/null +++ b/tools/power/cpupower/utils/helpers/msr.c | |||
@@ -0,0 +1,122 @@ | |||
1 | #if defined(__i386__) || defined(__x86_64__) | ||
2 | |||
3 | #include <fcntl.h> | ||
4 | #include <stdio.h> | ||
5 | #include <unistd.h> | ||
6 | #include <stdint.h> | ||
7 | |||
8 | #include "helpers/helpers.h" | ||
9 | |||
10 | /* Intel specific MSRs */ | ||
11 | #define MSR_IA32_PERF_STATUS 0x198 | ||
12 | #define MSR_IA32_MISC_ENABLES 0x1a0 | ||
13 | #define MSR_IA32_ENERGY_PERF_BIAS 0x1b0 | ||
14 | |||
15 | /* | ||
16 | * read_msr | ||
17 | * | ||
18 | * Will return 0 on success and -1 on failure. | ||
19 | * Possible errno values could be: | ||
20 | * EFAULT -If the read/write did not fully complete | ||
21 | * EIO -If the CPU does not support MSRs | ||
22 | * ENXIO -If the CPU does not exist | ||
23 | */ | ||
24 | |||
25 | int read_msr(int cpu, unsigned int idx, unsigned long long *val) | ||
26 | { | ||
27 | int fd; | ||
28 | char msr_file_name[64]; | ||
29 | |||
30 | sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu); | ||
31 | fd = open(msr_file_name, O_RDONLY); | ||
32 | if (fd < 0) | ||
33 | return -1; | ||
34 | if (lseek(fd, idx, SEEK_CUR) == -1) | ||
35 | goto err; | ||
36 | if (read(fd, val, sizeof *val) != sizeof *val) | ||
37 | goto err; | ||
38 | close(fd); | ||
39 | return 0; | ||
40 | err: | ||
41 | close(fd); | ||
42 | return -1; | ||
43 | } | ||
44 | |||
45 | /* | ||
46 | * write_msr | ||
47 | * | ||
48 | * Will return 0 on success and -1 on failure. | ||
49 | * Possible errno values could be: | ||
50 | * EFAULT -If the read/write did not fully complete | ||
51 | * EIO -If the CPU does not support MSRs | ||
52 | * ENXIO -If the CPU does not exist | ||
53 | */ | ||
54 | int write_msr(int cpu, unsigned int idx, unsigned long long val) | ||
55 | { | ||
56 | int fd; | ||
57 | char msr_file_name[64]; | ||
58 | |||
59 | sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu); | ||
60 | fd = open(msr_file_name, O_WRONLY); | ||
61 | if (fd < 0) | ||
62 | return -1; | ||
63 | if (lseek(fd, idx, SEEK_CUR) == -1) | ||
64 | goto err; | ||
65 | if (write(fd, &val, sizeof val) != sizeof val) | ||
66 | goto err; | ||
67 | close(fd); | ||
68 | return 0; | ||
69 | err: | ||
70 | close(fd); | ||
71 | return -1; | ||
72 | } | ||
73 | |||
74 | int msr_intel_has_boost_support(unsigned int cpu) | ||
75 | { | ||
76 | unsigned long long misc_enables; | ||
77 | int ret; | ||
78 | |||
79 | ret = read_msr(cpu, MSR_IA32_MISC_ENABLES, &misc_enables); | ||
80 | if (ret) | ||
81 | return ret; | ||
82 | return (misc_enables >> 38) & 0x1; | ||
83 | } | ||
84 | |||
85 | int msr_intel_boost_is_active(unsigned int cpu) | ||
86 | { | ||
87 | unsigned long long perf_status; | ||
88 | int ret; | ||
89 | |||
90 | ret = read_msr(cpu, MSR_IA32_PERF_STATUS, &perf_status); | ||
91 | if (ret) | ||
92 | return ret; | ||
93 | return (perf_status >> 32) & 0x1; | ||
94 | } | ||
95 | |||
96 | int msr_intel_get_perf_bias(unsigned int cpu) | ||
97 | { | ||
98 | unsigned long long val; | ||
99 | int ret; | ||
100 | |||
101 | if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_PERF_BIAS)) | ||
102 | return -1; | ||
103 | |||
104 | ret = read_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &val); | ||
105 | if (ret) | ||
106 | return ret; | ||
107 | return val; | ||
108 | } | ||
109 | |||
110 | int msr_intel_set_perf_bias(unsigned int cpu, unsigned int val) | ||
111 | { | ||
112 | int ret; | ||
113 | |||
114 | if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_PERF_BIAS)) | ||
115 | return -1; | ||
116 | |||
117 | ret = write_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, val); | ||
118 | if (ret) | ||
119 | return ret; | ||
120 | return 0; | ||
121 | } | ||
122 | #endif | ||