1*b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
27fe2f639SDominik Brodowski #if defined(__i386__) || defined(__x86_64__)
37fe2f639SDominik Brodowski
47fe2f639SDominik Brodowski #include <fcntl.h>
57fe2f639SDominik Brodowski #include <stdio.h>
67fe2f639SDominik Brodowski #include <unistd.h>
77fe2f639SDominik Brodowski #include <stdint.h>
87fe2f639SDominik Brodowski
97fe2f639SDominik Brodowski #include "helpers/helpers.h"
107fe2f639SDominik Brodowski
117fe2f639SDominik Brodowski /* Intel specific MSRs */
127fe2f639SDominik Brodowski #define MSR_IA32_PERF_STATUS 0x198
137fe2f639SDominik Brodowski #define MSR_IA32_MISC_ENABLES 0x1a0
148fb2e440SThomas Renninger #define MSR_NEHALEM_TURBO_RATIO_LIMIT 0x1ad
157fe2f639SDominik Brodowski
167fe2f639SDominik Brodowski /*
177fe2f639SDominik Brodowski * read_msr
187fe2f639SDominik Brodowski *
197fe2f639SDominik Brodowski * Will return 0 on success and -1 on failure.
207fe2f639SDominik Brodowski * Possible errno values could be:
217fe2f639SDominik Brodowski * EFAULT -If the read/write did not fully complete
227fe2f639SDominik Brodowski * EIO -If the CPU does not support MSRs
237fe2f639SDominik Brodowski * ENXIO -If the CPU does not exist
247fe2f639SDominik Brodowski */
257fe2f639SDominik Brodowski
read_msr(int cpu,unsigned int idx,unsigned long long * val)267fe2f639SDominik Brodowski int read_msr(int cpu, unsigned int idx, unsigned long long *val)
277fe2f639SDominik Brodowski {
287fe2f639SDominik Brodowski int fd;
297fe2f639SDominik Brodowski char msr_file_name[64];
307fe2f639SDominik Brodowski
317fe2f639SDominik Brodowski sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu);
327fe2f639SDominik Brodowski fd = open(msr_file_name, O_RDONLY);
337fe2f639SDominik Brodowski if (fd < 0)
347fe2f639SDominik Brodowski return -1;
357fe2f639SDominik Brodowski if (lseek(fd, idx, SEEK_CUR) == -1)
367fe2f639SDominik Brodowski goto err;
377fe2f639SDominik Brodowski if (read(fd, val, sizeof *val) != sizeof *val)
387fe2f639SDominik Brodowski goto err;
397fe2f639SDominik Brodowski close(fd);
407fe2f639SDominik Brodowski return 0;
417fe2f639SDominik Brodowski err:
427fe2f639SDominik Brodowski close(fd);
437fe2f639SDominik Brodowski return -1;
447fe2f639SDominik Brodowski }
457fe2f639SDominik Brodowski
467fe2f639SDominik Brodowski /*
477fe2f639SDominik Brodowski * write_msr
487fe2f639SDominik Brodowski *
497fe2f639SDominik Brodowski * Will return 0 on success and -1 on failure.
507fe2f639SDominik Brodowski * Possible errno values could be:
517fe2f639SDominik Brodowski * EFAULT -If the read/write did not fully complete
527fe2f639SDominik Brodowski * EIO -If the CPU does not support MSRs
537fe2f639SDominik Brodowski * ENXIO -If the CPU does not exist
547fe2f639SDominik Brodowski */
write_msr(int cpu,unsigned int idx,unsigned long long val)557fe2f639SDominik Brodowski int write_msr(int cpu, unsigned int idx, unsigned long long val)
567fe2f639SDominik Brodowski {
577fe2f639SDominik Brodowski int fd;
587fe2f639SDominik Brodowski char msr_file_name[64];
597fe2f639SDominik Brodowski
607fe2f639SDominik Brodowski sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu);
617fe2f639SDominik Brodowski fd = open(msr_file_name, O_WRONLY);
627fe2f639SDominik Brodowski if (fd < 0)
637fe2f639SDominik Brodowski return -1;
647fe2f639SDominik Brodowski if (lseek(fd, idx, SEEK_CUR) == -1)
657fe2f639SDominik Brodowski goto err;
667fe2f639SDominik Brodowski if (write(fd, &val, sizeof val) != sizeof val)
677fe2f639SDominik Brodowski goto err;
687fe2f639SDominik Brodowski close(fd);
697fe2f639SDominik Brodowski return 0;
707fe2f639SDominik Brodowski err:
717fe2f639SDominik Brodowski close(fd);
727fe2f639SDominik Brodowski return -1;
737fe2f639SDominik Brodowski }
747fe2f639SDominik Brodowski
msr_intel_get_turbo_ratio(unsigned int cpu)758fb2e440SThomas Renninger unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu)
768fb2e440SThomas Renninger {
778fb2e440SThomas Renninger unsigned long long val;
788fb2e440SThomas Renninger int ret;
798fb2e440SThomas Renninger
808fb2e440SThomas Renninger if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_HAS_TURBO_RATIO))
818fb2e440SThomas Renninger return -1;
828fb2e440SThomas Renninger
838fb2e440SThomas Renninger ret = read_msr(cpu, MSR_NEHALEM_TURBO_RATIO_LIMIT, &val);
848fb2e440SThomas Renninger if (ret)
858fb2e440SThomas Renninger return ret;
868fb2e440SThomas Renninger return val;
878fb2e440SThomas Renninger }
887fe2f639SDominik Brodowski #endif
89