xref: /linux/tools/power/cpupower/utils/helpers/msr.c (revision cdd38c5f1ce4398ec58fec95904b75824daab7b5)
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