Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
powernow-k8-decode.c
Go to the documentation of this file.
1 /*
2  * (C) 2004 Bruno Ducrot <[email protected]>
3  *
4  * Licensed under the terms of the GNU GPL License version 2.
5  *
6  * Based on code found in
7  * linux/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
8  * and originally developed by Paul Devriendt
9  */
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <stdint.h>
14 #include <unistd.h>
15 #include <errno.h>
16 #include <fcntl.h>
17 
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 
21 #define MCPU 32
22 
23 #define MSR_FIDVID_STATUS 0xc0010042
24 
25 #define MSR_S_HI_CURRENT_VID 0x0000001f
26 #define MSR_S_LO_CURRENT_FID 0x0000003f
27 
28 static int get_fidvid(uint32_t cpu, uint32_t *fid, uint32_t *vid)
29 {
30  int err = 1;
31  uint64_t msr = 0;
32  int fd;
33  char file[20];
34 
35  if (cpu > MCPU)
36  goto out;
37 
38  sprintf(file, "/dev/cpu/%d/msr", cpu);
39 
40  fd = open(file, O_RDONLY);
41  if (fd < 0)
42  goto out;
43  lseek(fd, MSR_FIDVID_STATUS, SEEK_CUR);
44  if (read(fd, &msr, 8) != 8)
45  goto err1;
46 
47  *fid = ((uint32_t )(msr & 0xffffffffull)) & MSR_S_LO_CURRENT_FID;
48  *vid = ((uint32_t )(msr>>32 & 0xffffffffull)) & MSR_S_HI_CURRENT_VID;
49  err = 0;
50 err1:
51  close(fd);
52 out:
53  return err;
54 }
55 
56 
57 /* Return a frequency in MHz, given an input fid */
58 static uint32_t find_freq_from_fid(uint32_t fid)
59 {
60  return 800 + (fid * 100);
61 }
62 
63 /* Return a voltage in miliVolts, given an input vid */
64 static uint32_t find_millivolts_from_vid(uint32_t vid)
65 {
66  return 1550-vid*25;
67 }
68 
69 int main (int argc, char *argv[])
70 {
71  int err;
72  int cpu;
73  uint32_t fid, vid;
74 
75  if (argc < 2)
76  cpu = 0;
77  else
78  cpu = strtoul(argv[1], NULL, 0);
79 
80  err = get_fidvid(cpu, &fid, &vid);
81 
82  if (err) {
83  printf("can't get fid, vid from MSR\n");
84  printf("Possible trouble: you don't run a powernow-k8 capable cpu\n");
85  printf("or you are not root, or the msr driver is not present\n");
86  exit(1);
87  }
88 
89 
90  printf("cpu %d currently at %d MHz and %d mV\n",
91  cpu,
92  find_freq_from_fid(fid),
93  find_millivolts_from_vid(vid));
94 
95  return 0;
96 }