blob: 64b4af212fb82d03f3826c4c452be468e8c6002b [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.
Peter Stugedad1e302008-11-22 17:13:36 +000014 */
15
16#include <sys/types.h>
17#include <sys/stat.h>
18#include <fcntl.h>
19#include <unistd.h>
20#include <string.h>
21#include <errno.h>
22
23#include "msrtool.h"
24
25static int msr_fd[MAX_CORES] = {-1, -1, -1, -1, -1, -1, -1, -1};
26
27int linux_probe(const struct sysdef *system) {
28 struct stat st;
29 return 0 == stat("/dev/cpu/0/msr", &st);
30}
31
32int linux_open(uint8_t cpu, enum SysModes mode) {
33 int fmode;
34 char fn[32];
35 switch (mode) {
36 case SYS_RDWR:
37 fmode = O_RDWR;
38 break;
39 case SYS_WRONLY:
40 fmode = O_WRONLY;
41 break;
42 case SYS_RDONLY:
43 default:
44 fmode = O_RDONLY;
45 break;
46 }
47 if (cpu >= MAX_CORES) {
48 fprintf(stderr, "%s: only cores 0-%d are supported. requested=%d\n", __func__, MAX_CORES, cpu);
49 return 0;
50 }
51 if (snprintf(fn, sizeof(fn), "/dev/cpu/%d/msr", cpu) == -1) {
52 fprintf(stderr, "%s: snprintf: %s\n", __func__, strerror(errno));
53 return 0;
54 }
55 msr_fd[cpu] = open(fn, fmode);
56 if (-1 == msr_fd[cpu]) {
57 fprintf(stderr, "open(%s): %s\n", fn, strerror(errno));
58 return 0;
59 }
60 return 1;
61}
62
63int linux_close(uint8_t cpu) {
64 int ret;
65 if (cpu >= MAX_CORES) {
66 fprintf(stderr, "%s: only cores 0-%d are supported. requested=%d\n", __func__, MAX_CORES, cpu);
67 return 0;
68 }
69 ret = close(msr_fd[cpu]);
70 msr_fd[cpu] = 0;
71 return 0 == ret;
72}
73
74int linux_rdmsr(uint8_t cpu, uint32_t addr, struct msr *val) {
Peter Stugec1d6ed92009-01-26 17:03:05 +000075 struct msr tmp;
Peter Stugedad1e302008-11-22 17:13:36 +000076 if (lseek(msr_fd[cpu], addr, SEEK_SET) == -1) {
77 SYSERROR(lseek, addr);
78 return 0;
79 }
Peter Stugec1d6ed92009-01-26 17:03:05 +000080 if (read(msr_fd[cpu], &tmp, 8) != 8) {
Peter Stugedad1e302008-11-22 17:13:36 +000081 SYSERROR(read, addr);
82 return 0;
83 }
Peter Stugec1d6ed92009-01-26 17:03:05 +000084 val->hi = tmp.lo;
85 val->lo = tmp.hi;
Peter Stugedad1e302008-11-22 17:13:36 +000086 return 1;
87}