1*7fe2f639SDominik Brodowski /* 2*7fe2f639SDominik Brodowski * (C) 2003 - 2004 Dominik Brodowski <linux@dominikbrodowski.de> 3*7fe2f639SDominik Brodowski * 4*7fe2f639SDominik Brodowski * Licensed under the terms of the GNU GPL License version 2. 5*7fe2f639SDominik Brodowski * 6*7fe2f639SDominik Brodowski * Based on code found in 7*7fe2f639SDominik Brodowski * linux/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 8*7fe2f639SDominik Brodowski * and originally developed by Jeremy Fitzhardinge. 9*7fe2f639SDominik Brodowski * 10*7fe2f639SDominik Brodowski * USAGE: simply run it to decode the current settings on CPU 0, 11*7fe2f639SDominik Brodowski * or pass the CPU number as argument, or pass the MSR content 12*7fe2f639SDominik Brodowski * as argument. 13*7fe2f639SDominik Brodowski */ 14*7fe2f639SDominik Brodowski 15*7fe2f639SDominik Brodowski #include <stdio.h> 16*7fe2f639SDominik Brodowski #include <stdlib.h> 17*7fe2f639SDominik Brodowski #include <stdint.h> 18*7fe2f639SDominik Brodowski #include <unistd.h> 19*7fe2f639SDominik Brodowski #include <errno.h> 20*7fe2f639SDominik Brodowski #include <fcntl.h> 21*7fe2f639SDominik Brodowski 22*7fe2f639SDominik Brodowski #include <sys/types.h> 23*7fe2f639SDominik Brodowski #include <sys/stat.h> 24*7fe2f639SDominik Brodowski 25*7fe2f639SDominik Brodowski #define MCPU 32 26*7fe2f639SDominik Brodowski 27*7fe2f639SDominik Brodowski #define MSR_IA32_PERF_STATUS 0x198 28*7fe2f639SDominik Brodowski 29*7fe2f639SDominik Brodowski static int rdmsr(unsigned int cpu, unsigned int msr, 30*7fe2f639SDominik Brodowski unsigned int *lo, unsigned int *hi) 31*7fe2f639SDominik Brodowski { 32*7fe2f639SDominik Brodowski int fd; 33*7fe2f639SDominik Brodowski char file[20]; 34*7fe2f639SDominik Brodowski unsigned long long val; 35*7fe2f639SDominik Brodowski int retval = -1; 36*7fe2f639SDominik Brodowski 37*7fe2f639SDominik Brodowski *lo = *hi = 0; 38*7fe2f639SDominik Brodowski 39*7fe2f639SDominik Brodowski if (cpu > MCPU) 40*7fe2f639SDominik Brodowski goto err1; 41*7fe2f639SDominik Brodowski 42*7fe2f639SDominik Brodowski sprintf(file, "/dev/cpu/%d/msr", cpu); 43*7fe2f639SDominik Brodowski fd = open(file, O_RDONLY); 44*7fe2f639SDominik Brodowski 45*7fe2f639SDominik Brodowski if (fd < 0) 46*7fe2f639SDominik Brodowski goto err1; 47*7fe2f639SDominik Brodowski 48*7fe2f639SDominik Brodowski if (lseek(fd, msr, SEEK_CUR) == -1) 49*7fe2f639SDominik Brodowski goto err2; 50*7fe2f639SDominik Brodowski 51*7fe2f639SDominik Brodowski if (read(fd, &val, 8) != 8) 52*7fe2f639SDominik Brodowski goto err2; 53*7fe2f639SDominik Brodowski 54*7fe2f639SDominik Brodowski *lo = (uint32_t )(val & 0xffffffffull); 55*7fe2f639SDominik Brodowski *hi = (uint32_t )(val>>32 & 0xffffffffull); 56*7fe2f639SDominik Brodowski 57*7fe2f639SDominik Brodowski retval = 0; 58*7fe2f639SDominik Brodowski err2: 59*7fe2f639SDominik Brodowski close(fd); 60*7fe2f639SDominik Brodowski err1: 61*7fe2f639SDominik Brodowski return retval; 62*7fe2f639SDominik Brodowski } 63*7fe2f639SDominik Brodowski 64*7fe2f639SDominik Brodowski static void decode (unsigned int msr) 65*7fe2f639SDominik Brodowski { 66*7fe2f639SDominik Brodowski unsigned int multiplier; 67*7fe2f639SDominik Brodowski unsigned int mv; 68*7fe2f639SDominik Brodowski 69*7fe2f639SDominik Brodowski multiplier = ((msr >> 8) & 0xFF); 70*7fe2f639SDominik Brodowski 71*7fe2f639SDominik Brodowski mv = (((msr & 0xFF) * 16) + 700); 72*7fe2f639SDominik Brodowski 73*7fe2f639SDominik Brodowski printf("0x%x means multiplier %d @ %d mV\n", msr, multiplier, mv); 74*7fe2f639SDominik Brodowski } 75*7fe2f639SDominik Brodowski 76*7fe2f639SDominik Brodowski static int decode_live(unsigned int cpu) 77*7fe2f639SDominik Brodowski { 78*7fe2f639SDominik Brodowski unsigned int lo, hi; 79*7fe2f639SDominik Brodowski int err; 80*7fe2f639SDominik Brodowski 81*7fe2f639SDominik Brodowski err = rdmsr(cpu, MSR_IA32_PERF_STATUS, &lo, &hi); 82*7fe2f639SDominik Brodowski 83*7fe2f639SDominik Brodowski if (err) { 84*7fe2f639SDominik Brodowski printf("can't get MSR_IA32_PERF_STATUS for cpu %d\n", cpu); 85*7fe2f639SDominik Brodowski printf("Possible trouble: you don't run an Enhanced SpeedStep capable cpu\n"); 86*7fe2f639SDominik Brodowski printf("or you are not root, or the msr driver is not present\n"); 87*7fe2f639SDominik Brodowski return 1; 88*7fe2f639SDominik Brodowski } 89*7fe2f639SDominik Brodowski 90*7fe2f639SDominik Brodowski decode(lo); 91*7fe2f639SDominik Brodowski 92*7fe2f639SDominik Brodowski return 0; 93*7fe2f639SDominik Brodowski } 94*7fe2f639SDominik Brodowski 95*7fe2f639SDominik Brodowski int main (int argc, char **argv) 96*7fe2f639SDominik Brodowski { 97*7fe2f639SDominik Brodowski unsigned int cpu, mode = 0; 98*7fe2f639SDominik Brodowski 99*7fe2f639SDominik Brodowski if (argc < 2) 100*7fe2f639SDominik Brodowski cpu = 0; 101*7fe2f639SDominik Brodowski else { 102*7fe2f639SDominik Brodowski cpu = strtoul(argv[1], NULL, 0); 103*7fe2f639SDominik Brodowski if (cpu >= MCPU) 104*7fe2f639SDominik Brodowski mode = 1; 105*7fe2f639SDominik Brodowski } 106*7fe2f639SDominik Brodowski 107*7fe2f639SDominik Brodowski if (mode) 108*7fe2f639SDominik Brodowski decode(cpu); 109*7fe2f639SDominik Brodowski else 110*7fe2f639SDominik Brodowski decode_live(cpu); 111*7fe2f639SDominik Brodowski 112*7fe2f639SDominik Brodowski return 0; 113*7fe2f639SDominik Brodowski } 114