Add constants for fast path resume copying
[coreboot.git] / util / msrtool / msrtool.c
index 41e7e2c2ce2485a7580d99cb06c938caaa5cf303..21f9c9d8fd305ae10ea16739672fa7fb1d8484f4 100644 (file)
@@ -44,12 +44,19 @@ static struct targetdef alltargets[] = {
        { "geodelx", "AMD Geode(tm) LX", geodelx_probe, geodelx_msrs },
        { "cs5536", "AMD Geode(tm) CS5536", cs5536_probe, cs5536_msrs },
        { "K8", "AMD K8 Family", k8_probe, k8_msrs },
+       { "intel_pentium3_early", "Intel Pentium III family", intel_pentium3_early_probe, intel_pentium3_early_msrs },
+       { "intel_pentium3", "Intel Pentium III Xeon Processor, Intel Pentium III Processor", intel_pentium3_probe, intel_pentium3_msrs },
+       { "intel_core1", "Intel Core Duo, Intel Core Solo processors", intel_core1_probe, intel_core1_msrs },
+       { "intel_core2_early", "Intel Xeon Processor 3000, 3200, 5100, 5300, 7300 series, Intel Core 2 Quad processor 6000 series, Intel Core 2 Extreme 6000    series, Intel Core 2 Duo 4000, 5000, 6000, 7000 series processors, Intel Pentium dual-core processors", intel_core2_early_probe, intel_core2_early_msrs },
+       { "intel_core2_later", "Intel Xeon Processor 5200, 5400 series, Intel Core 2 Quad       processors 8000, 9000 series", intel_core2_later_probe, intel_core2_later_msrs },
+       { "intel_pentium4_early", "Intel Xeon Processor, Intel Xeon Processor MP, Intel Pentium 4 processors", intel_pentium4_early_probe, intel_pentium4_early_msrs },
+       { "intel_pentium4_later", "Intel Xeon Processor, Intel Xeon Processor MP, Intel Pentium 4, Pentium D processors", intel_pentium4_later_probe, intel_pentium4_later_msrs },
        { TARGET_EOT }
 };
 
 static struct sysdef allsystems[] = {
        { "linux", "Linux with /dev/cpu/*/msr", linux_probe, linux_open, linux_close, linux_rdmsr },
-       { "darwin", "OS X with DirectIO", darwin_probe, darwin_open, darwin_close, darwin_rdmsr },
+       { "darwin", "Mac OS X with DirectHW", darwin_probe, darwin_open, darwin_close, darwin_rdmsr },
        { "freebsd", "FreeBSD with /dev/cpuctl*", freebsd_probe, freebsd_open, freebsd_close, freebsd_rdmsr },
        { SYSTEM_EOT }
 };
@@ -93,6 +100,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 +149,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 +199,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 +218,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 +225,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 +251,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);
@@ -323,7 +353,7 @@ int main(int argc, char *argv[]) {
        if (targets)
                for (tn = 0; tn < targets_found; tn++)
                        printf_quiet("Forced target %s: %s\n", targets[tn]->name, targets[tn]->prettyname);
-       else 
+       else
                for (t = alltargets; !TARGET_ISEOT(*t); t++) {
                        printf_verbose("Probing for target %s: %s\n", t->name, t->prettyname);
                        if (!t->probe(t))
@@ -351,13 +381,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 +393,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 +408,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 +419,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))