msrtool: added support for Intel CPUs
[coreboot.git] / util / msrtool / msrtool.c
index 6f0b3a01095959739a37208fb4cc0f88efb3eb99..21f9c9d8fd305ae10ea16739672fa7fb1d8484f4 100644 (file)
@@ -25,6 +25,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <errno.h>
+#include <pci/pci.h>
 
 #include "msrtool.h"
 
@@ -36,14 +37,27 @@ const struct targetdef **targets = NULL;
 const struct sysdef *sys = NULL;
 uint8_t reserved = 0, verbose = 0, quiet = 0;
 
+struct pci_access *pacc = NULL;
+
 static struct targetdef alltargets[] = {
+       { "geodegx2", "AMD Geode(tm) GX2", geodegx2_probe, geodegx2_msrs },
        { "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", "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 }
 };
 
@@ -86,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;
@@ -125,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) {
@@ -173,13 +199,13 @@ done:
 }
 
 int do_diff(const char *difffn) {
-       char tmpfn[20], line[512];
-       size_t start, len;
-       int ret = 1, tmp;
+       char tmpfn[20], line[512], *m1start, *m2start;
+       size_t len;
+       int ret = 1, tmp, m1pos, sys_opened = 0;
        FILE *fin = NULL, *fout = stdout;
        uint8_t rev = 0;
        uint32_t addr, linenum;
-       struct msr mf = MSR1(0), mhw = MSR1(0);
+       struct msr m1 = MSR1(0), m2 = MSR1(0);
 
        if (':' == difffn[0]) {
                rev = 1;
@@ -192,30 +218,41 @@ 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) {
-               start = (0 == strncmp("0x", line, 2)) ? 2 : 0;
-               if (sscanf(line + start, "%8x %n%*x", &addr, &tmp) >= 1) {
-                       start += tmp;
-                       for (len = strlen(line) - 1; NULL != strchr("\r\n", line[len]); --len)
-                               line[len] = 0;
-                       if (!str2msr(line + start, &mf)) {
-                               fprintf(stderr, "%s:%d: invalid MSR value '%s'\n", difffn, linenum, line + start);
-                               continue;
+               tmp = strncmp("0x", line, 2) ? 0 : 2;
+               if (sscanf(line + tmp, "%8x %n%*x", &addr, &m1pos) < 1)
+                       continue;
+               m1start = line + tmp + m1pos;
+               for (len = strlen(m1start) - 1; NULL != strchr("\r\n", m1start[len]); --len)
+                       m1start[len] = 0;
+               if (!str2msr(m1start, &m1, &m2start)) {
+                       fprintf(stderr, "%s:%d: invalid MSR1 value '%s'\n", difffn, linenum, m1start);
+                       continue;
+               }
+               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, &mhw))
+                       if (!sys->rdmsr(cpu, addr, &m2))
                                goto done;
-                       if (diff_msr(fout, addr, rev ? mhw : mf, rev ? mf : mhw))
-                               fprintf(fout, "\n");
                }
+               if (diff_msr(fout, addr, rev ? m2 : m1, rev ? m1 : m2))
+                       fprintf(fout, "\n");
        }
        if (!feof(fin))
                fprintf(stderr, "%s:%d: fgets: %s\n", difffn, linenum, strerror(errno));
        else
                ret = 0;
 done:
-       sys->close(cpu);
+       if (sys_opened)
+               sys->close(cpu);
        if (strcmp(difffn, "-")) {
                if (ret)
                        unlink(tmpfn);
@@ -275,13 +312,13 @@ int main(int argc, char *argv[]) {
                        break;
                case 'i':
                        input = 1;
-                       addr = strtoul(optarg, NULL, 16);
+                       addr = msraddrbyname(optarg);
                        optarg = strchr(optarg, '=');
                        if (NULL == optarg) {
                                fprintf(stderr, "missing value in -i argument!\n");
                                break;
                        }
-                       if (!str2msr(++optarg, &msrval))
+                       if (!str2msr(++optarg, &msrval, NULL))
                                fprintf(stderr, "invalid value in -i argument!\n");
                        break;
                case 's':
@@ -296,6 +333,14 @@ int main(int argc, char *argv[]) {
 
        printf_quiet("msrtool %s\n", VERSION);
 
+       pacc = pci_alloc();
+       if (NULL == pacc) {
+               fprintf(stderr, "Could not initialize PCI library! pci_alloc() failed.\n");
+               return 1;
+       }
+       pci_init(pacc);
+       pci_scan_bus(pacc);
+
        if (!sys && !input && !listknown)
                for (sys = allsystems; !SYSTEM_ISEOT(*sys); sys++) {
                        printf_verbose("Probing for system %s: %s\n", sys->name, sys->prettyname);
@@ -308,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))
@@ -336,12 +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, "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");
@@ -354,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);
@@ -372,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;
@@ -386,8 +419,13 @@ 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 = strtoul(argv[optind], NULL, 16);
+               addr = msraddrbyname(argv[optind]);
                if (!sys->rdmsr(cpu, addr, &msrval))
                        break;
                decodemsr(cpu, addr, msrval);