// SPDX-License-Identifier: GPL-2.0-only /* * (C) 2003 - 2004 Dominik Brodowski <linux@dominikbrodowski.de> * * Based on code found in * linux/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c * and originally developed by Jeremy Fitzhardinge. * * USAGE: simply run it to decode the current settings on CPU 0, * or pass the CPU number as argument, or pass the MSR content * as argument. */ #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <unistd.h> #include <errno.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #define MCPU 32 #define MSR_IA32_PERF_STATUS 0x198 static int rdmsr(unsigned int cpu, unsigned int msr, unsigned int *lo, unsigned int *hi) { int fd; char file[20]; unsigned long long val; int retval = -1; *lo = *hi = 0; if (cpu > MCPU) goto err1; sprintf(file, "/dev/cpu/%d/msr", cpu); fd = open(file, O_RDONLY); if (fd < 0) goto err1; if (lseek(fd, msr, SEEK_CUR) == -1) goto err2; if (read(fd, &val, 8) != 8) goto err2; *lo = (uint32_t )(val & 0xffffffffull); *hi = (uint32_t )(val>>32 & 0xffffffffull); retval = 0; err2: close(fd); err1: return retval; } static void decode (unsigned int msr) { unsigned int multiplier; unsigned int mv; multiplier = ((msr >> 8) & 0xFF); mv = (((msr & 0xFF) * 16) + 700); printf("0x%x means multiplier %d @ %d mV\n", msr, multiplier, mv); } static int decode_live(unsigned int cpu) { unsigned int lo, hi; int err; err = rdmsr(cpu, MSR_IA32_PERF_STATUS, &lo, &hi); if (err) { printf("can't get MSR_IA32_PERF_STATUS for cpu %d\n", cpu); printf("Possible trouble: you don't run an Enhanced SpeedStep capable cpu\n"); printf("or you are not root, or the msr driver is not present\n"); return 1; } decode(lo); return 0; } int main (int argc, char **argv) { unsigned int cpu, mode = 0; if (argc < 2) cpu = 0; else { cpu = strtoul(argv[1], NULL, 0); if (cpu >= MCPU) mode = 1; } if (mode) decode(cpu); else decode_live(cpu); return 0; }