blob: 0e1a0da7bae8dffb3ffa4af9db452f7aa47259b4 [file] [log] [blame]
Peter Stugedad1e302008-11-22 17:13:36 +00001/*
2 * This file is part of msrtool.
3 *
4 * Copyright (c) 2008 Peter Stuge <peter@stuge.se>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
Paul Menzela46a7122013-02-23 18:37:27 +010017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Peter Stugedad1e302008-11-22 17:13:36 +000018 */
19
20#include <sys/types.h>
21#include <sys/stat.h>
22#include <fcntl.h>
23#include <unistd.h>
24#include <string.h>
25#include <errno.h>
26
27#include "msrtool.h"
28
29static int msr_fd[MAX_CORES] = {-1, -1, -1, -1, -1, -1, -1, -1};
30
31int linux_probe(const struct sysdef *system) {
32 struct stat st;
33 return 0 == stat("/dev/cpu/0/msr", &st);
34}
35
36int linux_open(uint8_t cpu, enum SysModes mode) {
37 int fmode;
38 char fn[32];
39 switch (mode) {
40 case SYS_RDWR:
41 fmode = O_RDWR;
42 break;
43 case SYS_WRONLY:
44 fmode = O_WRONLY;
45 break;
46 case SYS_RDONLY:
47 default:
48 fmode = O_RDONLY;
49 break;
50 }
51 if (cpu >= MAX_CORES) {
52 fprintf(stderr, "%s: only cores 0-%d are supported. requested=%d\n", __func__, MAX_CORES, cpu);
53 return 0;
54 }
55 if (snprintf(fn, sizeof(fn), "/dev/cpu/%d/msr", cpu) == -1) {
56 fprintf(stderr, "%s: snprintf: %s\n", __func__, strerror(errno));
57 return 0;
58 }
59 msr_fd[cpu] = open(fn, fmode);
60 if (-1 == msr_fd[cpu]) {
61 fprintf(stderr, "open(%s): %s\n", fn, strerror(errno));
62 return 0;
63 }
64 return 1;
65}
66
67int linux_close(uint8_t cpu) {
68 int ret;
69 if (cpu >= MAX_CORES) {
70 fprintf(stderr, "%s: only cores 0-%d are supported. requested=%d\n", __func__, MAX_CORES, cpu);
71 return 0;
72 }
73 ret = close(msr_fd[cpu]);
74 msr_fd[cpu] = 0;
75 return 0 == ret;
76}
77
78int linux_rdmsr(uint8_t cpu, uint32_t addr, struct msr *val) {
Peter Stugec1d6ed92009-01-26 17:03:05 +000079 struct msr tmp;
Peter Stugedad1e302008-11-22 17:13:36 +000080 if (lseek(msr_fd[cpu], addr, SEEK_SET) == -1) {
81 SYSERROR(lseek, addr);
82 return 0;
83 }
Peter Stugec1d6ed92009-01-26 17:03:05 +000084 if (read(msr_fd[cpu], &tmp, 8) != 8) {
Peter Stugedad1e302008-11-22 17:13:36 +000085 SYSERROR(read, addr);
86 return 0;
87 }
Peter Stugec1d6ed92009-01-26 17:03:05 +000088 val->hi = tmp.lo;
89 val->lo = tmp.hi;
Peter Stugedad1e302008-11-22 17:13:36 +000090 return 1;
91}