Skip to content

Commit 280c8d2

Browse files
author
H. Peter Anvin
committed
Check in msr-tools 1.1
0 parents  commit 280c8d2

File tree

5 files changed

+491
-0
lines changed

5 files changed

+491
-0
lines changed

MAKEDEV-cpuid-msr

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/sh
2+
msr_major=202
3+
cpuid_major=203
4+
n=0
5+
while [ $n -lt 32 ]; do
6+
mkdir -m 0755 -p /dev/cpu/$n
7+
mknod /dev/cpu/$n/msr -m 0600 c $msr_major $n
8+
mknod /dev/cpu/$n/cpuid -m 0444 c $cpuid_major $n
9+
n=`expr $n + 1`
10+
done
11+

Makefile

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#ident "$Id$"
2+
## -----------------------------------------------------------------------
3+
##
4+
## Copyright 2000 Transmeta Corporation - All Rights Reserved
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 as published by
8+
## the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
9+
## USA; either version 2 of the License, or (at your option) any later
10+
## version; incorporated herein by reference.
11+
##
12+
## -----------------------------------------------------------------------
13+
14+
#
15+
# Makefile for MSRs
16+
#
17+
18+
CC = gcc -Wall
19+
CFLAGS = -g -O2 -fomit-frame-pointer
20+
LDFLAGS =
21+
22+
BIN = wrmsr rdmsr
23+
24+
sbindir = /usr/sbin
25+
26+
all: $(BIN)
27+
28+
clean:
29+
rm -f *.o $(BIN)
30+
31+
distclean: clean
32+
rm -f *~ \#*
33+
34+
install: all
35+
install -m 755 $(BIN) $(sbindir)
36+
37+
.o:
38+
$(CC) $(LDFLAGS) -o $@ $<
39+
40+
.c.o:
41+
$(CC) $(CFLAGS) -o $@ $<
42+
43+
.c:
44+
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<

