summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util/msrtool/msrtool.c59
1 files changed, 37 insertions, 22 deletions
diff --git a/util/msrtool/msrtool.c b/util/msrtool/msrtool.c
index 41e7e2c2ce..47b4938739 100644
--- a/util/msrtool/msrtool.c
+++ b/util/msrtool/msrtool.c
@@ -93,6 +93,16 @@ static void *add_target(const struct targetdef *t) {
return targets;
}
+static int found_system() {
+ if (!sys || (sys && !sys->name)) {
+ fprintf(stderr, "Unable to detect the current operating system!\n");
+ fprintf(stderr, "On Linux, please run 'modprobe msr' and try again.\n");
+ fprintf(stderr, "Please send a report or patch to coreboot@coreboot.org. Thanks for your help!\n");
+ fprintf(stderr, "\n");
+ }
+ return (sys && sys->name);
+}
+
int do_stream(const char *streamfn, uint8_t ignoreinput) {
char tmpfn[20], line[256];
uint8_t tn;
@@ -132,6 +142,8 @@ int do_stream(const char *streamfn, uint8_t ignoreinput) {
}
}
+ if (!found_system())
+ goto done;
if (!sys->open(cpu, SYS_RDONLY))
goto done;
if (ignoreinput) {
@@ -180,9 +192,9 @@ done:
}
int do_diff(const char *difffn) {
- char tmpfn[20], line[512], *m1start;
+ char tmpfn[20], line[512], *m1start, *m2start;
size_t len;
- int ret = 1, tmp, m1pos;
+ int ret = 1, tmp, m1pos, sys_opened = 0;
FILE *fin = NULL, *fout = stdout;
uint8_t rev = 0;
uint32_t addr, linenum;
@@ -199,8 +211,6 @@ int do_diff(const char *difffn) {
return 1;
}
- if (!sys->open(cpu, SYS_RDONLY))
- goto done;
for (linenum = 1; NULL != fgets(line, sizeof(line), fin); ++linenum) {
tmp = strncmp("0x", line, 2) ? 0 : 2;
if (sscanf(line + tmp, "%8x %n%*x", &addr, &m1pos) < 1)
@@ -208,12 +218,24 @@ int do_diff(const char *difffn) {
m1start = line + tmp + m1pos;
for (len = strlen(m1start) - 1; NULL != strchr("\r\n", m1start[len]); --len)
m1start[len] = 0;
- if (!str2msr(m1start, &m1, NULL)) {
- fprintf(stderr, "%s:%d: invalid MSR value '%s'\n", difffn, linenum, m1start);
+ if (!str2msr(m1start, &m1, &m2start)) {
+ fprintf(stderr, "%s:%d: invalid MSR1 value '%s'\n", difffn, linenum, m1start);
continue;
}
- if (!sys->rdmsr(cpu, addr, &m2))
- goto done;
+ while (' ' == *m2start)
+ ++m2start;
+ if (!str2msr(m2start, &m2, NULL)) {
+ fprintf(stderr, "%s:%d: invalid MSR2 value '%s' - reading from hardware!\n", difffn, linenum, m2start);
+ if (!sys_opened) {
+ if (!found_system())
+ goto done;
+ sys_opened = sys->open(cpu, SYS_RDONLY);
+ if (!sys_opened)
+ goto done;
+ }
+ if (!sys->rdmsr(cpu, addr, &m2))
+ goto done;
+ }
if (diff_msr(fout, addr, rev ? m2 : m1, rev ? m1 : m2))
fprintf(fout, "\n");
}
@@ -222,7 +244,8 @@ int do_diff(const char *difffn) {
else
ret = 0;
done:
- sys->close(cpu);
+ if (sys_opened)
+ sys->close(cpu);
if (strcmp(difffn, "-")) {
if (ret)
unlink(tmpfn);
@@ -351,13 +374,6 @@ int main(int argc, char *argv[]) {
return 0;
}
- if (sys && !sys->name) {
- fprintf(stderr, "Unable to detect the current operating system!\n");
- fprintf(stderr, "On Linux, please do 'modprobe msr' and retry.\n");
- fprintf(stderr, "Please send a report or patch to coreboot@coreboot.org. Thanks for your help!\n");
- fprintf(stderr, "\n");
- }
-
if (!targets_found || !targets) {
fprintf(stderr, "Unable to detect a known target; can not decode any MSRs! (Use -t to force)\n");
fprintf(stderr, "Please send a report or patch to coreboot@coreboot.org. Thanks for your help!\n");
@@ -370,9 +386,6 @@ int main(int argc, char *argv[]) {
return 0;
}
- if (sys && !sys->name)
- return 1;
-
if (listmsrs) {
if (streamfn)
return do_stream(streamfn, 1);
@@ -388,9 +401,6 @@ int main(int argc, char *argv[]) {
if (streamfn)
return do_stream(streamfn, 0);
- if (!sys->open(cpu, SYS_RDONLY))
- return 1;
-
if (difffn) {
ret = do_diff(difffn);
goto done;
@@ -402,6 +412,11 @@ int main(int argc, char *argv[]) {
goto done;
}
+ if (!found_system())
+ return 1;
+ if (!sys->open(cpu, SYS_RDONLY))
+ return 1;
+
for (; optind < argc; optind++) {
addr = msraddrbyname(argv[optind]);
if (!sys->rdmsr(cpu, addr, &msrval))