aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/power/x86/turbostat/turbostat.855
-rw-r--r--tools/power/x86/turbostat/turbostat.c214
2 files changed, 233 insertions, 36 deletions
diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8
index 74e44507dfe9..e4d0690cccf9 100644
--- a/tools/power/x86/turbostat/turbostat.8
+++ b/tools/power/x86/turbostat/turbostat.8
@@ -4,15 +4,11 @@ turbostat \- Report processor frequency and idle statistics
4.SH SYNOPSIS 4.SH SYNOPSIS
5.ft B 5.ft B
6.B turbostat 6.B turbostat
7.RB [ "\-s" ] 7.RB [ Options ]
8.RB [ "\-v" ]
9.RB [ "\-M MSR#" ]
10.RB command 8.RB command
11.br 9.br
12.B turbostat 10.B turbostat
13.RB [ "\-s" ] 11.RB [ Options ]
14.RB [ "\-v" ]
15.RB [ "\-M MSR#" ]
16.RB [ "\-i interval_sec" ] 12.RB [ "\-i interval_sec" ]
17.SH DESCRIPTION 13.SH DESCRIPTION
18\fBturbostat \fP reports processor topology, frequency 14\fBturbostat \fP reports processor topology, frequency
@@ -27,16 +23,23 @@ supports an "invariant" TSC, plus the APERF and MPERF MSRs.
27on processors that additionally support C-state residency counters. 23on processors that additionally support C-state residency counters.
28 24
29.SS Options 25.SS Options
30The \fB-s\fP option limits output to a 1-line system summary for each interval. 26The \fB-p\fP option limits output to the 1st thread in 1st core of each package.
31.PP 27.PP
32The \fB-c\fP option limits output to the 1st thread in each core. 28The \fB-P\fP option limits output to the 1st thread in each Package.
33.PP 29.PP
34The \fB-p\fP option limits output to the 1st thread in each package. 30The \fB-S\fP option limits output to a 1-line System Summary for each interval.
35.PP 31.PP
36The \fB-v\fP option increases verbosity. 32The \fB-v\fP option increases verbosity.
37.PP 33.PP
38The \fB-M MSR#\fP option dumps the specified MSR, 34The \fB-s\fP option prints the SMI counter, equivalent to "-c 0x34"
39in addition to the usual frequency and idle statistics. 35.PP
36The \fB-c MSR#\fP option includes the delta of the specified 32-bit MSR counter.
37.PP
38The \fB-C MSR#\fP option includes the delta of the specified 64-bit MSR counter.
39.PP
40The \fB-m MSR#\fP option includes the the specified 32-bit MSR value.
41.PP
42The \fB-M MSR#\fP option includes the the specified 64-bit MSR value.
40.PP 43.PP
41The \fB-i interval_sec\fP option prints statistics every \fiinterval_sec\fP seconds. 44The \fB-i interval_sec\fP option prints statistics every \fiinterval_sec\fP seconds.
42The default is 5 seconds. 45The default is 5 seconds.
@@ -150,6 +153,29 @@ Note that turbostat reports average GHz of 3.63, while
150the arithmetic average of the GHz column above is lower. 153the arithmetic average of the GHz column above is lower.
151This is a weighted average, where the weight is %c0. ie. it is the total number of 154This is a weighted average, where the weight is %c0. ie. it is the total number of
152un-halted cycles elapsed per time divided by the number of CPUs. 155un-halted cycles elapsed per time divided by the number of CPUs.
156.SH SMI COUNTING EXAMPLE
157On Intel Nehalem and newer processors, MSR 0x34 is a System Management Mode Interrupt (SMI) counter.
158Using the -m option, you can display how many SMIs have fired since reset, or if there
159are SMIs during the measurement interval, you can display the delta using the -d option.
160.nf
161[root@x980 ~]# turbostat -m 0x34
162cor CPU %c0 GHz TSC MSR 0x034 %c1 %c3 %c6 %pc3 %pc6
163 1.41 1.82 3.38 0x00000000 8.92 37.82 51.85 17.37 0.55
164 0 0 3.73 2.03 3.38 0x00000055 1.72 48.25 46.31 17.38 0.55
165 0 6 0.14 1.63 3.38 0x00000056 5.30
166 1 2 2.51 1.80 3.38 0x00000056 15.65 29.33 52.52
167 1 8 0.10 1.65 3.38 0x00000056 18.05
168 2 4 1.16 1.68 3.38 0x00000056 5.87 24.47 68.50
169 2 10 0.10 1.63 3.38 0x00000056 6.93
170 8 1 3.84 1.91 3.38 0x00000056 1.36 50.65 44.16
171 8 7 0.08 1.64 3.38 0x00000056 5.12
172 9 3 1.82 1.73 3.38 0x00000056 7.59 24.21 66.38
173 9 9 0.09 1.68 3.38 0x00000056 9.32
174 10 5 1.66 1.65 3.38 0x00000056 15.10 50.00 33.23
175 10 11 1.72 1.65 3.38 0x00000056 15.05
176^C
177[root@x980 ~]#
178.fi
153.SH NOTES 179.SH NOTES
154 180
155.B "turbostat " 181.B "turbostat "
@@ -165,6 +191,13 @@ may work poorly on Linux-2.6.20 through 2.6.29,
165as \fBacpi-cpufreq \fPperiodically cleared the APERF and MPERF 191as \fBacpi-cpufreq \fPperiodically cleared the APERF and MPERF
166in those kernels. 192in those kernels.
167 193
194If the TSC column does not make sense, then
195the other numbers will also make no sense.
196Turbostat is lightweight, and its data collection is not atomic.
197These issues are usually caused by an extremely short measurement
198interval (much less than 1 second), or system activity that prevents
199turbostat from being able to run on all CPUS to quickly collect data.
200
168The APERF, MPERF MSRs are defined to count non-halted cycles. 201The APERF, MPERF MSRs are defined to count non-halted cycles.
169Although it is not guaranteed by the architecture, turbostat assumes 202Although it is not guaranteed by the architecture, turbostat assumes
170that they count at TSC rate, which is true on all processors tested to date. 203that they count at TSC rate, which is true on all processors tested to date.
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 861d77190206..2655ae9a3ad8 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -35,9 +35,9 @@
35#include <ctype.h> 35#include <ctype.h>
36#include <sched.h> 36#include <sched.h>
37 37
38#define MSR_TSC 0x10
39#define MSR_NEHALEM_PLATFORM_INFO 0xCE 38#define MSR_NEHALEM_PLATFORM_INFO 0xCE
40#define MSR_NEHALEM_TURBO_RATIO_LIMIT 0x1AD 39#define MSR_NEHALEM_TURBO_RATIO_LIMIT 0x1AD
40#define MSR_IVT_TURBO_RATIO_LIMIT 0x1AE
41#define MSR_APERF 0xE8 41#define MSR_APERF 0xE8
42#define MSR_MPERF 0xE7 42#define MSR_MPERF 0xE7
43#define MSR_PKG_C2_RESIDENCY 0x60D /* SNB only */ 43#define MSR_PKG_C2_RESIDENCY 0x60D /* SNB only */
@@ -62,7 +62,11 @@ unsigned int genuine_intel;
62unsigned int has_invariant_tsc; 62unsigned int has_invariant_tsc;
63unsigned int do_nehalem_platform_info; 63unsigned int do_nehalem_platform_info;
64unsigned int do_nehalem_turbo_ratio_limit; 64unsigned int do_nehalem_turbo_ratio_limit;
65unsigned int extra_msr_offset; 65unsigned int do_ivt_turbo_ratio_limit;
66unsigned int extra_msr_offset32;
67unsigned int extra_msr_offset64;
68unsigned int extra_delta_offset32;
69unsigned int extra_delta_offset64;
66double bclk; 70double bclk;
67unsigned int show_pkg; 71unsigned int show_pkg;
68unsigned int show_core; 72unsigned int show_core;
@@ -83,7 +87,10 @@ struct thread_data {
83 unsigned long long aperf; 87 unsigned long long aperf;
84 unsigned long long mperf; 88 unsigned long long mperf;
85 unsigned long long c1; /* derived */ 89 unsigned long long c1; /* derived */
86 unsigned long long extra_msr; 90 unsigned long long extra_msr64;
91 unsigned long long extra_delta64;
92 unsigned long long extra_msr32;
93 unsigned long long extra_delta32;
87 unsigned int cpu_id; 94 unsigned int cpu_id;
88 unsigned int flags; 95 unsigned int flags;
89#define CPU_IS_FIRST_THREAD_IN_CORE 0x2 96#define CPU_IS_FIRST_THREAD_IN_CORE 0x2
@@ -222,6 +229,14 @@ void print_header(void)
222 if (has_aperf) 229 if (has_aperf)
223 outp += sprintf(outp, " GHz"); 230 outp += sprintf(outp, " GHz");
224 outp += sprintf(outp, " TSC"); 231 outp += sprintf(outp, " TSC");
232 if (extra_delta_offset32)
233 outp += sprintf(outp, " count 0x%03X", extra_delta_offset32);
234 if (extra_delta_offset64)
235 outp += sprintf(outp, " COUNT 0x%03X", extra_delta_offset64);
236 if (extra_msr_offset32)
237 outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset32);
238 if (extra_msr_offset64)
239 outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64);
225 if (do_nhm_cstates) 240 if (do_nhm_cstates)
226 outp += sprintf(outp, " %%c1"); 241 outp += sprintf(outp, " %%c1");
227 if (do_nhm_cstates) 242 if (do_nhm_cstates)
@@ -238,8 +253,6 @@ void print_header(void)
238 outp += sprintf(outp, " %%pc6"); 253 outp += sprintf(outp, " %%pc6");
239 if (do_snb_cstates) 254 if (do_snb_cstates)
240 outp += sprintf(outp, " %%pc7"); 255 outp += sprintf(outp, " %%pc7");
241 if (extra_msr_offset)
242 outp += sprintf(outp, " MSR 0x%x ", extra_msr_offset);
243 256
244 outp += sprintf(outp, "\n"); 257 outp += sprintf(outp, "\n");
245} 258}
@@ -255,8 +268,14 @@ int dump_counters(struct thread_data *t, struct core_data *c,
255 fprintf(stderr, "aperf: %016llX\n", t->aperf); 268 fprintf(stderr, "aperf: %016llX\n", t->aperf);
256 fprintf(stderr, "mperf: %016llX\n", t->mperf); 269 fprintf(stderr, "mperf: %016llX\n", t->mperf);
257 fprintf(stderr, "c1: %016llX\n", t->c1); 270 fprintf(stderr, "c1: %016llX\n", t->c1);
271 fprintf(stderr, "msr0x%x: %08llX\n",
272 extra_delta_offset32, t->extra_delta32);
258 fprintf(stderr, "msr0x%x: %016llX\n", 273 fprintf(stderr, "msr0x%x: %016llX\n",
259 extra_msr_offset, t->extra_msr); 274 extra_delta_offset64, t->extra_delta64);
275 fprintf(stderr, "msr0x%x: %08llX\n",
276 extra_msr_offset32, t->extra_msr32);
277 fprintf(stderr, "msr0x%x: %016llX\n",
278 extra_msr_offset64, t->extra_msr64);
260 } 279 }
261 280
262 if (c) { 281 if (c) {
@@ -360,6 +379,21 @@ int format_counters(struct thread_data *t, struct core_data *c,
360 /* TSC */ 379 /* TSC */
361 outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float); 380 outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float);
362 381
382 /* delta */
383 if (extra_delta_offset32)
384 outp += sprintf(outp, " %11llu", t->extra_delta32);
385
386 /* DELTA */
387 if (extra_delta_offset64)
388 outp += sprintf(outp, " %11llu", t->extra_delta64);
389 /* msr */
390 if (extra_msr_offset32)
391 outp += sprintf(outp, " 0x%08llx", t->extra_msr32);
392
393 /* MSR */
394 if (extra_msr_offset64)
395 outp += sprintf(outp, " 0x%016llx", t->extra_msr64);
396
363 if (do_nhm_cstates) { 397 if (do_nhm_cstates) {
364 if (!skip_c1) 398 if (!skip_c1)
365 outp += sprintf(outp, " %6.2f", 100.0 * t->c1/t->tsc); 399 outp += sprintf(outp, " %6.2f", 100.0 * t->c1/t->tsc);
@@ -391,8 +425,6 @@ int format_counters(struct thread_data *t, struct core_data *c,
391 if (do_snb_cstates) 425 if (do_snb_cstates)
392 outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc); 426 outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc);
393done: 427done:
394 if (extra_msr_offset)
395 outp += sprintf(outp, " 0x%016llx", t->extra_msr);
396 outp += sprintf(outp, "\n"); 428 outp += sprintf(outp, "\n");
397 429
398 return 0; 430 return 0;
@@ -502,10 +534,16 @@ delta_thread(struct thread_data *new, struct thread_data *old,
502 old->mperf = 1; /* divide by 0 protection */ 534 old->mperf = 1; /* divide by 0 protection */
503 } 535 }
504 536
537 old->extra_delta32 = new->extra_delta32 - old->extra_delta32;
538 old->extra_delta32 &= 0xFFFFFFFF;
539
540 old->extra_delta64 = new->extra_delta64 - old->extra_delta64;
541
505 /* 542 /*
506 * for "extra msr", just copy the latest w/o subtracting 543 * Extra MSR is just a snapshot, simply copy latest w/o subtracting
507 */ 544 */
508 old->extra_msr = new->extra_msr; 545 old->extra_msr32 = new->extra_msr32;
546 old->extra_msr64 = new->extra_msr64;
509} 547}
510 548
511int delta_cpu(struct thread_data *t, struct core_data *c, 549int delta_cpu(struct thread_data *t, struct core_data *c,
@@ -533,6 +571,9 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data
533 t->mperf = 0; 571 t->mperf = 0;
534 t->c1 = 0; 572 t->c1 = 0;
535 573
574 t->extra_delta32 = 0;
575 t->extra_delta64 = 0;
576
536 /* tells format_counters to dump all fields from this set */ 577 /* tells format_counters to dump all fields from this set */
537 t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE; 578 t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE;
538 579
@@ -553,6 +594,9 @@ int sum_counters(struct thread_data *t, struct core_data *c,
553 average.threads.mperf += t->mperf; 594 average.threads.mperf += t->mperf;
554 average.threads.c1 += t->c1; 595 average.threads.c1 += t->c1;
555 596
597 average.threads.extra_delta32 += t->extra_delta32;
598 average.threads.extra_delta64 += t->extra_delta64;
599
556 /* sum per-core values only for 1st thread in core */ 600 /* sum per-core values only for 1st thread in core */
557 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) 601 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
558 return 0; 602 return 0;
@@ -588,6 +632,11 @@ void compute_average(struct thread_data *t, struct core_data *c,
588 average.threads.mperf /= topo.num_cpus; 632 average.threads.mperf /= topo.num_cpus;
589 average.threads.c1 /= topo.num_cpus; 633 average.threads.c1 /= topo.num_cpus;
590 634
635 average.threads.extra_delta32 /= topo.num_cpus;
636 average.threads.extra_delta32 &= 0xFFFFFFFF;
637
638 average.threads.extra_delta64 /= topo.num_cpus;
639
591 average.cores.c3 /= topo.num_cores; 640 average.cores.c3 /= topo.num_cores;
592 average.cores.c6 /= topo.num_cores; 641 average.cores.c6 /= topo.num_cores;
593 average.cores.c7 /= topo.num_cores; 642 average.cores.c7 /= topo.num_cores;
@@ -629,8 +678,24 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
629 return -4; 678 return -4;
630 } 679 }
631 680
632 if (extra_msr_offset) 681 if (extra_delta_offset32) {
633 if (get_msr(cpu, extra_msr_offset, &t->extra_msr)) 682 if (get_msr(cpu, extra_delta_offset32, &t->extra_delta32))
683 return -5;
684 t->extra_delta32 &= 0xFFFFFFFF;
685 }
686
687 if (extra_delta_offset64)
688 if (get_msr(cpu, extra_delta_offset64, &t->extra_delta64))
689 return -5;
690
691 if (extra_msr_offset32) {
692 if (get_msr(cpu, extra_msr_offset32, &t->extra_msr32))
693 return -5;
694 t->extra_msr32 &= 0xFFFFFFFF;
695 }
696
697 if (extra_msr_offset64)
698 if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64))
634 return -5; 699 return -5;
635 700
636 /* collect core counters only for 1st thread in core */ 701 /* collect core counters only for 1st thread in core */
@@ -677,6 +742,9 @@ void print_verbose_header(void)
677 742
678 get_msr(0, MSR_NEHALEM_PLATFORM_INFO, &msr); 743 get_msr(0, MSR_NEHALEM_PLATFORM_INFO, &msr);
679 744
745 if (verbose > 1)
746 fprintf(stderr, "MSR_NEHALEM_PLATFORM_INFO: 0x%llx\n", msr);
747
680 ratio = (msr >> 40) & 0xFF; 748 ratio = (msr >> 40) & 0xFF;
681 fprintf(stderr, "%d * %.0f = %.0f MHz max efficiency\n", 749 fprintf(stderr, "%d * %.0f = %.0f MHz max efficiency\n",
682 ratio, bclk, ratio * bclk); 750 ratio, bclk, ratio * bclk);
@@ -685,14 +753,84 @@ void print_verbose_header(void)
685 fprintf(stderr, "%d * %.0f = %.0f MHz TSC frequency\n", 753 fprintf(stderr, "%d * %.0f = %.0f MHz TSC frequency\n",
686 ratio, bclk, ratio * bclk); 754 ratio, bclk, ratio * bclk);
687 755
756 if (!do_ivt_turbo_ratio_limit)
757 goto print_nhm_turbo_ratio_limits;
758
759 get_msr(0, MSR_IVT_TURBO_RATIO_LIMIT, &msr);
760
688 if (verbose > 1) 761 if (verbose > 1)
689 fprintf(stderr, "MSR_NEHALEM_PLATFORM_INFO: 0x%llx\n", msr); 762 fprintf(stderr, "MSR_IVT_TURBO_RATIO_LIMIT: 0x%llx\n", msr);
763
764 ratio = (msr >> 56) & 0xFF;
765 if (ratio)
766 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 16 active cores\n",
767 ratio, bclk, ratio * bclk);
768
769 ratio = (msr >> 48) & 0xFF;
770 if (ratio)
771 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 15 active cores\n",
772 ratio, bclk, ratio * bclk);
773
774 ratio = (msr >> 40) & 0xFF;
775 if (ratio)
776 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 14 active cores\n",
777 ratio, bclk, ratio * bclk);
778
779 ratio = (msr >> 32) & 0xFF;
780 if (ratio)
781 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 13 active cores\n",
782 ratio, bclk, ratio * bclk);
783
784 ratio = (msr >> 24) & 0xFF;
785 if (ratio)
786 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 12 active cores\n",
787 ratio, bclk, ratio * bclk);
788
789 ratio = (msr >> 16) & 0xFF;
790 if (ratio)
791 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 11 active cores\n",
792 ratio, bclk, ratio * bclk);
793
794 ratio = (msr >> 8) & 0xFF;
795 if (ratio)
796 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 10 active cores\n",
797 ratio, bclk, ratio * bclk);
798
799 ratio = (msr >> 0) & 0xFF;
800 if (ratio)
801 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 9 active cores\n",
802 ratio, bclk, ratio * bclk);
803
804print_nhm_turbo_ratio_limits:
690 805
691 if (!do_nehalem_turbo_ratio_limit) 806 if (!do_nehalem_turbo_ratio_limit)
692 return; 807 return;
693 808
694 get_msr(0, MSR_NEHALEM_TURBO_RATIO_LIMIT, &msr); 809 get_msr(0, MSR_NEHALEM_TURBO_RATIO_LIMIT, &msr);
695 810
811 if (verbose > 1)
812 fprintf(stderr, "MSR_NEHALEM_TURBO_RATIO_LIMIT: 0x%llx\n", msr);
813
814 ratio = (msr >> 56) & 0xFF;
815 if (ratio)
816 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 8 active cores\n",
817 ratio, bclk, ratio * bclk);
818
819 ratio = (msr >> 48) & 0xFF;
820 if (ratio)
821 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 7 active cores\n",
822 ratio, bclk, ratio * bclk);
823
824 ratio = (msr >> 40) & 0xFF;
825 if (ratio)
826 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 6 active cores\n",
827 ratio, bclk, ratio * bclk);
828
829 ratio = (msr >> 32) & 0xFF;
830 if (ratio)
831 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 5 active cores\n",
832 ratio, bclk, ratio * bclk);
833
696 ratio = (msr >> 24) & 0xFF; 834 ratio = (msr >> 24) & 0xFF;
697 if (ratio) 835 if (ratio)
698 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 4 active cores\n", 836 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 4 active cores\n",
@@ -712,7 +850,6 @@ void print_verbose_header(void)
712 if (ratio) 850 if (ratio)
713 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 1 active cores\n", 851 fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 1 active cores\n",
714 ratio, bclk, ratio * bclk); 852 ratio, bclk, ratio * bclk);
715
716} 853}
717 854
718void free_all_buffers(void) 855void free_all_buffers(void)
@@ -1038,7 +1175,7 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
1038 case 0x2A: /* SNB */ 1175 case 0x2A: /* SNB */
1039 case 0x2D: /* SNB Xeon */ 1176 case 0x2D: /* SNB Xeon */
1040 case 0x3A: /* IVB */ 1177 case 0x3A: /* IVB */
1041 case 0x3D: /* IVB Xeon */ 1178 case 0x3E: /* IVB Xeon */
1042 return 1; 1179 return 1;
1043 case 0x2E: /* Nehalem-EX Xeon - Beckton */ 1180 case 0x2E: /* Nehalem-EX Xeon - Beckton */
1044 case 0x2F: /* Westmere-EX Xeon - Eagleton */ 1181 case 0x2F: /* Westmere-EX Xeon - Eagleton */
@@ -1046,6 +1183,22 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
1046 return 0; 1183 return 0;
1047 } 1184 }
1048} 1185}
1186int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model)
1187{
1188 if (!genuine_intel)
1189 return 0;
1190
1191 if (family != 6)
1192 return 0;
1193
1194 switch (model) {
1195 case 0x3E: /* IVB Xeon */
1196 return 1;
1197 default:
1198 return 0;
1199 }
1200}
1201
1049 1202
1050int is_snb(unsigned int family, unsigned int model) 1203int is_snb(unsigned int family, unsigned int model)
1051{ 1204{
@@ -1056,7 +1209,7 @@ int is_snb(unsigned int family, unsigned int model)
1056 case 0x2A: 1209 case 0x2A:
1057 case 0x2D: 1210 case 0x2D:
1058 case 0x3A: /* IVB */ 1211 case 0x3A: /* IVB */
1059 case 0x3D: /* IVB Xeon */ 1212 case 0x3E: /* IVB Xeon */
1060 return 1; 1213 return 1;
1061 } 1214 }
1062 return 0; 1215 return 0;
@@ -1145,12 +1298,13 @@ void check_cpuid()
1145 bclk = discover_bclk(family, model); 1298 bclk = discover_bclk(family, model);
1146 1299
1147 do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model); 1300 do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model);
1301 do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model);
1148} 1302}
1149 1303
1150 1304
1151void usage() 1305void usage()
1152{ 1306{
1153 fprintf(stderr, "%s: [-v] [-M MSR#] [-i interval_sec | command ...]\n", 1307 fprintf(stderr, "%s: [-v][-p|-P|-S][-c MSR# | -s]][-C MSR#][-m MSR#][-M MSR#][-i interval_sec | command ...]\n",
1154 progname); 1308 progname);
1155 exit(1); 1309 exit(1);
1156} 1310}
@@ -1440,15 +1594,15 @@ void cmdline(int argc, char **argv)
1440 1594
1441 progname = argv[0]; 1595 progname = argv[0];
1442 1596
1443 while ((opt = getopt(argc, argv, "+cpsvi:M:")) != -1) { 1597 while ((opt = getopt(argc, argv, "+pPSvisc:sC:m:M:")) != -1) {
1444 switch (opt) { 1598 switch (opt) {
1445 case 'c': 1599 case 'p':
1446 show_core_only++; 1600 show_core_only++;
1447 break; 1601 break;
1448 case 'p': 1602 case 'P':
1449 show_pkg_only++; 1603 show_pkg_only++;
1450 break; 1604 break;
1451 case 's': 1605 case 'S':
1452 summary_only++; 1606 summary_only++;
1453 break; 1607 break;
1454 case 'v': 1608 case 'v':
@@ -1457,10 +1611,20 @@ void cmdline(int argc, char **argv)
1457 case 'i': 1611 case 'i':
1458 interval_sec = atoi(optarg); 1612 interval_sec = atoi(optarg);
1459 break; 1613 break;
1614 case 'c':
1615 sscanf(optarg, "%x", &extra_delta_offset32);
1616 break;
1617 case 's':
1618 extra_delta_offset32 = 0x34; /* SMI counter */
1619 break;
1620 case 'C':
1621 sscanf(optarg, "%x", &extra_delta_offset64);
1622 break;
1623 case 'm':
1624 sscanf(optarg, "%x", &extra_msr_offset32);
1625 break;
1460 case 'M': 1626 case 'M':
1461 sscanf(optarg, "%x", &extra_msr_offset); 1627 sscanf(optarg, "%x", &extra_msr_offset64);
1462 if (verbose > 1)
1463 fprintf(stderr, "MSR 0x%X\n", extra_msr_offset);
1464 break; 1628 break;
1465 default: 1629 default:
1466 usage(); 1630 usage();
@@ -1473,7 +1637,7 @@ int main(int argc, char **argv)
1473 cmdline(argc, argv); 1637 cmdline(argc, argv);
1474 1638
1475 if (verbose > 1) 1639 if (verbose > 1)
1476 fprintf(stderr, "turbostat v2.0 May 16, 2012" 1640 fprintf(stderr, "turbostat v2.1 October 6, 2012"
1477 " - Len Brown <lenb@kernel.org>\n"); 1641 " - Len Brown <lenb@kernel.org>\n");
1478 1642
1479 turbostat_init(); 1643 turbostat_init();