rdmsr.c

Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
#ident "$Id$"
2+
/* ----------------------------------------------------------------------- *
3+
*
4+
* Copyright 2000 Transmeta Corporation - All Rights Reserved
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 as published by
8+
* the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
9+
* USA; either version 2 of the License, or (at your option) any later
10+
* version; incorporated herein by reference.
11+
*
12+
* ----------------------------------------------------------------------- */
13+
14+
/*
15+
* rdmsr.c
16+
*
17+
* Utility to read an MSR.
18+
*/
19+
20+
#include <errno.h>
21+
#include <stdio.h>
22+
#include <fcntl.h>
23+
#include <unistd.h>
24+
#include <stdlib.h>
25+
#include <getopt.h>
26+
#include <inttypes.h>
27+
#include <sys/types.h>
28+
29+
#include "version.h"
30+
31+
struct option long_options[] = {
32+
{ "help", 0, 0, 'h' },
33+
{ "version", 0, 0, 'V' },
34+
{ "hexadecimal", 0, 0, 'x' },
35+
{ "capital-hexadecimal", 0, 0, 'X' },
36+
{ "decimal", 0, 0, 'd' },
37+
{ "signed-decimal", 0, 0, 'd' },
38+
{ "unsigned-decimal", 0, 0, 'u' },
39+
{ "octal", 0, 0, 'o' },
40+
{ "c-language", 0, 0, 'c' },
41+
{ "zero-fill", 0, 0, '0' },
42+
{ "zero-pad", 0, 0, '0' },
43+
{ "raw", 0, 0, 'r' },
44+
{ "processor", 1, 0, 'p' },
45+
{ "cpu", 1, 0, 'p' },
46+
{ "bitfield", 1, 0, 'f' },
47+
{ 0, 0, 0, 0 }
48+
};
49+
50+
/* Number of decimal digits for a certain number of bits */
51+
/* (int) ceil(log(2^n)/log(10)) */
52+
int decdigits[] = {
53+
1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5,
54+
5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10,
55+
10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15,
56+
15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19,
57+
20
58+
};
59+
60+
#define mo_hex 0x01
61+
#define mo_dec 0x02
62+
#define mo_oct 0x03
63+
#define mo_raw 0x04
64+
#define mo_uns 0x05
65+
#define mo_chx 0x06
66+
#define mo_mask 0x0f
67+
#define mo_fill 0x40
68+
#define mo_c 0x80
69+
70+
const char *program;
71+
72+
void usage(void)
73+
{
74+
fprintf(stderr,
75+
"Usage: %s [options] regno\n"
76+
" --help -h Print this help\n"
77+
" --version -V Print current version\n"
78+
" --hexadecimal -x Hexadecimal output (lower case)\n"
79+
" --captial-hex -X Hexadecimal output (upper case)\n"
80+
" --decimal -d Signed decimal output\n"
81+
" --unsigned -u Unsigned decimal output\n"
82+
" --octal -o Octal output\n"
83+
" --c-language -c Format output as a C language constant\n"
84+
" --zero-pad -0 Output leading zeroes\n"
85+
" --raw -r Raw binary output\n"
86+
" --processor # -p Select processor number (default 0)\n"
87+
" --bitfield h:l -f Output bits [h:l] only\n"
88+
, program);
89+
}
90+
91+
int main(int argc, char *argv[])
92+
{
93+
uint32_t reg;
94+
uint64_t data;
95+
int c, fd;
96+
int mode = mo_hex;
97+
int cpu = 0;
98+
unsigned int highbit = 63, lowbit = 0, bits;
99+
unsigned long arg;
100+
char *endarg;
101+
char *pat;
102+
int width;
103+
char msr_file_name[64];
104+
105+
program = argv[0];
106+
107+
while ( (c = getopt_long(argc,argv,"hVxXdoruc0p:f:",long_options,NULL)) != -1 ) {
108+
switch ( c ) {
109+
case 'h':
110+
usage();
111+
exit(0);
112+
case 'v':
113+
fprintf(stderr, "%s: version %s\n", program, VERSION_STRING);
114+
exit(0);
115+
case 'x':
116+
mode = (mode & ~mo_mask) | mo_hex;
117+
break;
118+
case 'X':
119+
mode = (mode & ~mo_mask) | mo_chx;
120+
break;
121+
case 'o':
122+
mode = (mode & ~mo_mask) | mo_oct;
123+
break;
124+
case 'd':
125+
mode = (mode & ~mo_mask) | mo_dec;
126+
break;
127+
case 'r':
128+
mode = (mode & ~mo_mask) | mo_raw;
129+
break;
130+
case 'u':
131+
mode = (mode & ~mo_mask) | mo_uns;
132+
break;
133+
case 'c':
134+
mode |= mo_c;
135+
break;
136+
case '0':
137+
mode |= mo_fill;
138+
break;
139+
case 'p':
140+
arg = strtoul(optarg, &endarg, 0);
141+
if ( *endarg || arg > 255 ) {
142+
usage();
143+
exit(127);
144+
}
145+
cpu = (int)arg;
146+
break;
147+
case 'f':
148+
{
149+
if ( sscanf(optarg, "%u:%u", &highbit, &lowbit) != 2 ||
150+
highbit > 63 || lowbit > highbit ) {
151+
usage();
152+
exit(127);
153+
}
154+
}
155+
break;
156+
default:
157+
usage();
158+
exit(127);
159+
}
160+
}
161+
162+
if ( optind != argc-1 ) {
163+
/* Should have exactly one argument */
164+
usage();
165+
exit(127);
166+
}
167+
168+
reg = strtoul(argv[optind], NULL, 0);
169+
170+
sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu);
171+
fd = open(msr_file_name, O_RDONLY);
172+
if ( fd < 0 ) {
173+
if ( errno == ENXIO ) {
174+
fprintf(stderr, "rdmsr: No CPU %d\n", cpu);
175+
exit(2);
176+
} else if ( errno == EIO ) {
177+
fprintf(stderr, "rdmsr: CPU %d doesn't support MSRs\n", cpu);
178+
exit(3);
179+
} else {
180+
perror("rdmsr:open");
181+
exit(127);
182+
}
183+
}
184+
185+
if ( lseek(fd, reg, SEEK_SET) != reg ) {
186+
perror("rdmsr:seek");
187+
exit(127);
188+
}
189+
190+
if ( read(fd, &data, sizeof data) != sizeof data ) {
191+
perror("rdmsr:read");
192+
exit(127);
193+
}
194+
195+
close(fd);
196+
197+
bits = highbit-lowbit+1;
198+
if ( bits < 64 ) {
199+
/* Show only part of register */
200+
data >>= lowbit;
201+
data &= (1ULL << bits)-1;
202+
}
203+
204+
pat = NULL;
205+
206+
width = 1; /* Default */
207+
switch(mode) {
208+
case mo_hex:
209+
pat = "%*llx\n";
210+
break;
211+
case mo_chx:
212+
pat = "%*llX\n";
213+
break;
214+
case mo_dec:
215+
case mo_dec|mo_c:
216+
case mo_dec|mo_fill|mo_c:
217+
/* Make sure we get sign correct */
218+
if ( data & (1ULL << (bits-1)) ) {
219+
data &= ~(1ULL << (bits-1));
220+
data = -data;
221+
}
222+
pat = "%*lld\n";
223+
break;
224+
case mo_uns:
225+
pat = "%*llu\n";
226+
break;
227+
case mo_oct:
228+
pat = "%*llo\n";
229+
break;
230+
case mo_hex|mo_c:
231+
pat = "0x%*llx\n";
232+
break;
233+
case mo_chx|mo_c:
234+
pat = "0x%*llX\n";
235+
break;
236+
case mo_oct|mo_c:
237+
pat = "0%*llo\n";
238+
break;
239+
case mo_uns|mo_c:
240+
case mo_uns|mo_fill|mo_c:
241+
pat = "%*lluU\n";
242+
break;
243+
case mo_hex|mo_fill:
244+
pat = "%0*llx\n";
245+
width = (bits+3)/4;
246+
break;
247+
case mo_chx|mo_fill:
248+
pat = "%0*llX\n";
249+
width = (bits+3)/4;
250+
break;
251+
case mo_dec|mo_fill:
252+
/* Make sure we get sign correct */
253+
if ( data & (1ULL << (bits-1)) ) {
254+
data &= ~(1ULL << (bits-1));
255+
data = -data;
256+
}
257+
pat = "%0*lld\n";
258+
width = decdigits[bits-1]+1;
259+
break;
260+
case mo_uns|mo_fill:
261+
pat = "%0*llu\n";
262+
width = decdigits[bits];
263+
break;
264+
case mo_oct|mo_fill:
265+
pat = "%0*llo\n";
266+
width = (bits+2)/3;
267+
break;
268+
case mo_hex|mo_fill|mo_c:
269+
pat = "0x%0*llx\n";
270+
width = (bits+3)/4;
271+
break;
272+
case mo_chx|mo_fill|mo_c:
273+
pat = "0x%0*llX\n";
274+
width = (bits+3)/4;
275+
break;
276+
case mo_oct|mo_fill|mo_c:
277+
pat = "0%0*llo\n";
278+
width = (bits+2)/3;
279+
break;
280+
case mo_raw:
281+
case mo_raw|mo_fill:
282+
fwrite(&data,sizeof data,1,stdout);
283+
break;
284+
case mo_raw|mo_c:
285+
case mo_raw|mo_fill|mo_c:
286+
{
287+
unsigned char *p = (unsigned char *)&data;
288+
int i;
289+
for ( i = 0 ; i < sizeof data ; i++ ) {
290+
printf("%s0x%02x", i?",":"{", (unsigned int)(*p++));
291+
}
292+
printf("}\n");
293+
}
294+
break;
295+
default:
296+
fprintf(stderr, "%s: Impossible case, line %d\n", program, __LINE__);
297+
exit(127);
298+
}
299+
300+
if ( width < 1 )
301+
width = 1;
302+
303+
if ( pat )
304+
printf(pat, width, data);
305+
306+
exit(0);
307+
}

version.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#ifndef MSR_TOOLS_VERSION_H
2+
#define MSR_TOOLS_VERSION_H
3+
#define VERSION_STRING "msr-tools-1.1"
4+
#endif

0 commit comments

Comments
 (0)