]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - tools/power/x86/turbostat/turbostat.c
tools/power turbostat: fix SKX PKG_CSTATE_LIMIT decoding
[mirror_ubuntu-zesty-kernel.git] / tools / power / x86 / turbostat / turbostat.c
CommitLineData
103a8fea
LB
1/*
2 * turbostat -- show CPU frequency and C-state residency
3 * on modern Intel turbo-capable processors.
4 *
144b44b1 5 * Copyright (c) 2013 Intel Corporation.
103a8fea
LB
6 * Len Brown <len.brown@intel.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
88c3281f 22#define _GNU_SOURCE
b731f311 23#include MSRHEADER
869ce69e 24#include INTEL_FAMILY_HEADER
95aebc44 25#include <stdarg.h>
103a8fea 26#include <stdio.h>
b2c95d90 27#include <err.h>
103a8fea
LB
28#include <unistd.h>
29#include <sys/types.h>
30#include <sys/wait.h>
31#include <sys/stat.h>
32#include <sys/resource.h>
33#include <fcntl.h>
34#include <signal.h>
35#include <sys/time.h>
36#include <stdlib.h>
d8af6f5f 37#include <getopt.h>
103a8fea
LB
38#include <dirent.h>
39#include <string.h>
40#include <ctype.h>
88c3281f 41#include <sched.h>
2a0609c0 42#include <time.h>
2b92865e 43#include <cpuid.h>
98481e79
LB
44#include <linux/capability.h>
45#include <errno.h>
103a8fea 46
103a8fea 47char *proc_stat = "/proc/stat";
b7d8c148 48FILE *outf;
36229897 49int *fd_percpu;
2a0609c0 50struct timespec interval_ts = {5, 0};
d8af6f5f
LB
51unsigned int debug;
52unsigned int rapl_joules;
53unsigned int summary_only;
54unsigned int dump_only;
103a8fea
LB
55unsigned int do_nhm_cstates;
56unsigned int do_snb_cstates;
fb5d4327 57unsigned int do_knl_cstates;
ee7e38e3
LB
58unsigned int do_pc2;
59unsigned int do_pc3;
60unsigned int do_pc6;
61unsigned int do_pc7;
ca58710f 62unsigned int do_c8_c9_c10;
0b2bb692 63unsigned int do_skl_residency;
144b44b1
LB
64unsigned int do_slm_cstates;
65unsigned int use_c1_residency_msr;
103a8fea 66unsigned int has_aperf;
889facbe 67unsigned int has_epb;
5a63426e
LB
68unsigned int do_irtl_snb;
69unsigned int do_irtl_hsw;
fc04cc67 70unsigned int units = 1000000; /* MHz etc */
103a8fea
LB
71unsigned int genuine_intel;
72unsigned int has_invariant_tsc;
d7899447 73unsigned int do_nhm_platform_info;
2f32edf1
LB
74unsigned int extra_msr_offset32;
75unsigned int extra_msr_offset64;
8e180f3c
LB
76unsigned int extra_delta_offset32;
77unsigned int extra_delta_offset64;
b2b34dfe 78unsigned int aperf_mperf_multiplier = 1;
562a2d37 79int do_irq = 1;
1ed51011 80int do_smi;
103a8fea 81double bclk;
a2b7b749 82double base_hz;
21ed5574 83unsigned int has_base_hz;
a2b7b749 84double tsc_tweak = 1.0;
103a8fea
LB
85unsigned int show_pkg;
86unsigned int show_core;
87unsigned int show_cpu;
c98d5d94
LB
88unsigned int show_pkg_only;
89unsigned int show_core_only;
90char *output_buffer, *outp;
889facbe
LB
91unsigned int do_rapl;
92unsigned int do_dts;
93unsigned int do_ptm;
fdf676e5
LB
94unsigned int do_gfx_rc6_ms;
95unsigned long long gfx_cur_rc6_ms;
27d47356
LB
96unsigned int do_gfx_mhz;
97unsigned int gfx_cur_mhz;
889facbe
LB
98unsigned int tcc_activation_temp;
99unsigned int tcc_activation_temp_override;
40ee8e3b
AS
100double rapl_power_units, rapl_time_units;
101double rapl_dram_energy_units, rapl_energy_units;
889facbe 102double rapl_joule_counter_range;
3a9a941d
LB
103unsigned int do_core_perf_limit_reasons;
104unsigned int do_gfx_perf_limit_reasons;
105unsigned int do_ring_perf_limit_reasons;
8a5bdf41
LB
106unsigned int crystal_hz;
107unsigned long long tsc_hz;
7ce7d5de 108int base_cpu;
21ed5574 109double discover_bclk(unsigned int family, unsigned int model);
7f5c258e
LB
110unsigned int has_hwp; /* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */
111 /* IA32_HWP_REQUEST, IA32_HWP_STATUS */
112unsigned int has_hwp_notify; /* IA32_HWP_INTERRUPT */
113unsigned int has_hwp_activity_window; /* IA32_HWP_REQUEST[bits 41:32] */
114unsigned int has_hwp_epp; /* IA32_HWP_REQUEST[bits 31:24] */
115unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */
889facbe 116
e6f9bb3c
LB
117#define RAPL_PKG (1 << 0)
118 /* 0x610 MSR_PKG_POWER_LIMIT */
119 /* 0x611 MSR_PKG_ENERGY_STATUS */
120#define RAPL_PKG_PERF_STATUS (1 << 1)
121 /* 0x613 MSR_PKG_PERF_STATUS */
122#define RAPL_PKG_POWER_INFO (1 << 2)
123 /* 0x614 MSR_PKG_POWER_INFO */
124
125#define RAPL_DRAM (1 << 3)
126 /* 0x618 MSR_DRAM_POWER_LIMIT */
127 /* 0x619 MSR_DRAM_ENERGY_STATUS */
e6f9bb3c
LB
128#define RAPL_DRAM_PERF_STATUS (1 << 4)
129 /* 0x61b MSR_DRAM_PERF_STATUS */
0b2bb692
LB
130#define RAPL_DRAM_POWER_INFO (1 << 5)
131 /* 0x61c MSR_DRAM_POWER_INFO */
e6f9bb3c 132
9148494c 133#define RAPL_CORES_POWER_LIMIT (1 << 6)
e6f9bb3c 134 /* 0x638 MSR_PP0_POWER_LIMIT */
0b2bb692 135#define RAPL_CORE_POLICY (1 << 7)
e6f9bb3c
LB
136 /* 0x63a MSR_PP0_POLICY */
137
0b2bb692 138#define RAPL_GFX (1 << 8)
e6f9bb3c
LB
139 /* 0x640 MSR_PP1_POWER_LIMIT */
140 /* 0x641 MSR_PP1_ENERGY_STATUS */
141 /* 0x642 MSR_PP1_POLICY */
9148494c
JP
142
143#define RAPL_CORES_ENERGY_STATUS (1 << 9)
144 /* 0x639 MSR_PP0_ENERGY_STATUS */
145#define RAPL_CORES (RAPL_CORES_ENERGY_STATUS | RAPL_CORES_POWER_LIMIT)
889facbe
LB
146#define TJMAX_DEFAULT 100
147
148#define MAX(a, b) ((a) > (b) ? (a) : (b))
103a8fea 149
103a8fea
LB
150int backwards_count;
151char *progname;
103a8fea 152
c98d5d94
LB
153cpu_set_t *cpu_present_set, *cpu_affinity_set;
154size_t cpu_present_setsize, cpu_affinity_setsize;
155
156struct thread_data {
157 unsigned long long tsc;
158 unsigned long long aperf;
159 unsigned long long mperf;
144b44b1 160 unsigned long long c1;
2f32edf1 161 unsigned long long extra_msr64;
8e180f3c
LB
162 unsigned long long extra_delta64;
163 unsigned long long extra_msr32;
164 unsigned long long extra_delta32;
562a2d37 165 unsigned int irq_count;
1ed51011 166 unsigned int smi_count;
c98d5d94
LB
167 unsigned int cpu_id;
168 unsigned int flags;
169#define CPU_IS_FIRST_THREAD_IN_CORE 0x2
170#define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4
171} *thread_even, *thread_odd;
172
173struct core_data {
174 unsigned long long c3;
175 unsigned long long c6;
176 unsigned long long c7;
889facbe 177 unsigned int core_temp_c;
c98d5d94
LB
178 unsigned int core_id;
179} *core_even, *core_odd;
180
181struct pkg_data {
182 unsigned long long pc2;
183 unsigned long long pc3;
184 unsigned long long pc6;
185 unsigned long long pc7;
ca58710f
KCA
186 unsigned long long pc8;
187 unsigned long long pc9;
188 unsigned long long pc10;
0b2bb692
LB
189 unsigned long long pkg_wtd_core_c0;
190 unsigned long long pkg_any_core_c0;
191 unsigned long long pkg_any_gfxe_c0;
192 unsigned long long pkg_both_core_gfxe_c0;
9185e988 193 long long gfx_rc6_ms;
27d47356 194 unsigned int gfx_mhz;
c98d5d94 195 unsigned int package_id;
889facbe
LB
196 unsigned int energy_pkg; /* MSR_PKG_ENERGY_STATUS */
197 unsigned int energy_dram; /* MSR_DRAM_ENERGY_STATUS */
198 unsigned int energy_cores; /* MSR_PP0_ENERGY_STATUS */
199 unsigned int energy_gfx; /* MSR_PP1_ENERGY_STATUS */
200 unsigned int rapl_pkg_perf_status; /* MSR_PKG_PERF_STATUS */
201 unsigned int rapl_dram_perf_status; /* MSR_DRAM_PERF_STATUS */
202 unsigned int pkg_temp_c;
203
c98d5d94
LB
204} *package_even, *package_odd;
205
206#define ODD_COUNTERS thread_odd, core_odd, package_odd
207#define EVEN_COUNTERS thread_even, core_even, package_even
208
209#define GET_THREAD(thread_base, thread_no, core_no, pkg_no) \
210 (thread_base + (pkg_no) * topo.num_cores_per_pkg * \
211 topo.num_threads_per_core + \
212 (core_no) * topo.num_threads_per_core + (thread_no))
213#define GET_CORE(core_base, core_no, pkg_no) \
214 (core_base + (pkg_no) * topo.num_cores_per_pkg + (core_no))
215#define GET_PKG(pkg_base, pkg_no) (pkg_base + pkg_no)
216
217struct system_summary {
218 struct thread_data threads;
219 struct core_data cores;
220 struct pkg_data packages;
221} sum, average;
222
223
224struct topo_params {
225 int num_packages;
226 int num_cpus;
227 int num_cores;
228 int max_cpu_num;
229 int num_cores_per_pkg;
230 int num_threads_per_core;
231} topo;
232
233struct timeval tv_even, tv_odd, tv_delta;
234
562a2d37
LB
235int *irq_column_2_cpu; /* /proc/interrupts column numbers */
236int *irqs_per_cpu; /* indexed by cpu_num */
237
c98d5d94
LB
238void setup_all_buffers(void);
239
240int cpu_is_not_present(int cpu)
d15cf7c1 241{
c98d5d94 242 return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set);
d15cf7c1 243}
88c3281f 244/*
c98d5d94
LB
245 * run func(thread, core, package) in topology order
246 * skip non-present cpus
88c3281f 247 */
c98d5d94
LB
248
249int for_all_cpus(int (func)(struct thread_data *, struct core_data *, struct pkg_data *),
250 struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base)
88c3281f 251{
c98d5d94 252 int retval, pkg_no, core_no, thread_no;
d15cf7c1 253
c98d5d94
LB
254 for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) {
255 for (core_no = 0; core_no < topo.num_cores_per_pkg; ++core_no) {
256 for (thread_no = 0; thread_no <
257 topo.num_threads_per_core; ++thread_no) {
258 struct thread_data *t;
259 struct core_data *c;
260 struct pkg_data *p;
88c3281f 261
c98d5d94
LB
262 t = GET_THREAD(thread_base, thread_no, core_no, pkg_no);
263
264 if (cpu_is_not_present(t->cpu_id))
265 continue;
266
267 c = GET_CORE(core_base, core_no, pkg_no);
268 p = GET_PKG(pkg_base, pkg_no);
269
270 retval = func(t, c, p);
271 if (retval)
272 return retval;
273 }
274 }
275 }
276 return 0;
88c3281f
LB
277}
278
279int cpu_migrate(int cpu)
280{
c98d5d94
LB
281 CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
282 CPU_SET_S(cpu, cpu_affinity_setsize, cpu_affinity_set);
283 if (sched_setaffinity(0, cpu_affinity_setsize, cpu_affinity_set) == -1)
88c3281f
LB
284 return -1;
285 else
286 return 0;
287}
36229897 288int get_msr_fd(int cpu)
103a8fea 289{
103a8fea
LB
290 char pathname[32];
291 int fd;
292
36229897
LB
293 fd = fd_percpu[cpu];
294
295 if (fd)
296 return fd;
297
103a8fea
LB
298 sprintf(pathname, "/dev/cpu/%d/msr", cpu);
299 fd = open(pathname, O_RDONLY);
15aaa346 300 if (fd < 0)
98481e79 301 err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, or run as root", pathname);
103a8fea 302
36229897
LB
303 fd_percpu[cpu] = fd;
304
305 return fd;
306}
307
308int get_msr(int cpu, off_t offset, unsigned long long *msr)
309{
310 ssize_t retval;
311
312 retval = pread(get_msr_fd(cpu), msr, sizeof(*msr), offset);
15aaa346 313
98481e79 314 if (retval != sizeof *msr)
36229897 315 err(-1, "msr %d offset 0x%llx read failed", cpu, (unsigned long long)offset);
15aaa346
LB
316
317 return 0;
103a8fea
LB
318}
319
fc04cc67
LB
320/*
321 * Example Format w/ field column widths:
322 *
27d47356 323 * Package Core CPU Avg_MHz Bzy_MHz TSC_MHz IRQ SMI Busy% CPU_%c1 CPU_%c3 CPU_%c6 CPU_%c7 CoreTmp PkgTmp GFXMHz Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt
562a2d37 324 * 12345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678
fc04cc67
LB
325 */
326
a829eb4d 327void print_header(void)
103a8fea
LB
328{
329 if (show_pkg)
3d109de2 330 outp += sprintf(outp, "\tPackage");
103a8fea 331 if (show_core)
3d109de2 332 outp += sprintf(outp, "\tCore");
103a8fea 333 if (show_cpu)
3d109de2 334 outp += sprintf(outp, "\tCPU");
fc04cc67 335 if (has_aperf)
3d109de2 336 outp += sprintf(outp, "\tAvg_MHz");
d7899447 337 if (has_aperf)
3d109de2 338 outp += sprintf(outp, "\tBusy%%");
103a8fea 339 if (has_aperf)
3d109de2
LB
340 outp += sprintf(outp, "\tBzy_MHz");
341 outp += sprintf(outp, "\tTSC_MHz");
1cc21f7b 342
8e180f3c 343 if (extra_delta_offset32)
3d109de2 344 outp += sprintf(outp, "\tcount 0x%03X", extra_delta_offset32);
8e180f3c 345 if (extra_delta_offset64)
3d109de2 346 outp += sprintf(outp, "\tCOUNT 0x%03X", extra_delta_offset64);
2f32edf1 347 if (extra_msr_offset32)
3d109de2 348 outp += sprintf(outp, "\tMSR 0x%03X", extra_msr_offset32);
2f32edf1 349 if (extra_msr_offset64)
3d109de2 350 outp += sprintf(outp, "\tMSR 0x%03X", extra_msr_offset64);
1cc21f7b
LB
351
352 if (!debug)
353 goto done;
354
562a2d37 355 if (do_irq)
3d109de2 356 outp += sprintf(outp, "\tIRQ");
1cc21f7b 357 if (do_smi)
3d109de2 358 outp += sprintf(outp, "\tSMI");
1cc21f7b 359
103a8fea 360 if (do_nhm_cstates)
3d109de2 361 outp += sprintf(outp, "\tCPU%%c1");
fb5d4327 362 if (do_nhm_cstates && !do_slm_cstates && !do_knl_cstates)
3d109de2 363 outp += sprintf(outp, "\tCPU%%c3");
103a8fea 364 if (do_nhm_cstates)
3d109de2 365 outp += sprintf(outp, "\tCPU%%c6");
103a8fea 366 if (do_snb_cstates)
3d109de2 367 outp += sprintf(outp, "\tCPU%%c7");
889facbe
LB
368
369 if (do_dts)
3d109de2 370 outp += sprintf(outp, "\tCoreTmp");
889facbe 371 if (do_ptm)
3d109de2 372 outp += sprintf(outp, "\tPkgTmp");
889facbe 373
fdf676e5 374 if (do_gfx_rc6_ms)
3d109de2 375 outp += sprintf(outp, "\tGFX%%rc6");
fdf676e5 376
27d47356 377 if (do_gfx_mhz)
3d109de2 378 outp += sprintf(outp, "\tGFXMHz");
27d47356 379
0b2bb692 380 if (do_skl_residency) {
3d109de2
LB
381 outp += sprintf(outp, "\tTotl%%C0");
382 outp += sprintf(outp, "\tAny%%C0");
383 outp += sprintf(outp, "\tGFX%%C0");
384 outp += sprintf(outp, "\tCPUGFX%%");
0b2bb692
LB
385 }
386
ee7e38e3 387 if (do_pc2)
3d109de2 388 outp += sprintf(outp, "\tPkg%%pc2");
ee7e38e3 389 if (do_pc3)
3d109de2 390 outp += sprintf(outp, "\tPkg%%pc3");
ee7e38e3 391 if (do_pc6)
3d109de2 392 outp += sprintf(outp, "\tPkg%%pc6");
ee7e38e3 393 if (do_pc7)
3d109de2 394 outp += sprintf(outp, "\tPkg%%pc7");
ca58710f 395 if (do_c8_c9_c10) {
3d109de2
LB
396 outp += sprintf(outp, "\tPkg%%pc8");
397 outp += sprintf(outp, "\tPkg%%pc9");
398 outp += sprintf(outp, "\tPk%%pc10");
ca58710f 399 }
103a8fea 400
5c56be9a
DB
401 if (do_rapl && !rapl_joules) {
402 if (do_rapl & RAPL_PKG)
3d109de2 403 outp += sprintf(outp, "\tPkgWatt");
9148494c 404 if (do_rapl & RAPL_CORES_ENERGY_STATUS)
3d109de2 405 outp += sprintf(outp, "\tCorWatt");
5c56be9a 406 if (do_rapl & RAPL_GFX)
3d109de2 407 outp += sprintf(outp, "\tGFXWatt");
5c56be9a 408 if (do_rapl & RAPL_DRAM)
3d109de2 409 outp += sprintf(outp, "\tRAMWatt");
5c56be9a 410 if (do_rapl & RAPL_PKG_PERF_STATUS)
3d109de2 411 outp += sprintf(outp, "\tPKG_%%");
5c56be9a 412 if (do_rapl & RAPL_DRAM_PERF_STATUS)
3d109de2 413 outp += sprintf(outp, "\tRAM_%%");
d7899447 414 } else if (do_rapl && rapl_joules) {
5c56be9a 415 if (do_rapl & RAPL_PKG)
3d109de2 416 outp += sprintf(outp, "\tPkg_J");
9148494c 417 if (do_rapl & RAPL_CORES_ENERGY_STATUS)
3d109de2 418 outp += sprintf(outp, "\tCor_J");
5c56be9a 419 if (do_rapl & RAPL_GFX)
3d109de2 420 outp += sprintf(outp, "\tGFX_J");
5c56be9a 421 if (do_rapl & RAPL_DRAM)
3d109de2 422 outp += sprintf(outp, "\tRAM_J");
5c56be9a 423 if (do_rapl & RAPL_PKG_PERF_STATUS)
3d109de2 424 outp += sprintf(outp, "\tPKG_%%");
5c56be9a 425 if (do_rapl & RAPL_DRAM_PERF_STATUS)
3d109de2 426 outp += sprintf(outp, "\tRAM_%%");
5c56be9a 427 }
1cc21f7b 428 done:
c98d5d94 429 outp += sprintf(outp, "\n");
103a8fea
LB
430}
431
c98d5d94
LB
432int dump_counters(struct thread_data *t, struct core_data *c,
433 struct pkg_data *p)
103a8fea 434{
3b4d5c7f 435 outp += sprintf(outp, "t %p, c %p, p %p\n", t, c, p);
c98d5d94
LB
436
437 if (t) {
3b4d5c7f
AS
438 outp += sprintf(outp, "CPU: %d flags 0x%x\n",
439 t->cpu_id, t->flags);
440 outp += sprintf(outp, "TSC: %016llX\n", t->tsc);
441 outp += sprintf(outp, "aperf: %016llX\n", t->aperf);
442 outp += sprintf(outp, "mperf: %016llX\n", t->mperf);
443 outp += sprintf(outp, "c1: %016llX\n", t->c1);
444 outp += sprintf(outp, "msr0x%x: %08llX\n",
8e180f3c 445 extra_delta_offset32, t->extra_delta32);
3b4d5c7f 446 outp += sprintf(outp, "msr0x%x: %016llX\n",
8e180f3c 447 extra_delta_offset64, t->extra_delta64);
3b4d5c7f 448 outp += sprintf(outp, "msr0x%x: %08llX\n",
2f32edf1 449 extra_msr_offset32, t->extra_msr32);
3b4d5c7f 450 outp += sprintf(outp, "msr0x%x: %016llX\n",
2f32edf1 451 extra_msr_offset64, t->extra_msr64);
562a2d37
LB
452 if (do_irq)
453 outp += sprintf(outp, "IRQ: %08X\n", t->irq_count);
1ed51011 454 if (do_smi)
3b4d5c7f 455 outp += sprintf(outp, "SMI: %08X\n", t->smi_count);
c98d5d94 456 }
103a8fea 457
c98d5d94 458 if (c) {
3b4d5c7f
AS
459 outp += sprintf(outp, "core: %d\n", c->core_id);
460 outp += sprintf(outp, "c3: %016llX\n", c->c3);
461 outp += sprintf(outp, "c6: %016llX\n", c->c6);
462 outp += sprintf(outp, "c7: %016llX\n", c->c7);
463 outp += sprintf(outp, "DTS: %dC\n", c->core_temp_c);
c98d5d94 464 }
103a8fea 465
c98d5d94 466 if (p) {
3b4d5c7f 467 outp += sprintf(outp, "package: %d\n", p->package_id);
0b2bb692
LB
468
469 outp += sprintf(outp, "Weighted cores: %016llX\n", p->pkg_wtd_core_c0);
470 outp += sprintf(outp, "Any cores: %016llX\n", p->pkg_any_core_c0);
471 outp += sprintf(outp, "Any GFX: %016llX\n", p->pkg_any_gfxe_c0);
472 outp += sprintf(outp, "CPU + GFX: %016llX\n", p->pkg_both_core_gfxe_c0);
473
3b4d5c7f 474 outp += sprintf(outp, "pc2: %016llX\n", p->pc2);
ee7e38e3
LB
475 if (do_pc3)
476 outp += sprintf(outp, "pc3: %016llX\n", p->pc3);
477 if (do_pc6)
478 outp += sprintf(outp, "pc6: %016llX\n", p->pc6);
479 if (do_pc7)
480 outp += sprintf(outp, "pc7: %016llX\n", p->pc7);
3b4d5c7f
AS
481 outp += sprintf(outp, "pc8: %016llX\n", p->pc8);
482 outp += sprintf(outp, "pc9: %016llX\n", p->pc9);
483 outp += sprintf(outp, "pc10: %016llX\n", p->pc10);
484 outp += sprintf(outp, "Joules PKG: %0X\n", p->energy_pkg);
485 outp += sprintf(outp, "Joules COR: %0X\n", p->energy_cores);
486 outp += sprintf(outp, "Joules GFX: %0X\n", p->energy_gfx);
487 outp += sprintf(outp, "Joules RAM: %0X\n", p->energy_dram);
488 outp += sprintf(outp, "Throttle PKG: %0X\n",
489 p->rapl_pkg_perf_status);
490 outp += sprintf(outp, "Throttle RAM: %0X\n",
491 p->rapl_dram_perf_status);
492 outp += sprintf(outp, "PTM: %dC\n", p->pkg_temp_c);
c98d5d94 493 }
3b4d5c7f
AS
494
495 outp += sprintf(outp, "\n");
496
c98d5d94 497 return 0;
103a8fea
LB
498}
499
e23da037
LB
500/*
501 * column formatting convention & formats
e23da037 502 */
c98d5d94
LB
503int format_counters(struct thread_data *t, struct core_data *c,
504 struct pkg_data *p)
103a8fea
LB
505{
506 double interval_float;
fc04cc67 507 char *fmt8;
103a8fea 508
c98d5d94
LB
509 /* if showing only 1st thread in core and this isn't one, bail out */
510 if (show_core_only && !(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
511 return 0;
512
513 /* if showing only 1st thread in pkg and this isn't one, bail out */
514 if (show_pkg_only && !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
515 return 0;
516
103a8fea
LB
517 interval_float = tv_delta.tv_sec + tv_delta.tv_usec/1000000.0;
518
c98d5d94
LB
519 /* topo columns, print blanks on 1st (average) line */
520 if (t == &average.threads) {
103a8fea 521 if (show_pkg)
3d109de2 522 outp += sprintf(outp, "\t-");
103a8fea 523 if (show_core)
3d109de2 524 outp += sprintf(outp, "\t-");
103a8fea 525 if (show_cpu)
3d109de2 526 outp += sprintf(outp, "\t-");
103a8fea 527 } else {
c98d5d94
LB
528 if (show_pkg) {
529 if (p)
3d109de2 530 outp += sprintf(outp, "\t%d", p->package_id);
c98d5d94 531 else
3d109de2 532 outp += sprintf(outp, "\t-");
c98d5d94 533 }
c98d5d94
LB
534 if (show_core) {
535 if (c)
3d109de2 536 outp += sprintf(outp, "\t%d", c->core_id);
c98d5d94 537 else
3d109de2 538 outp += sprintf(outp, "\t-");
c98d5d94 539 }
103a8fea 540 if (show_cpu)
3d109de2 541 outp += sprintf(outp, "\t%d", t->cpu_id);
103a8fea 542 }
fc04cc67 543
d7899447 544 /* Avg_MHz */
fc04cc67 545 if (has_aperf)
3d109de2 546 outp += sprintf(outp, "\t%.0f",
fc04cc67
LB
547 1.0 / units * t->aperf / interval_float);
548
75d2e44e 549 /* Busy% */
ba3dec99 550 if (has_aperf)
3d109de2 551 outp += sprintf(outp, "\t%.2f", 100.0 * t->mperf/t->tsc/tsc_tweak);
103a8fea 552
d7899447 553 /* Bzy_MHz */
21ed5574
LB
554 if (has_aperf) {
555 if (has_base_hz)
3d109de2 556 outp += sprintf(outp, "\t%.0f", base_hz / units * t->aperf / t->mperf);
21ed5574 557 else
3d109de2 558 outp += sprintf(outp, "\t%.0f",
21ed5574
LB
559 1.0 * t->tsc / units * t->aperf / t->mperf / interval_float);
560 }
103a8fea 561
d7899447 562 /* TSC_MHz */
3d109de2 563 outp += sprintf(outp, "\t%.0f", 1.0 * t->tsc/units/interval_float);
103a8fea 564
8e180f3c
LB
565 /* delta */
566 if (extra_delta_offset32)
3d109de2 567 outp += sprintf(outp, "\t%11llu", t->extra_delta32);
8e180f3c
LB
568
569 /* DELTA */
570 if (extra_delta_offset64)
3d109de2 571 outp += sprintf(outp, "\t%11llu", t->extra_delta64);
2f32edf1
LB
572 /* msr */
573 if (extra_msr_offset32)
3d109de2 574 outp += sprintf(outp, "\t0x%08llx", t->extra_msr32);
2f32edf1 575
130ff304 576 /* MSR */
2f32edf1 577 if (extra_msr_offset64)
3d109de2 578 outp += sprintf(outp, "\t0x%016llx", t->extra_msr64);
130ff304 579
1cc21f7b
LB
580 if (!debug)
581 goto done;
582
562a2d37
LB
583 /* IRQ */
584 if (do_irq)
3d109de2 585 outp += sprintf(outp, "\t%d", t->irq_count);
562a2d37 586
1cc21f7b
LB
587 /* SMI */
588 if (do_smi)
3d109de2 589 outp += sprintf(outp, "\t%d", t->smi_count);
1cc21f7b 590
ba3dec99 591 if (do_nhm_cstates)
3d109de2 592 outp += sprintf(outp, "\t%.2f", 100.0 * t->c1/t->tsc);
c98d5d94
LB
593
594 /* print per-core data only for 1st thread in core */
595 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
596 goto done;
597
fb5d4327 598 if (do_nhm_cstates && !do_slm_cstates && !do_knl_cstates)
3d109de2 599 outp += sprintf(outp, "\t%.2f", 100.0 * c->c3/t->tsc);
103a8fea 600 if (do_nhm_cstates)
3d109de2 601 outp += sprintf(outp, "\t%.2f", 100.0 * c->c6/t->tsc);
103a8fea 602 if (do_snb_cstates)
3d109de2 603 outp += sprintf(outp, "\t%.2f", 100.0 * c->c7/t->tsc);
c98d5d94 604
889facbe 605 if (do_dts)
3d109de2 606 outp += sprintf(outp, "\t%d", c->core_temp_c);
889facbe 607
c98d5d94
LB
608 /* print per-package data only for 1st core in package */
609 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
610 goto done;
611
0b2bb692 612 /* PkgTmp */
889facbe 613 if (do_ptm)
3d109de2 614 outp += sprintf(outp, "\t%d", p->pkg_temp_c);
889facbe 615
fdf676e5 616 /* GFXrc6 */
9185e988 617 if (do_gfx_rc6_ms) {
ba3dec99 618 if (p->gfx_rc6_ms == -1) { /* detect GFX counter reset */
3d109de2 619 outp += sprintf(outp, "\t**.**");
9185e988 620 } else {
3d109de2 621 outp += sprintf(outp, "\t%.2f",
9185e988
LB
622 p->gfx_rc6_ms / 10.0 / interval_float);
623 }
624 }
fdf676e5 625
27d47356
LB
626 /* GFXMHz */
627 if (do_gfx_mhz)
3d109de2 628 outp += sprintf(outp, "\t%d", p->gfx_mhz);
27d47356 629
0b2bb692
LB
630 /* Totl%C0, Any%C0 GFX%C0 CPUGFX% */
631 if (do_skl_residency) {
3d109de2
LB
632 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_wtd_core_c0/t->tsc);
633 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_any_core_c0/t->tsc);
634 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_any_gfxe_c0/t->tsc);
635 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_both_core_gfxe_c0/t->tsc);
0b2bb692
LB
636 }
637
ee7e38e3 638 if (do_pc2)
3d109de2 639 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc2/t->tsc);
ee7e38e3 640 if (do_pc3)
3d109de2 641 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc3/t->tsc);
ee7e38e3 642 if (do_pc6)
3d109de2 643 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc6/t->tsc);
ee7e38e3 644 if (do_pc7)
3d109de2 645 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc7/t->tsc);
ca58710f 646 if (do_c8_c9_c10) {
3d109de2
LB
647 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc8/t->tsc);
648 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc9/t->tsc);
649 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc10/t->tsc);
ca58710f 650 }
889facbe
LB
651
652 /*
653 * If measurement interval exceeds minimum RAPL Joule Counter range,
654 * indicate that results are suspect by printing "**" in fraction place.
655 */
fc04cc67 656 if (interval_float < rapl_joule_counter_range)
3d109de2 657 fmt8 = "\t%.2f";
fc04cc67 658 else
e975db5d 659 fmt8 = "%6.0f**";
889facbe 660
5c56be9a
DB
661 if (do_rapl && !rapl_joules) {
662 if (do_rapl & RAPL_PKG)
fc04cc67 663 outp += sprintf(outp, fmt8, p->energy_pkg * rapl_energy_units / interval_float);
9148494c 664 if (do_rapl & RAPL_CORES_ENERGY_STATUS)
fc04cc67 665 outp += sprintf(outp, fmt8, p->energy_cores * rapl_energy_units / interval_float);
5c56be9a 666 if (do_rapl & RAPL_GFX)
fc04cc67 667 outp += sprintf(outp, fmt8, p->energy_gfx * rapl_energy_units / interval_float);
5c56be9a 668 if (do_rapl & RAPL_DRAM)
40ee8e3b 669 outp += sprintf(outp, fmt8, p->energy_dram * rapl_dram_energy_units / interval_float);
5c56be9a 670 if (do_rapl & RAPL_PKG_PERF_STATUS)
fc04cc67 671 outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
5c56be9a 672 if (do_rapl & RAPL_DRAM_PERF_STATUS)
fc04cc67 673 outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
d7899447 674 } else if (do_rapl && rapl_joules) {
5c56be9a 675 if (do_rapl & RAPL_PKG)
fc04cc67 676 outp += sprintf(outp, fmt8,
5c56be9a
DB
677 p->energy_pkg * rapl_energy_units);
678 if (do_rapl & RAPL_CORES)
fc04cc67 679 outp += sprintf(outp, fmt8,
5c56be9a
DB
680 p->energy_cores * rapl_energy_units);
681 if (do_rapl & RAPL_GFX)
fc04cc67 682 outp += sprintf(outp, fmt8,
5c56be9a
DB
683 p->energy_gfx * rapl_energy_units);
684 if (do_rapl & RAPL_DRAM)
fc04cc67 685 outp += sprintf(outp, fmt8,
40ee8e3b 686 p->energy_dram * rapl_dram_energy_units);
5c56be9a 687 if (do_rapl & RAPL_PKG_PERF_STATUS)
fc04cc67 688 outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
5c56be9a 689 if (do_rapl & RAPL_DRAM_PERF_STATUS)
fc04cc67 690 outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
5c56be9a 691 }
c98d5d94 692done:
c98d5d94
LB
693 outp += sprintf(outp, "\n");
694
695 return 0;
103a8fea
LB
696}
697
b7d8c148 698void flush_output_stdout(void)
c98d5d94 699{
b7d8c148
LB
700 FILE *filep;
701
702 if (outf == stderr)
703 filep = stdout;
704 else
705 filep = outf;
706
707 fputs(output_buffer, filep);
708 fflush(filep);
709
c98d5d94
LB
710 outp = output_buffer;
711}
b7d8c148 712void flush_output_stderr(void)
c98d5d94 713{
b7d8c148
LB
714 fputs(output_buffer, outf);
715 fflush(outf);
c98d5d94
LB
716 outp = output_buffer;
717}
718void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
103a8fea 719{
e23da037 720 static int printed;
103a8fea 721
e23da037
LB
722 if (!printed || !summary_only)
723 print_header();
103a8fea 724
c98d5d94
LB
725 if (topo.num_cpus > 1)
726 format_counters(&average.threads, &average.cores,
727 &average.packages);
103a8fea 728
e23da037
LB
729 printed = 1;
730
731 if (summary_only)
732 return;
733
c98d5d94 734 for_all_cpus(format_counters, t, c, p);
103a8fea
LB
735}
736
889facbe
LB
737#define DELTA_WRAP32(new, old) \
738 if (new > old) { \
739 old = new - old; \
740 } else { \
741 old = 0x100000000 + new - old; \
742 }
743
ba3dec99 744int
c98d5d94
LB
745delta_package(struct pkg_data *new, struct pkg_data *old)
746{
0b2bb692
LB
747
748 if (do_skl_residency) {
749 old->pkg_wtd_core_c0 = new->pkg_wtd_core_c0 - old->pkg_wtd_core_c0;
750 old->pkg_any_core_c0 = new->pkg_any_core_c0 - old->pkg_any_core_c0;
751 old->pkg_any_gfxe_c0 = new->pkg_any_gfxe_c0 - old->pkg_any_gfxe_c0;
752 old->pkg_both_core_gfxe_c0 = new->pkg_both_core_gfxe_c0 - old->pkg_both_core_gfxe_c0;
753 }
c98d5d94 754 old->pc2 = new->pc2 - old->pc2;
ee7e38e3
LB
755 if (do_pc3)
756 old->pc3 = new->pc3 - old->pc3;
757 if (do_pc6)
758 old->pc6 = new->pc6 - old->pc6;
759 if (do_pc7)
760 old->pc7 = new->pc7 - old->pc7;
ca58710f
KCA
761 old->pc8 = new->pc8 - old->pc8;
762 old->pc9 = new->pc9 - old->pc9;
763 old->pc10 = new->pc10 - old->pc10;
889facbe
LB
764 old->pkg_temp_c = new->pkg_temp_c;
765
9185e988
LB
766 /* flag an error when rc6 counter resets/wraps */
767 if (old->gfx_rc6_ms > new->gfx_rc6_ms)
768 old->gfx_rc6_ms = -1;
769 else
770 old->gfx_rc6_ms = new->gfx_rc6_ms - old->gfx_rc6_ms;
771
27d47356
LB
772 old->gfx_mhz = new->gfx_mhz;
773
889facbe
LB
774 DELTA_WRAP32(new->energy_pkg, old->energy_pkg);
775 DELTA_WRAP32(new->energy_cores, old->energy_cores);
776 DELTA_WRAP32(new->energy_gfx, old->energy_gfx);
777 DELTA_WRAP32(new->energy_dram, old->energy_dram);
778 DELTA_WRAP32(new->rapl_pkg_perf_status, old->rapl_pkg_perf_status);
779 DELTA_WRAP32(new->rapl_dram_perf_status, old->rapl_dram_perf_status);
ba3dec99
LB
780
781 return 0;
c98d5d94 782}
103a8fea 783
c98d5d94
LB
784void
785delta_core(struct core_data *new, struct core_data *old)
103a8fea 786{
c98d5d94
LB
787 old->c3 = new->c3 - old->c3;
788 old->c6 = new->c6 - old->c6;
789 old->c7 = new->c7 - old->c7;
889facbe 790 old->core_temp_c = new->core_temp_c;
c98d5d94 791}
103a8fea 792
c3ae331d
LB
793/*
794 * old = new - old
795 */
ba3dec99 796int
c98d5d94
LB
797delta_thread(struct thread_data *new, struct thread_data *old,
798 struct core_data *core_delta)
799{
800 old->tsc = new->tsc - old->tsc;
801
802 /* check for TSC < 1 Mcycles over interval */
b2c95d90
JT
803 if (old->tsc < (1000 * 1000))
804 errx(-3, "Insanely slow TSC rate, TSC stops in idle?\n"
805 "You can disable all c-states by booting with \"idle=poll\"\n"
806 "or just the deep ones with \"processor.max_cstate=1\"");
103a8fea 807
c98d5d94 808 old->c1 = new->c1 - old->c1;
103a8fea 809
a729617c
LB
810 if (has_aperf) {
811 if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) {
812 old->aperf = new->aperf - old->aperf;
813 old->mperf = new->mperf - old->mperf;
814 } else {
ba3dec99 815 return -1;
103a8fea 816 }
c98d5d94 817 }
103a8fea 818
103a8fea 819
144b44b1
LB
820 if (use_c1_residency_msr) {
821 /*
822 * Some models have a dedicated C1 residency MSR,
823 * which should be more accurate than the derivation below.
824 */
825 } else {
826 /*
827 * As counter collection is not atomic,
828 * it is possible for mperf's non-halted cycles + idle states
829 * to exceed TSC's all cycles: show c1 = 0% in that case.
830 */
831 if ((old->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > old->tsc)
832 old->c1 = 0;
833 else {
834 /* normal case, derive c1 */
835 old->c1 = old->tsc - old->mperf - core_delta->c3
c98d5d94 836 - core_delta->c6 - core_delta->c7;
144b44b1 837 }
c98d5d94 838 }
c3ae331d 839
c98d5d94 840 if (old->mperf == 0) {
b7d8c148
LB
841 if (debug > 1)
842 fprintf(outf, "cpu%d MPERF 0!\n", old->cpu_id);
c98d5d94 843 old->mperf = 1; /* divide by 0 protection */
103a8fea 844 }
c98d5d94 845
8e180f3c
LB
846 old->extra_delta32 = new->extra_delta32 - old->extra_delta32;
847 old->extra_delta32 &= 0xFFFFFFFF;
848
849 old->extra_delta64 = new->extra_delta64 - old->extra_delta64;
850
c98d5d94 851 /*
8e180f3c 852 * Extra MSR is just a snapshot, simply copy latest w/o subtracting
c98d5d94 853 */
2f32edf1
LB
854 old->extra_msr32 = new->extra_msr32;
855 old->extra_msr64 = new->extra_msr64;
1ed51011 856
562a2d37
LB
857 if (do_irq)
858 old->irq_count = new->irq_count - old->irq_count;
859
1ed51011
LB
860 if (do_smi)
861 old->smi_count = new->smi_count - old->smi_count;
ba3dec99
LB
862
863 return 0;
c98d5d94
LB
864}
865
866int delta_cpu(struct thread_data *t, struct core_data *c,
867 struct pkg_data *p, struct thread_data *t2,
868 struct core_data *c2, struct pkg_data *p2)
869{
ba3dec99
LB
870 int retval = 0;
871
c98d5d94
LB
872 /* calculate core delta only for 1st thread in core */
873 if (t->flags & CPU_IS_FIRST_THREAD_IN_CORE)
874 delta_core(c, c2);
875
876 /* always calculate thread delta */
ba3dec99
LB
877 retval = delta_thread(t, t2, c2); /* c2 is core delta */
878 if (retval)
879 return retval;
c98d5d94
LB
880
881 /* calculate package delta only for 1st core in package */
882 if (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)
ba3dec99 883 retval = delta_package(p, p2);
c98d5d94 884
ba3dec99 885 return retval;
103a8fea
LB
886}
887
c98d5d94
LB
888void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
889{
890 t->tsc = 0;
891 t->aperf = 0;
892 t->mperf = 0;
893 t->c1 = 0;
894
8e180f3c
LB
895 t->extra_delta32 = 0;
896 t->extra_delta64 = 0;
897
562a2d37
LB
898 t->irq_count = 0;
899 t->smi_count = 0;
900
c98d5d94
LB
901 /* tells format_counters to dump all fields from this set */
902 t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE;
903
904 c->c3 = 0;
905 c->c6 = 0;
906 c->c7 = 0;
889facbe 907 c->core_temp_c = 0;
c98d5d94 908
0b2bb692
LB
909 p->pkg_wtd_core_c0 = 0;
910 p->pkg_any_core_c0 = 0;
911 p->pkg_any_gfxe_c0 = 0;
912 p->pkg_both_core_gfxe_c0 = 0;
913
c98d5d94 914 p->pc2 = 0;
ee7e38e3
LB
915 if (do_pc3)
916 p->pc3 = 0;
917 if (do_pc6)
918 p->pc6 = 0;
919 if (do_pc7)
920 p->pc7 = 0;
ca58710f
KCA
921 p->pc8 = 0;
922 p->pc9 = 0;
923 p->pc10 = 0;
889facbe
LB
924
925 p->energy_pkg = 0;
926 p->energy_dram = 0;
927 p->energy_cores = 0;
928 p->energy_gfx = 0;
929 p->rapl_pkg_perf_status = 0;
930 p->rapl_dram_perf_status = 0;
931 p->pkg_temp_c = 0;
27d47356 932
fdf676e5 933 p->gfx_rc6_ms = 0;
27d47356 934 p->gfx_mhz = 0;
c98d5d94
LB
935}
936int sum_counters(struct thread_data *t, struct core_data *c,
937 struct pkg_data *p)
103a8fea 938{
c98d5d94
LB
939 average.threads.tsc += t->tsc;
940 average.threads.aperf += t->aperf;
941 average.threads.mperf += t->mperf;
942 average.threads.c1 += t->c1;
103a8fea 943
8e180f3c
LB
944 average.threads.extra_delta32 += t->extra_delta32;
945 average.threads.extra_delta64 += t->extra_delta64;
946
562a2d37
LB
947 average.threads.irq_count += t->irq_count;
948 average.threads.smi_count += t->smi_count;
949
c98d5d94
LB
950 /* sum per-core values only for 1st thread in core */
951 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
952 return 0;
103a8fea 953
c98d5d94
LB
954 average.cores.c3 += c->c3;
955 average.cores.c6 += c->c6;
956 average.cores.c7 += c->c7;
957
889facbe
LB
958 average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c);
959
c98d5d94
LB
960 /* sum per-pkg values only for 1st core in pkg */
961 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
962 return 0;
963
0b2bb692
LB
964 if (do_skl_residency) {
965 average.packages.pkg_wtd_core_c0 += p->pkg_wtd_core_c0;
966 average.packages.pkg_any_core_c0 += p->pkg_any_core_c0;
967 average.packages.pkg_any_gfxe_c0 += p->pkg_any_gfxe_c0;
968 average.packages.pkg_both_core_gfxe_c0 += p->pkg_both_core_gfxe_c0;
969 }
970
c98d5d94 971 average.packages.pc2 += p->pc2;
ee7e38e3
LB
972 if (do_pc3)
973 average.packages.pc3 += p->pc3;
974 if (do_pc6)
975 average.packages.pc6 += p->pc6;
976 if (do_pc7)
977 average.packages.pc7 += p->pc7;
ca58710f
KCA
978 average.packages.pc8 += p->pc8;
979 average.packages.pc9 += p->pc9;
980 average.packages.pc10 += p->pc10;
c98d5d94 981
889facbe
LB
982 average.packages.energy_pkg += p->energy_pkg;
983 average.packages.energy_dram += p->energy_dram;
984 average.packages.energy_cores += p->energy_cores;
985 average.packages.energy_gfx += p->energy_gfx;
986
fdf676e5 987 average.packages.gfx_rc6_ms = p->gfx_rc6_ms;
27d47356
LB
988 average.packages.gfx_mhz = p->gfx_mhz;
989
889facbe
LB
990 average.packages.pkg_temp_c = MAX(average.packages.pkg_temp_c, p->pkg_temp_c);
991
992 average.packages.rapl_pkg_perf_status += p->rapl_pkg_perf_status;
993 average.packages.rapl_dram_perf_status += p->rapl_dram_perf_status;
c98d5d94
LB
994 return 0;
995}
996/*
997 * sum the counters for all cpus in the system
998 * compute the weighted average
999 */
1000void compute_average(struct thread_data *t, struct core_data *c,
1001 struct pkg_data *p)
1002{
1003 clear_counters(&average.threads, &average.cores, &average.packages);
1004
1005 for_all_cpus(sum_counters, t, c, p);
1006
1007 average.threads.tsc /= topo.num_cpus;
1008 average.threads.aperf /= topo.num_cpus;
1009 average.threads.mperf /= topo.num_cpus;
1010 average.threads.c1 /= topo.num_cpus;
1011
8e180f3c
LB
1012 average.threads.extra_delta32 /= topo.num_cpus;
1013 average.threads.extra_delta32 &= 0xFFFFFFFF;
1014
1015 average.threads.extra_delta64 /= topo.num_cpus;
1016
c98d5d94
LB
1017 average.cores.c3 /= topo.num_cores;
1018 average.cores.c6 /= topo.num_cores;
1019 average.cores.c7 /= topo.num_cores;
1020
0b2bb692
LB
1021 if (do_skl_residency) {
1022 average.packages.pkg_wtd_core_c0 /= topo.num_packages;
1023 average.packages.pkg_any_core_c0 /= topo.num_packages;
1024 average.packages.pkg_any_gfxe_c0 /= topo.num_packages;
1025 average.packages.pkg_both_core_gfxe_c0 /= topo.num_packages;
1026 }
1027
c98d5d94 1028 average.packages.pc2 /= topo.num_packages;
ee7e38e3
LB
1029 if (do_pc3)
1030 average.packages.pc3 /= topo.num_packages;
1031 if (do_pc6)
1032 average.packages.pc6 /= topo.num_packages;
1033 if (do_pc7)
1034 average.packages.pc7 /= topo.num_packages;
ca58710f
KCA
1035
1036 average.packages.pc8 /= topo.num_packages;
1037 average.packages.pc9 /= topo.num_packages;
1038 average.packages.pc10 /= topo.num_packages;
103a8fea
LB
1039}
1040
c98d5d94 1041static unsigned long long rdtsc(void)
103a8fea 1042{
c98d5d94 1043 unsigned int low, high;
15aaa346 1044
c98d5d94 1045 asm volatile("rdtsc" : "=a" (low), "=d" (high));
15aaa346 1046
c98d5d94
LB
1047 return low | ((unsigned long long)high) << 32;
1048}
15aaa346 1049
c98d5d94
LB
1050/*
1051 * get_counters(...)
1052 * migrate to cpu
1053 * acquire and record local counters for that cpu
1054 */
1055int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1056{
1057 int cpu = t->cpu_id;
889facbe 1058 unsigned long long msr;
0102b067 1059 int aperf_mperf_retry_count = 0;
88c3281f 1060
e52966c0 1061 if (cpu_migrate(cpu)) {
b7d8c148 1062 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
c98d5d94 1063 return -1;
e52966c0 1064 }
15aaa346 1065
0102b067 1066retry:
c98d5d94
LB
1067 t->tsc = rdtsc(); /* we are running on local CPU of interest */
1068
1069 if (has_aperf) {
0102b067
LB
1070 unsigned long long tsc_before, tsc_between, tsc_after, aperf_time, mperf_time;
1071
1072 /*
1073 * The TSC, APERF and MPERF must be read together for
1074 * APERF/MPERF and MPERF/TSC to give accurate results.
1075 *
1076 * Unfortunately, APERF and MPERF are read by
1077 * individual system call, so delays may occur
1078 * between them. If the time to read them
1079 * varies by a large amount, we re-read them.
1080 */
1081
1082 /*
1083 * This initial dummy APERF read has been seen to
1084 * reduce jitter in the subsequent reads.
1085 */
1086
1087 if (get_msr(cpu, MSR_IA32_APERF, &t->aperf))
1088 return -3;
1089
1090 t->tsc = rdtsc(); /* re-read close to APERF */
1091
1092 tsc_before = t->tsc;
1093
9c63a650 1094 if (get_msr(cpu, MSR_IA32_APERF, &t->aperf))
c98d5d94 1095 return -3;
0102b067
LB
1096
1097 tsc_between = rdtsc();
1098
9c63a650 1099 if (get_msr(cpu, MSR_IA32_MPERF, &t->mperf))
c98d5d94 1100 return -4;
0102b067
LB
1101
1102 tsc_after = rdtsc();
1103
1104 aperf_time = tsc_between - tsc_before;
1105 mperf_time = tsc_after - tsc_between;
1106
1107 /*
1108 * If the system call latency to read APERF and MPERF
1109 * differ by more than 2x, then try again.
1110 */
1111 if ((aperf_time > (2 * mperf_time)) || (mperf_time > (2 * aperf_time))) {
1112 aperf_mperf_retry_count++;
1113 if (aperf_mperf_retry_count < 5)
1114 goto retry;
1115 else
1116 warnx("cpu%d jitter %lld %lld",
1117 cpu, aperf_time, mperf_time);
1118 }
1119 aperf_mperf_retry_count = 0;
1120
b2b34dfe
HC
1121 t->aperf = t->aperf * aperf_mperf_multiplier;
1122 t->mperf = t->mperf * aperf_mperf_multiplier;
c98d5d94
LB
1123 }
1124
562a2d37
LB
1125 if (do_irq)
1126 t->irq_count = irqs_per_cpu[cpu];
1ed51011
LB
1127 if (do_smi) {
1128 if (get_msr(cpu, MSR_SMI_COUNT, &msr))
1129 return -5;
1130 t->smi_count = msr & 0xFFFFFFFF;
1131 }
8e180f3c 1132 if (extra_delta_offset32) {
889facbe 1133 if (get_msr(cpu, extra_delta_offset32, &msr))
8e180f3c 1134 return -5;
889facbe 1135 t->extra_delta32 = msr & 0xFFFFFFFF;
8e180f3c
LB
1136 }
1137
1138 if (extra_delta_offset64)
1139 if (get_msr(cpu, extra_delta_offset64, &t->extra_delta64))
2f32edf1
LB
1140 return -5;
1141
8e180f3c 1142 if (extra_msr_offset32) {
889facbe 1143 if (get_msr(cpu, extra_msr_offset32, &msr))
8e180f3c 1144 return -5;
889facbe 1145 t->extra_msr32 = msr & 0xFFFFFFFF;
8e180f3c
LB
1146 }
1147
2f32edf1
LB
1148 if (extra_msr_offset64)
1149 if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64))
c98d5d94
LB
1150 return -5;
1151
144b44b1
LB
1152 if (use_c1_residency_msr) {
1153 if (get_msr(cpu, MSR_CORE_C1_RES, &t->c1))
1154 return -6;
1155 }
1156
c98d5d94
LB
1157 /* collect core counters only for 1st thread in core */
1158 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
1159 return 0;
1160
fb5d4327 1161 if (do_nhm_cstates && !do_slm_cstates && !do_knl_cstates) {
c98d5d94
LB
1162 if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3))
1163 return -6;
144b44b1
LB
1164 }
1165
fb5d4327 1166 if (do_nhm_cstates && !do_knl_cstates) {
c98d5d94
LB
1167 if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6))
1168 return -7;
fb5d4327
DC
1169 } else if (do_knl_cstates) {
1170 if (get_msr(cpu, MSR_KNL_CORE_C6_RESIDENCY, &c->c6))
1171 return -7;
c98d5d94
LB
1172 }
1173
1174 if (do_snb_cstates)
1175 if (get_msr(cpu, MSR_CORE_C7_RESIDENCY, &c->c7))
1176 return -8;
1177
889facbe
LB
1178 if (do_dts) {
1179 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
1180 return -9;
1181 c->core_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F);
1182 }
1183
1184
c98d5d94
LB
1185 /* collect package counters only for 1st core in package */
1186 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
1187 return 0;
1188
0b2bb692
LB
1189 if (do_skl_residency) {
1190 if (get_msr(cpu, MSR_PKG_WEIGHTED_CORE_C0_RES, &p->pkg_wtd_core_c0))
1191 return -10;
1192 if (get_msr(cpu, MSR_PKG_ANY_CORE_C0_RES, &p->pkg_any_core_c0))
1193 return -11;
1194 if (get_msr(cpu, MSR_PKG_ANY_GFXE_C0_RES, &p->pkg_any_gfxe_c0))
1195 return -12;
1196 if (get_msr(cpu, MSR_PKG_BOTH_CORE_GFXE_C0_RES, &p->pkg_both_core_gfxe_c0))
1197 return -13;
1198 }
ee7e38e3 1199 if (do_pc3)
c98d5d94
LB
1200 if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3))
1201 return -9;
ee7e38e3 1202 if (do_pc6)
c98d5d94
LB
1203 if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6))
1204 return -10;
ee7e38e3 1205 if (do_pc2)
c98d5d94
LB
1206 if (get_msr(cpu, MSR_PKG_C2_RESIDENCY, &p->pc2))
1207 return -11;
ee7e38e3 1208 if (do_pc7)
c98d5d94
LB
1209 if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7))
1210 return -12;
ca58710f
KCA
1211 if (do_c8_c9_c10) {
1212 if (get_msr(cpu, MSR_PKG_C8_RESIDENCY, &p->pc8))
1213 return -13;
1214 if (get_msr(cpu, MSR_PKG_C9_RESIDENCY, &p->pc9))
1215 return -13;
1216 if (get_msr(cpu, MSR_PKG_C10_RESIDENCY, &p->pc10))
1217 return -13;
1218 }
889facbe
LB
1219 if (do_rapl & RAPL_PKG) {
1220 if (get_msr(cpu, MSR_PKG_ENERGY_STATUS, &msr))
1221 return -13;
1222 p->energy_pkg = msr & 0xFFFFFFFF;
1223 }
9148494c 1224 if (do_rapl & RAPL_CORES_ENERGY_STATUS) {
889facbe
LB
1225 if (get_msr(cpu, MSR_PP0_ENERGY_STATUS, &msr))
1226 return -14;
1227 p->energy_cores = msr & 0xFFFFFFFF;
1228 }
1229 if (do_rapl & RAPL_DRAM) {
1230 if (get_msr(cpu, MSR_DRAM_ENERGY_STATUS, &msr))
1231 return -15;
1232 p->energy_dram = msr & 0xFFFFFFFF;
1233 }
1234 if (do_rapl & RAPL_GFX) {
1235 if (get_msr(cpu, MSR_PP1_ENERGY_STATUS, &msr))
1236 return -16;
1237 p->energy_gfx = msr & 0xFFFFFFFF;
1238 }
1239 if (do_rapl & RAPL_PKG_PERF_STATUS) {
1240 if (get_msr(cpu, MSR_PKG_PERF_STATUS, &msr))
1241 return -16;
1242 p->rapl_pkg_perf_status = msr & 0xFFFFFFFF;
1243 }
1244 if (do_rapl & RAPL_DRAM_PERF_STATUS) {
1245 if (get_msr(cpu, MSR_DRAM_PERF_STATUS, &msr))
1246 return -16;
1247 p->rapl_dram_perf_status = msr & 0xFFFFFFFF;
1248 }
1249 if (do_ptm) {
1250 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
1251 return -17;
1252 p->pkg_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F);
1253 }
fdf676e5
LB
1254
1255 if (do_gfx_rc6_ms)
1256 p->gfx_rc6_ms = gfx_cur_rc6_ms;
1257
27d47356
LB
1258 if (do_gfx_mhz)
1259 p->gfx_mhz = gfx_cur_mhz;
1260
15aaa346 1261 return 0;
103a8fea
LB
1262}
1263
ee7e38e3
LB
1264/*
1265 * MSR_PKG_CST_CONFIG_CONTROL decoding for pkg_cstate_limit:
1266 * If you change the values, note they are used both in comparisons
1267 * (>= PCL__7) and to index pkg_cstate_limit_strings[].
1268 */
1269
1270#define PCLUKN 0 /* Unknown */
1271#define PCLRSV 1 /* Reserved */
1272#define PCL__0 2 /* PC0 */
1273#define PCL__1 3 /* PC1 */
1274#define PCL__2 4 /* PC2 */
1275#define PCL__3 5 /* PC3 */
1276#define PCL__4 6 /* PC4 */
1277#define PCL__6 7 /* PC6 */
1278#define PCL_6N 8 /* PC6 No Retention */
1279#define PCL_6R 9 /* PC6 Retention */
1280#define PCL__7 10 /* PC7 */
1281#define PCL_7S 11 /* PC7 Shrink */
0b2bb692
LB
1282#define PCL__8 12 /* PC8 */
1283#define PCL__9 13 /* PC9 */
1284#define PCLUNL 14 /* Unlimited */
ee7e38e3
LB
1285
1286int pkg_cstate_limit = PCLUKN;
1287char *pkg_cstate_limit_strings[] = { "reserved", "unknown", "pc0", "pc1", "pc2",
0b2bb692 1288 "pc3", "pc4", "pc6", "pc6n", "pc6r", "pc7", "pc7s", "pc8", "pc9", "unlimited"};
ee7e38e3 1289
e9257f5f
LB
1290int nhm_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCL__3, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
1291int snb_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCL__7, PCL_7S, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
1292int hsw_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL__3, PCL__6, PCL__7, PCL_7S, PCL__8, PCL__9, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
1293int slv_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
1294int amt_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
1295int phi_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
e4085d54 1296int bxt_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
d8ebb442 1297int skx_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
ee7e38e3 1298
a2b7b749
LB
1299
1300static void
1301calculate_tsc_tweak()
1302{
a2b7b749
LB
1303 tsc_tweak = base_hz / tsc_hz;
1304}
1305
fcd17211
LB
1306static void
1307dump_nhm_platform_info(void)
103a8fea
LB
1308{
1309 unsigned long long msr;
1310 unsigned int ratio;
1311
ec0adc53 1312 get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
103a8fea 1313
b7d8c148 1314 fprintf(outf, "cpu%d: MSR_PLATFORM_INFO: 0x%08llx\n", base_cpu, msr);
6574a5d5 1315
103a8fea 1316 ratio = (msr >> 40) & 0xFF;
b7d8c148 1317 fprintf(outf, "%d * %.0f = %.0f MHz max efficiency frequency\n",
103a8fea
LB
1318 ratio, bclk, ratio * bclk);
1319
1320 ratio = (msr >> 8) & 0xFF;
b7d8c148 1321 fprintf(outf, "%d * %.0f = %.0f MHz base frequency\n",
103a8fea
LB
1322 ratio, bclk, ratio * bclk);
1323
7ce7d5de 1324 get_msr(base_cpu, MSR_IA32_POWER_CTL, &msr);
b7d8c148 1325 fprintf(outf, "cpu%d: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n",
bfae2052 1326 base_cpu, msr, msr & 0x2 ? "EN" : "DIS");
67920418 1327
fcd17211
LB
1328 return;
1329}
1330
1331static void
1332dump_hsw_turbo_ratio_limits(void)
1333{
1334 unsigned long long msr;
1335 unsigned int ratio;
1336
7ce7d5de 1337 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT2, &msr);
fcd17211 1338
b7d8c148 1339 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT2: 0x%08llx\n", base_cpu, msr);
fcd17211
LB
1340
1341 ratio = (msr >> 8) & 0xFF;
1342 if (ratio)
b7d8c148 1343 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 18 active cores\n",
fcd17211
LB
1344 ratio, bclk, ratio * bclk);
1345
1346 ratio = (msr >> 0) & 0xFF;
1347 if (ratio)
b7d8c148 1348 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 17 active cores\n",
fcd17211
LB
1349 ratio, bclk, ratio * bclk);
1350 return;
1351}
1352
1353static void
1354dump_ivt_turbo_ratio_limits(void)
1355{
1356 unsigned long long msr;
1357 unsigned int ratio;
6574a5d5 1358
7ce7d5de 1359 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &msr);
6574a5d5 1360
b7d8c148 1361 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, msr);
6574a5d5
LB
1362
1363 ratio = (msr >> 56) & 0xFF;
1364 if (ratio)
b7d8c148 1365 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 16 active cores\n",
6574a5d5
LB
1366 ratio, bclk, ratio * bclk);
1367
1368 ratio = (msr >> 48) & 0xFF;
1369 if (ratio)
b7d8c148 1370 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 15 active cores\n",
6574a5d5
LB
1371 ratio, bclk, ratio * bclk);
1372
1373 ratio = (msr >> 40) & 0xFF;
1374 if (ratio)
b7d8c148 1375 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 14 active cores\n",
6574a5d5
LB
1376 ratio, bclk, ratio * bclk);
1377
1378 ratio = (msr >> 32) & 0xFF;
1379 if (ratio)
b7d8c148 1380 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 13 active cores\n",
6574a5d5
LB
1381 ratio, bclk, ratio * bclk);
1382
1383 ratio = (msr >> 24) & 0xFF;
1384 if (ratio)
b7d8c148 1385 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 12 active cores\n",
6574a5d5
LB
1386 ratio, bclk, ratio * bclk);
1387
1388 ratio = (msr >> 16) & 0xFF;
1389 if (ratio)
b7d8c148 1390 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 11 active cores\n",
6574a5d5
LB
1391 ratio, bclk, ratio * bclk);
1392
1393 ratio = (msr >> 8) & 0xFF;
1394 if (ratio)
b7d8c148 1395 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 10 active cores\n",
6574a5d5
LB
1396 ratio, bclk, ratio * bclk);
1397
1398 ratio = (msr >> 0) & 0xFF;
1399 if (ratio)
b7d8c148 1400 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 9 active cores\n",
6574a5d5 1401 ratio, bclk, ratio * bclk);
fcd17211
LB
1402 return;
1403}
6574a5d5 1404
fcd17211
LB
1405static void
1406dump_nhm_turbo_ratio_limits(void)
1407{
1408 unsigned long long msr;
1409 unsigned int ratio;
103a8fea 1410
7ce7d5de 1411 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
103a8fea 1412
b7d8c148 1413 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", base_cpu, msr);
6574a5d5
LB
1414
1415 ratio = (msr >> 56) & 0xFF;
1416 if (ratio)
b7d8c148 1417 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 8 active cores\n",
6574a5d5
LB
1418 ratio, bclk, ratio * bclk);
1419
1420 ratio = (msr >> 48) & 0xFF;
1421 if (ratio)
b7d8c148 1422 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 7 active cores\n",
6574a5d5
LB
1423 ratio, bclk, ratio * bclk);
1424
1425 ratio = (msr >> 40) & 0xFF;
1426 if (ratio)
b7d8c148 1427 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 6 active cores\n",
6574a5d5
LB
1428 ratio, bclk, ratio * bclk);
1429
1430 ratio = (msr >> 32) & 0xFF;
1431 if (ratio)
b7d8c148 1432 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 5 active cores\n",
6574a5d5
LB
1433 ratio, bclk, ratio * bclk);
1434
103a8fea
LB
1435 ratio = (msr >> 24) & 0xFF;
1436 if (ratio)
b7d8c148 1437 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 4 active cores\n",
103a8fea
LB
1438 ratio, bclk, ratio * bclk);
1439
1440 ratio = (msr >> 16) & 0xFF;
1441 if (ratio)
b7d8c148 1442 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 3 active cores\n",
103a8fea
LB
1443 ratio, bclk, ratio * bclk);
1444
1445 ratio = (msr >> 8) & 0xFF;
1446 if (ratio)
b7d8c148 1447 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 2 active cores\n",
103a8fea
LB
1448 ratio, bclk, ratio * bclk);
1449
1450 ratio = (msr >> 0) & 0xFF;
1451 if (ratio)
b7d8c148 1452 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 1 active cores\n",
103a8fea 1453 ratio, bclk, ratio * bclk);
fcd17211
LB
1454 return;
1455}
3a9a941d 1456
fb5d4327
DC
1457static void
1458dump_knl_turbo_ratio_limits(void)
1459{
cbf97aba
HC
1460 const unsigned int buckets_no = 7;
1461
fb5d4327 1462 unsigned long long msr;
cbf97aba
HC
1463 int delta_cores, delta_ratio;
1464 int i, b_nr;
1465 unsigned int cores[buckets_no];
1466 unsigned int ratio[buckets_no];
fb5d4327 1467
ebf5926a 1468 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
fb5d4327 1469
b7d8c148 1470 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n",
bfae2052 1471 base_cpu, msr);
fb5d4327
DC
1472
1473 /**
1474 * Turbo encoding in KNL is as follows:
cbf97aba
HC
1475 * [0] -- Reserved
1476 * [7:1] -- Base value of number of active cores of bucket 1.
fb5d4327
DC
1477 * [15:8] -- Base value of freq ratio of bucket 1.
1478 * [20:16] -- +ve delta of number of active cores of bucket 2.
1479 * i.e. active cores of bucket 2 =
1480 * active cores of bucket 1 + delta
1481 * [23:21] -- Negative delta of freq ratio of bucket 2.
1482 * i.e. freq ratio of bucket 2 =
1483 * freq ratio of bucket 1 - delta
1484 * [28:24]-- +ve delta of number of active cores of bucket 3.
1485 * [31:29]-- -ve delta of freq ratio of bucket 3.
1486 * [36:32]-- +ve delta of number of active cores of bucket 4.
1487 * [39:37]-- -ve delta of freq ratio of bucket 4.
1488 * [44:40]-- +ve delta of number of active cores of bucket 5.
1489 * [47:45]-- -ve delta of freq ratio of bucket 5.
1490 * [52:48]-- +ve delta of number of active cores of bucket 6.
1491 * [55:53]-- -ve delta of freq ratio of bucket 6.
1492 * [60:56]-- +ve delta of number of active cores of bucket 7.
1493 * [63:61]-- -ve delta of freq ratio of bucket 7.
1494 */
cbf97aba
HC
1495
1496 b_nr = 0;
1497 cores[b_nr] = (msr & 0xFF) >> 1;
1498 ratio[b_nr] = (msr >> 8) & 0xFF;
1499
1500 for (i = 16; i < 64; i += 8) {
fb5d4327 1501 delta_cores = (msr >> i) & 0x1F;
cbf97aba
HC
1502 delta_ratio = (msr >> (i + 5)) & 0x7;
1503
1504 cores[b_nr + 1] = cores[b_nr] + delta_cores;
1505 ratio[b_nr + 1] = ratio[b_nr] - delta_ratio;
1506 b_nr++;
fb5d4327 1507 }
cbf97aba
HC
1508
1509 for (i = buckets_no - 1; i >= 0; i--)
1510 if (i > 0 ? ratio[i] != ratio[i - 1] : 1)
b7d8c148 1511 fprintf(outf,
fb5d4327 1512 "%d * %.0f = %.0f MHz max turbo %d active cores\n",
cbf97aba 1513 ratio[i], bclk, ratio[i] * bclk, cores[i]);
fb5d4327
DC
1514}
1515
fcd17211
LB
1516static void
1517dump_nhm_cst_cfg(void)
1518{
1519 unsigned long long msr;
1520
7ce7d5de 1521 get_msr(base_cpu, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr);
fcd17211
LB
1522
1523#define SNB_C1_AUTO_UNDEMOTE (1UL << 27)
1524#define SNB_C3_AUTO_UNDEMOTE (1UL << 28)
1525
b7d8c148 1526 fprintf(outf, "cpu%d: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x%08llx", base_cpu, msr);
fcd17211 1527
b7d8c148 1528 fprintf(outf, " (%s%s%s%s%slocked: pkg-cstate-limit=%d: %s)\n",
fcd17211
LB
1529 (msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "",
1530 (msr & SNB_C1_AUTO_UNDEMOTE) ? "UNdemote-C1, " : "",
1531 (msr & NHM_C3_AUTO_DEMOTE) ? "demote-C3, " : "",
1532 (msr & NHM_C1_AUTO_DEMOTE) ? "demote-C1, " : "",
1533 (msr & (1 << 15)) ? "" : "UN",
6c34f160 1534 (unsigned int)msr & 0xF,
fcd17211
LB
1535 pkg_cstate_limit_strings[pkg_cstate_limit]);
1536 return;
103a8fea
LB
1537}
1538
6fb3143b
LB
1539static void
1540dump_config_tdp(void)
1541{
1542 unsigned long long msr;
1543
1544 get_msr(base_cpu, MSR_CONFIG_TDP_NOMINAL, &msr);
b7d8c148 1545 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_NOMINAL: 0x%08llx", base_cpu, msr);
685b535b 1546 fprintf(outf, " (base_ratio=%d)\n", (unsigned int)msr & 0xFF);
6fb3143b
LB
1547
1548 get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_1, &msr);
b7d8c148 1549 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_1: 0x%08llx (", base_cpu, msr);
6fb3143b 1550 if (msr) {
685b535b
CY
1551 fprintf(outf, "PKG_MIN_PWR_LVL1=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
1552 fprintf(outf, "PKG_MAX_PWR_LVL1=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
1553 fprintf(outf, "LVL1_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
1554 fprintf(outf, "PKG_TDP_LVL1=%d", (unsigned int)(msr) & 0x7FFF);
6fb3143b 1555 }
b7d8c148 1556 fprintf(outf, ")\n");
6fb3143b
LB
1557
1558 get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_2, &msr);
b7d8c148 1559 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_2: 0x%08llx (", base_cpu, msr);
6fb3143b 1560 if (msr) {
685b535b
CY
1561 fprintf(outf, "PKG_MIN_PWR_LVL2=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
1562 fprintf(outf, "PKG_MAX_PWR_LVL2=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
1563 fprintf(outf, "LVL2_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
1564 fprintf(outf, "PKG_TDP_LVL2=%d", (unsigned int)(msr) & 0x7FFF);
6fb3143b 1565 }
b7d8c148 1566 fprintf(outf, ")\n");
6fb3143b
LB
1567
1568 get_msr(base_cpu, MSR_CONFIG_TDP_CONTROL, &msr);
b7d8c148 1569 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_CONTROL: 0x%08llx (", base_cpu, msr);
6fb3143b 1570 if ((msr) & 0x3)
b7d8c148
LB
1571 fprintf(outf, "TDP_LEVEL=%d ", (unsigned int)(msr) & 0x3);
1572 fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
1573 fprintf(outf, ")\n");
36229897 1574
6fb3143b 1575 get_msr(base_cpu, MSR_TURBO_ACTIVATION_RATIO, &msr);
b7d8c148 1576 fprintf(outf, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu, msr);
685b535b 1577 fprintf(outf, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0xFF);
b7d8c148
LB
1578 fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
1579 fprintf(outf, ")\n");
6fb3143b 1580}
5a63426e
LB
1581
1582unsigned int irtl_time_units[] = {1, 32, 1024, 32768, 1048576, 33554432, 0, 0 };
1583
1584void print_irtl(void)
1585{
1586 unsigned long long msr;
1587
1588 get_msr(base_cpu, MSR_PKGC3_IRTL, &msr);
1589 fprintf(outf, "cpu%d: MSR_PKGC3_IRTL: 0x%08llx (", base_cpu, msr);
1590 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
1591 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
1592
1593 get_msr(base_cpu, MSR_PKGC6_IRTL, &msr);
1594 fprintf(outf, "cpu%d: MSR_PKGC6_IRTL: 0x%08llx (", base_cpu, msr);
1595 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
1596 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
1597
1598 get_msr(base_cpu, MSR_PKGC7_IRTL, &msr);
1599 fprintf(outf, "cpu%d: MSR_PKGC7_IRTL: 0x%08llx (", base_cpu, msr);
1600 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
1601 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
1602
1603 if (!do_irtl_hsw)
1604 return;
1605
1606 get_msr(base_cpu, MSR_PKGC8_IRTL, &msr);
1607 fprintf(outf, "cpu%d: MSR_PKGC8_IRTL: 0x%08llx (", base_cpu, msr);
1608 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
1609 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
1610
1611 get_msr(base_cpu, MSR_PKGC9_IRTL, &msr);
1612 fprintf(outf, "cpu%d: MSR_PKGC9_IRTL: 0x%08llx (", base_cpu, msr);
1613 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
1614 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
1615
1616 get_msr(base_cpu, MSR_PKGC10_IRTL, &msr);
1617 fprintf(outf, "cpu%d: MSR_PKGC10_IRTL: 0x%08llx (", base_cpu, msr);
1618 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
1619 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
1620
1621}
36229897
LB
1622void free_fd_percpu(void)
1623{
1624 int i;
1625
01a67adf 1626 for (i = 0; i < topo.max_cpu_num + 1; ++i) {
36229897
LB
1627 if (fd_percpu[i] != 0)
1628 close(fd_percpu[i]);
1629 }
1630
1631 free(fd_percpu);
6fb3143b
LB
1632}
1633
c98d5d94 1634void free_all_buffers(void)
103a8fea 1635{
c98d5d94
LB
1636 CPU_FREE(cpu_present_set);
1637 cpu_present_set = NULL;
36229897 1638 cpu_present_setsize = 0;
103a8fea 1639
c98d5d94
LB
1640 CPU_FREE(cpu_affinity_set);
1641 cpu_affinity_set = NULL;
1642 cpu_affinity_setsize = 0;
103a8fea 1643
c98d5d94
LB
1644 free(thread_even);
1645 free(core_even);
1646 free(package_even);
103a8fea 1647
c98d5d94
LB
1648 thread_even = NULL;
1649 core_even = NULL;
1650 package_even = NULL;
103a8fea 1651
c98d5d94
LB
1652 free(thread_odd);
1653 free(core_odd);
1654 free(package_odd);
103a8fea 1655
c98d5d94
LB
1656 thread_odd = NULL;
1657 core_odd = NULL;
1658 package_odd = NULL;
103a8fea 1659
c98d5d94
LB
1660 free(output_buffer);
1661 output_buffer = NULL;
1662 outp = NULL;
36229897
LB
1663
1664 free_fd_percpu();
562a2d37
LB
1665
1666 free(irq_column_2_cpu);
1667 free(irqs_per_cpu);
103a8fea
LB
1668}
1669
57a42a34
JT
1670/*
1671 * Open a file, and exit on failure
1672 */
1673FILE *fopen_or_die(const char *path, const char *mode)
1674{
b7d8c148 1675 FILE *filep = fopen(path, mode);
b2c95d90
JT
1676 if (!filep)
1677 err(1, "%s: open failed", path);
57a42a34
JT
1678 return filep;
1679}
1680
c98d5d94 1681/*
95aebc44 1682 * Parse a file containing a single int.
c98d5d94 1683 */
95aebc44 1684int parse_int_file(const char *fmt, ...)
103a8fea 1685{
95aebc44
JT
1686 va_list args;
1687 char path[PATH_MAX];
c98d5d94 1688 FILE *filep;
95aebc44 1689 int value;
103a8fea 1690
95aebc44
JT
1691 va_start(args, fmt);
1692 vsnprintf(path, sizeof(path), fmt, args);
1693 va_end(args);
57a42a34 1694 filep = fopen_or_die(path, "r");
b2c95d90
JT
1695 if (fscanf(filep, "%d", &value) != 1)
1696 err(1, "%s: failed to parse number from file", path);
c98d5d94 1697 fclose(filep);
95aebc44
JT
1698 return value;
1699}
1700
1701/*
e275b388
DC
1702 * get_cpu_position_in_core(cpu)
1703 * return the position of the CPU among its HT siblings in the core
1704 * return -1 if the sibling is not in list
95aebc44 1705 */
e275b388 1706int get_cpu_position_in_core(int cpu)
95aebc44 1707{
e275b388
DC
1708 char path[64];
1709 FILE *filep;
1710 int this_cpu;
1711 char character;
1712 int i;
1713
1714 sprintf(path,
1715 "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list",
1716 cpu);
1717 filep = fopen(path, "r");
1718 if (filep == NULL) {
1719 perror(path);
1720 exit(1);
1721 }
1722
1723 for (i = 0; i < topo.num_threads_per_core; i++) {
1724 fscanf(filep, "%d", &this_cpu);
1725 if (this_cpu == cpu) {
1726 fclose(filep);
1727 return i;
1728 }
1729
1730 /* Account for no separator after last thread*/
1731 if (i != (topo.num_threads_per_core - 1))
1732 fscanf(filep, "%c", &character);
1733 }
1734
1735 fclose(filep);
1736 return -1;
103a8fea
LB
1737}
1738
c98d5d94
LB
1739/*
1740 * cpu_is_first_core_in_package(cpu)
1741 * return 1 if given CPU is 1st core in package
1742 */
1743int cpu_is_first_core_in_package(int cpu)
103a8fea 1744{
95aebc44 1745 return cpu == parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_siblings_list", cpu);
103a8fea
LB
1746}
1747
1748int get_physical_package_id(int cpu)
1749{
95aebc44 1750 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu);
103a8fea
LB
1751}
1752
1753int get_core_id(int cpu)
1754{
95aebc44 1755 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", cpu);
103a8fea
LB
1756}
1757
c98d5d94
LB
1758int get_num_ht_siblings(int cpu)
1759{
1760 char path[80];
1761 FILE *filep;
e275b388
DC
1762 int sib1;
1763 int matches = 0;
c98d5d94 1764 char character;
e275b388
DC
1765 char str[100];
1766 char *ch;
c98d5d94
LB
1767
1768 sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", cpu);
57a42a34 1769 filep = fopen_or_die(path, "r");
e275b388 1770
c98d5d94
LB
1771 /*
1772 * file format:
e275b388
DC
1773 * A ',' separated or '-' separated set of numbers
1774 * (eg 1-2 or 1,3,4,5)
c98d5d94 1775 */
e275b388
DC
1776 fscanf(filep, "%d%c\n", &sib1, &character);
1777 fseek(filep, 0, SEEK_SET);
1778 fgets(str, 100, filep);
1779 ch = strchr(str, character);
1780 while (ch != NULL) {
1781 matches++;
1782 ch = strchr(ch+1, character);
1783 }
c98d5d94
LB
1784
1785 fclose(filep);
e275b388 1786 return matches+1;
c98d5d94
LB
1787}
1788
103a8fea 1789/*
c98d5d94
LB
1790 * run func(thread, core, package) in topology order
1791 * skip non-present cpus
103a8fea
LB
1792 */
1793
c98d5d94
LB
1794int for_all_cpus_2(int (func)(struct thread_data *, struct core_data *,
1795 struct pkg_data *, struct thread_data *, struct core_data *,
1796 struct pkg_data *), struct thread_data *thread_base,
1797 struct core_data *core_base, struct pkg_data *pkg_base,
1798 struct thread_data *thread_base2, struct core_data *core_base2,
1799 struct pkg_data *pkg_base2)
1800{
1801 int retval, pkg_no, core_no, thread_no;
1802
1803 for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) {
1804 for (core_no = 0; core_no < topo.num_cores_per_pkg; ++core_no) {
1805 for (thread_no = 0; thread_no <
1806 topo.num_threads_per_core; ++thread_no) {
1807 struct thread_data *t, *t2;
1808 struct core_data *c, *c2;
1809 struct pkg_data *p, *p2;
1810
1811 t = GET_THREAD(thread_base, thread_no, core_no, pkg_no);
1812
1813 if (cpu_is_not_present(t->cpu_id))
1814 continue;
1815
1816 t2 = GET_THREAD(thread_base2, thread_no, core_no, pkg_no);
1817
1818 c = GET_CORE(core_base, core_no, pkg_no);
1819 c2 = GET_CORE(core_base2, core_no, pkg_no);
1820
1821 p = GET_PKG(pkg_base, pkg_no);
1822 p2 = GET_PKG(pkg_base2, pkg_no);
1823
1824 retval = func(t, c, p, t2, c2, p2);
1825 if (retval)
1826 return retval;
1827 }
1828 }
1829 }
1830 return 0;
1831}
1832
1833/*
1834 * run func(cpu) on every cpu in /proc/stat
1835 * return max_cpu number
1836 */
1837int for_all_proc_cpus(int (func)(int))
103a8fea
LB
1838{
1839 FILE *fp;
c98d5d94 1840 int cpu_num;
103a8fea
LB
1841 int retval;
1842
57a42a34 1843 fp = fopen_or_die(proc_stat, "r");
103a8fea
LB
1844
1845 retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n");
b2c95d90
JT
1846 if (retval != 0)
1847 err(1, "%s: failed to parse format", proc_stat);
103a8fea 1848
c98d5d94
LB
1849 while (1) {
1850 retval = fscanf(fp, "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n", &cpu_num);
103a8fea
LB
1851 if (retval != 1)
1852 break;
1853
c98d5d94
LB
1854 retval = func(cpu_num);
1855 if (retval) {
1856 fclose(fp);
1857 return(retval);
1858 }
103a8fea
LB
1859 }
1860 fclose(fp);
c98d5d94 1861 return 0;
103a8fea
LB
1862}
1863
1864void re_initialize(void)
1865{
c98d5d94
LB
1866 free_all_buffers();
1867 setup_all_buffers();
1868 printf("turbostat: re-initialized with num_cpus %d\n", topo.num_cpus);
103a8fea
LB
1869}
1870
c98d5d94 1871
103a8fea 1872/*
c98d5d94
LB
1873 * count_cpus()
1874 * remember the last one seen, it will be the max
103a8fea 1875 */
c98d5d94 1876int count_cpus(int cpu)
103a8fea 1877{
c98d5d94
LB
1878 if (topo.max_cpu_num < cpu)
1879 topo.max_cpu_num = cpu;
103a8fea 1880
c98d5d94
LB
1881 topo.num_cpus += 1;
1882 return 0;
1883}
1884int mark_cpu_present(int cpu)
1885{
1886 CPU_SET_S(cpu, cpu_present_setsize, cpu_present_set);
15aaa346 1887 return 0;
103a8fea
LB
1888}
1889
562a2d37
LB
1890/*
1891 * snapshot_proc_interrupts()
1892 *
1893 * read and record summary of /proc/interrupts
1894 *
1895 * return 1 if config change requires a restart, else return 0
1896 */
1897int snapshot_proc_interrupts(void)
1898{
1899 static FILE *fp;
1900 int column, retval;
1901
1902 if (fp == NULL)
1903 fp = fopen_or_die("/proc/interrupts", "r");
1904 else
1905 rewind(fp);
1906
1907 /* read 1st line of /proc/interrupts to get cpu* name for each column */
1908 for (column = 0; column < topo.num_cpus; ++column) {
1909 int cpu_number;
1910
1911 retval = fscanf(fp, " CPU%d", &cpu_number);
1912 if (retval != 1)
1913 break;
1914
1915 if (cpu_number > topo.max_cpu_num) {
1916 warn("/proc/interrupts: cpu%d: > %d", cpu_number, topo.max_cpu_num);
1917 return 1;
1918 }
1919
1920 irq_column_2_cpu[column] = cpu_number;
1921 irqs_per_cpu[cpu_number] = 0;
1922 }
1923
1924 /* read /proc/interrupt count lines and sum up irqs per cpu */
1925 while (1) {
1926 int column;
1927 char buf[64];
1928
1929 retval = fscanf(fp, " %s:", buf); /* flush irq# "N:" */
1930 if (retval != 1)
1931 break;
1932
1933 /* read the count per cpu */
1934 for (column = 0; column < topo.num_cpus; ++column) {
1935
1936 int cpu_number, irq_count;
1937
1938 retval = fscanf(fp, " %d", &irq_count);
1939 if (retval != 1)
1940 break;
1941
1942 cpu_number = irq_column_2_cpu[column];
1943 irqs_per_cpu[cpu_number] += irq_count;
1944
1945 }
1946
1947 while (getc(fp) != '\n')
1948 ; /* flush interrupt description */
1949
1950 }
1951 return 0;
1952}
fdf676e5
LB
1953/*
1954 * snapshot_gfx_rc6_ms()
1955 *
1956 * record snapshot of
1957 * /sys/class/drm/card0/power/rc6_residency_ms
1958 *
1959 * return 1 if config change requires a restart, else return 0
1960 */
1961int snapshot_gfx_rc6_ms(void)
1962{
1963 FILE *fp;
1964 int retval;
1965
1966 fp = fopen_or_die("/sys/class/drm/card0/power/rc6_residency_ms", "r");
1967
1968 retval = fscanf(fp, "%lld", &gfx_cur_rc6_ms);
1969 if (retval != 1)
1970 err(1, "GFX rc6");
1971
1972 fclose(fp);
1973
1974 return 0;
1975}
27d47356
LB
1976/*
1977 * snapshot_gfx_mhz()
1978 *
1979 * record snapshot of
1980 * /sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz
1981 *
1982 * return 1 if config change requires a restart, else return 0
1983 */
1984int snapshot_gfx_mhz(void)
1985{
1986 static FILE *fp;
1987 int retval;
1988
1989 if (fp == NULL)
1990 fp = fopen_or_die("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", "r");
1991 else
1992 rewind(fp);
1993
1994 retval = fscanf(fp, "%d", &gfx_cur_mhz);
1995 if (retval != 1)
1996 err(1, "GFX MHz");
1997
1998 return 0;
1999}
562a2d37
LB
2000
2001/*
2002 * snapshot /proc and /sys files
2003 *
2004 * return 1 if configuration restart needed, else return 0
2005 */
2006int snapshot_proc_sysfs_files(void)
2007{
2008 if (snapshot_proc_interrupts())
2009 return 1;
2010
fdf676e5
LB
2011 if (do_gfx_rc6_ms)
2012 snapshot_gfx_rc6_ms();
2013
27d47356
LB
2014 if (do_gfx_mhz)
2015 snapshot_gfx_mhz();
2016
562a2d37
LB
2017 return 0;
2018}
2019
103a8fea
LB
2020void turbostat_loop()
2021{
c98d5d94 2022 int retval;
e52966c0 2023 int restarted = 0;
c98d5d94 2024
103a8fea 2025restart:
e52966c0
LB
2026 restarted++;
2027
562a2d37 2028 snapshot_proc_sysfs_files();
c98d5d94 2029 retval = for_all_cpus(get_counters, EVEN_COUNTERS);
d91bb17c
LB
2030 if (retval < -1) {
2031 exit(retval);
2032 } else if (retval == -1) {
e52966c0
LB
2033 if (restarted > 1) {
2034 exit(retval);
2035 }
c98d5d94
LB
2036 re_initialize();
2037 goto restart;
2038 }
e52966c0 2039 restarted = 0;
103a8fea
LB
2040 gettimeofday(&tv_even, (struct timezone *)NULL);
2041
2042 while (1) {
c98d5d94 2043 if (for_all_proc_cpus(cpu_is_not_present)) {
103a8fea
LB
2044 re_initialize();
2045 goto restart;
2046 }
2a0609c0 2047 nanosleep(&interval_ts, NULL);
562a2d37
LB
2048 if (snapshot_proc_sysfs_files())
2049 goto restart;
c98d5d94 2050 retval = for_all_cpus(get_counters, ODD_COUNTERS);
d91bb17c
LB
2051 if (retval < -1) {
2052 exit(retval);
2053 } else if (retval == -1) {
15aaa346
LB
2054 re_initialize();
2055 goto restart;
2056 }
103a8fea 2057 gettimeofday(&tv_odd, (struct timezone *)NULL);
103a8fea 2058 timersub(&tv_odd, &tv_even, &tv_delta);
ba3dec99
LB
2059 if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS)) {
2060 re_initialize();
2061 goto restart;
2062 }
c98d5d94
LB
2063 compute_average(EVEN_COUNTERS);
2064 format_all_counters(EVEN_COUNTERS);
b7d8c148 2065 flush_output_stdout();
2a0609c0 2066 nanosleep(&interval_ts, NULL);
562a2d37
LB
2067 if (snapshot_proc_sysfs_files())
2068 goto restart;
c98d5d94 2069 retval = for_all_cpus(get_counters, EVEN_COUNTERS);
d91bb17c
LB
2070 if (retval < -1) {
2071 exit(retval);
2072 } else if (retval == -1) {
103a8fea
LB
2073 re_initialize();
2074 goto restart;
2075 }
103a8fea 2076 gettimeofday(&tv_even, (struct timezone *)NULL);
103a8fea 2077 timersub(&tv_even, &tv_odd, &tv_delta);
ba3dec99
LB
2078 if (for_all_cpus_2(delta_cpu, EVEN_COUNTERS, ODD_COUNTERS)) {
2079 re_initialize();
2080 goto restart;
2081 }
c98d5d94
LB
2082 compute_average(ODD_COUNTERS);
2083 format_all_counters(ODD_COUNTERS);
b7d8c148 2084 flush_output_stdout();
103a8fea
LB
2085 }
2086}
2087
2088void check_dev_msr()
2089{
2090 struct stat sb;
7ce7d5de 2091 char pathname[32];
103a8fea 2092
7ce7d5de
PB
2093 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
2094 if (stat(pathname, &sb))
a21d38c8
LB
2095 if (system("/sbin/modprobe msr > /dev/null 2>&1"))
2096 err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" ");
103a8fea
LB
2097}
2098
98481e79 2099void check_permissions()
103a8fea 2100{
98481e79
LB
2101 struct __user_cap_header_struct cap_header_data;
2102 cap_user_header_t cap_header = &cap_header_data;
2103 struct __user_cap_data_struct cap_data_data;
2104 cap_user_data_t cap_data = &cap_data_data;
2105 extern int capget(cap_user_header_t hdrp, cap_user_data_t datap);
2106 int do_exit = 0;
7ce7d5de 2107 char pathname[32];
98481e79
LB
2108
2109 /* check for CAP_SYS_RAWIO */
2110 cap_header->pid = getpid();
2111 cap_header->version = _LINUX_CAPABILITY_VERSION;
2112 if (capget(cap_header, cap_data) < 0)
2113 err(-6, "capget(2) failed");
2114
2115 if ((cap_data->effective & (1 << CAP_SYS_RAWIO)) == 0) {
2116 do_exit++;
2117 warnx("capget(CAP_SYS_RAWIO) failed,"
2118 " try \"# setcap cap_sys_rawio=ep %s\"", progname);
2119 }
2120
2121 /* test file permissions */
7ce7d5de
PB
2122 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
2123 if (euidaccess(pathname, R_OK)) {
98481e79
LB
2124 do_exit++;
2125 warn("/dev/cpu/0/msr open failed, try chown or chmod +r /dev/cpu/*/msr");
2126 }
2127
2128 /* if all else fails, thell them to be root */
2129 if (do_exit)
2130 if (getuid() != 0)
d7899447 2131 warnx("... or simply run as root");
98481e79
LB
2132
2133 if (do_exit)
2134 exit(-6);
103a8fea
LB
2135}
2136
d7899447
LB
2137/*
2138 * NHM adds support for additional MSRs:
2139 *
2140 * MSR_SMI_COUNT 0x00000034
2141 *
ec0adc53 2142 * MSR_PLATFORM_INFO 0x000000ce
d7899447
LB
2143 * MSR_NHM_SNB_PKG_CST_CFG_CTL 0x000000e2
2144 *
2145 * MSR_PKG_C3_RESIDENCY 0x000003f8
2146 * MSR_PKG_C6_RESIDENCY 0x000003f9
2147 * MSR_CORE_C3_RESIDENCY 0x000003fc
2148 * MSR_CORE_C6_RESIDENCY 0x000003fd
2149 *
ee7e38e3
LB
2150 * Side effect:
2151 * sets global pkg_cstate_limit to decode MSR_NHM_SNB_PKG_CST_CFG_CTL
d7899447 2152 */
ee7e38e3 2153int probe_nhm_msrs(unsigned int family, unsigned int model)
103a8fea 2154{
ee7e38e3 2155 unsigned long long msr;
21ed5574 2156 unsigned int base_ratio;
ee7e38e3
LB
2157 int *pkg_cstate_limits;
2158
103a8fea
LB
2159 if (!genuine_intel)
2160 return 0;
2161
2162 if (family != 6)
2163 return 0;
2164
21ed5574
LB
2165 bclk = discover_bclk(family, model);
2166
103a8fea 2167 switch (model) {
869ce69e
LB
2168 case INTEL_FAM6_NEHALEM_EP: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */
2169 case INTEL_FAM6_NEHALEM: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */
103a8fea 2170 case 0x1F: /* Core i7 and i5 Processor - Nehalem */
869ce69e
LB
2171 case INTEL_FAM6_WESTMERE: /* Westmere Client - Clarkdale, Arrandale */
2172 case INTEL_FAM6_WESTMERE_EP: /* Westmere EP - Gulftown */
2173 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */
2174 case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */
ee7e38e3
LB
2175 pkg_cstate_limits = nhm_pkg_cstate_limits;
2176 break;
869ce69e
LB
2177 case INTEL_FAM6_SANDYBRIDGE: /* SNB */
2178 case INTEL_FAM6_SANDYBRIDGE_X: /* SNB Xeon */
2179 case INTEL_FAM6_IVYBRIDGE: /* IVB */
2180 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
ee7e38e3
LB
2181 pkg_cstate_limits = snb_pkg_cstate_limits;
2182 break;
869ce69e
LB
2183 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2184 case INTEL_FAM6_HASWELL_X: /* HSX */
2185 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2186 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
2187 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2188 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
2189 case INTEL_FAM6_BROADWELL_X: /* BDX */
2190 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2191 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2192 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2193 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2194 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
ee7e38e3
LB
2195 pkg_cstate_limits = hsw_pkg_cstate_limits;
2196 break;
d8ebb442
LB
2197 case INTEL_FAM6_SKYLAKE_X: /* SKX */
2198 pkg_cstate_limits = skx_pkg_cstate_limits;
2199 break;
869ce69e
LB
2200 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
2201 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
ee7e38e3
LB
2202 pkg_cstate_limits = slv_pkg_cstate_limits;
2203 break;
869ce69e 2204 case INTEL_FAM6_ATOM_AIRMONT: /* AMT */
ee7e38e3
LB
2205 pkg_cstate_limits = amt_pkg_cstate_limits;
2206 break;
869ce69e 2207 case INTEL_FAM6_XEON_PHI_KNL: /* PHI */
005c82d6 2208 case INTEL_FAM6_XEON_PHI_KNM:
ee7e38e3
LB
2209 pkg_cstate_limits = phi_pkg_cstate_limits;
2210 break;
869ce69e
LB
2211 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
2212 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
e4085d54
LB
2213 pkg_cstate_limits = bxt_pkg_cstate_limits;
2214 break;
103a8fea
LB
2215 default:
2216 return 0;
2217 }
7ce7d5de 2218 get_msr(base_cpu, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr);
e9257f5f 2219 pkg_cstate_limit = pkg_cstate_limits[msr & 0xF];
ee7e38e3 2220
ec0adc53 2221 get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
21ed5574
LB
2222 base_ratio = (msr >> 8) & 0xFF;
2223
2224 base_hz = base_ratio * bclk * 1000000;
2225 has_base_hz = 1;
ee7e38e3 2226 return 1;
103a8fea 2227}
d7899447
LB
2228int has_nhm_turbo_ratio_limit(unsigned int family, unsigned int model)
2229{
d7899447
LB
2230 switch (model) {
2231 /* Nehalem compatible, but do not include turbo-ratio limit support */
869ce69e
LB
2232 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */
2233 case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */
2234 case INTEL_FAM6_XEON_PHI_KNL: /* PHI - Knights Landing (different MSR definition) */
005c82d6 2235 case INTEL_FAM6_XEON_PHI_KNM:
d7899447
LB
2236 return 0;
2237 default:
2238 return 1;
2239 }
2240}
6574a5d5
LB
2241int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model)
2242{
2243 if (!genuine_intel)
2244 return 0;
2245
2246 if (family != 6)
2247 return 0;
2248
2249 switch (model) {
869ce69e
LB
2250 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
2251 case INTEL_FAM6_HASWELL_X: /* HSW Xeon */
fcd17211
LB
2252 return 1;
2253 default:
2254 return 0;
2255 }
2256}
2257int has_hsw_turbo_ratio_limit(unsigned int family, unsigned int model)
2258{
2259 if (!genuine_intel)
2260 return 0;
2261
2262 if (family != 6)
2263 return 0;
2264
2265 switch (model) {
869ce69e 2266 case INTEL_FAM6_HASWELL_X: /* HSW Xeon */
6574a5d5
LB
2267 return 1;
2268 default:
2269 return 0;
2270 }
2271}
2272
fb5d4327
DC
2273int has_knl_turbo_ratio_limit(unsigned int family, unsigned int model)
2274{
2275 if (!genuine_intel)
2276 return 0;
2277
2278 if (family != 6)
2279 return 0;
2280
2281 switch (model) {
869ce69e 2282 case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */
005c82d6 2283 case INTEL_FAM6_XEON_PHI_KNM:
fb5d4327
DC
2284 return 1;
2285 default:
2286 return 0;
2287 }
2288}
6fb3143b
LB
2289int has_config_tdp(unsigned int family, unsigned int model)
2290{
2291 if (!genuine_intel)
2292 return 0;
2293
2294 if (family != 6)
2295 return 0;
2296
2297 switch (model) {
869ce69e
LB
2298 case INTEL_FAM6_IVYBRIDGE: /* IVB */
2299 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2300 case INTEL_FAM6_HASWELL_X: /* HSX */
2301 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2302 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
2303 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2304 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
2305 case INTEL_FAM6_BROADWELL_X: /* BDX */
2306 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2307 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2308 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2309 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2310 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
2311 case INTEL_FAM6_SKYLAKE_X: /* SKX */
2312
2313 case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */
005c82d6 2314 case INTEL_FAM6_XEON_PHI_KNM:
6fb3143b
LB
2315 return 1;
2316 default:
2317 return 0;
2318 }
2319}
2320
fcd17211 2321static void
1b69317d 2322dump_cstate_pstate_config_info(unsigned int family, unsigned int model)
fcd17211
LB
2323{
2324 if (!do_nhm_platform_info)
2325 return;
2326
2327 dump_nhm_platform_info();
2328
2329 if (has_hsw_turbo_ratio_limit(family, model))
2330 dump_hsw_turbo_ratio_limits();
2331
2332 if (has_ivt_turbo_ratio_limit(family, model))
2333 dump_ivt_turbo_ratio_limits();
2334
2335 if (has_nhm_turbo_ratio_limit(family, model))
2336 dump_nhm_turbo_ratio_limits();
2337
fb5d4327
DC
2338 if (has_knl_turbo_ratio_limit(family, model))
2339 dump_knl_turbo_ratio_limits();
2340
6fb3143b
LB
2341 if (has_config_tdp(family, model))
2342 dump_config_tdp();
2343
fcd17211
LB
2344 dump_nhm_cst_cfg();
2345}
2346
2347
889facbe
LB
2348/*
2349 * print_epb()
2350 * Decode the ENERGY_PERF_BIAS MSR
2351 */
2352int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2353{
2354 unsigned long long msr;
2355 char *epb_string;
2356 int cpu;
2357
2358 if (!has_epb)
2359 return 0;
2360
2361 cpu = t->cpu_id;
2362
2363 /* EPB is per-package */
2364 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
2365 return 0;
2366
2367 if (cpu_migrate(cpu)) {
b7d8c148 2368 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
889facbe
LB
2369 return -1;
2370 }
2371
2372 if (get_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &msr))
2373 return 0;
2374
e9be7dd6 2375 switch (msr & 0xF) {
889facbe
LB
2376 case ENERGY_PERF_BIAS_PERFORMANCE:
2377 epb_string = "performance";
2378 break;
2379 case ENERGY_PERF_BIAS_NORMAL:
2380 epb_string = "balanced";
2381 break;
2382 case ENERGY_PERF_BIAS_POWERSAVE:
2383 epb_string = "powersave";
2384 break;
2385 default:
2386 epb_string = "custom";
2387 break;
2388 }
b7d8c148 2389 fprintf(outf, "cpu%d: MSR_IA32_ENERGY_PERF_BIAS: 0x%08llx (%s)\n", cpu, msr, epb_string);
889facbe
LB
2390
2391 return 0;
2392}
7f5c258e
LB
2393/*
2394 * print_hwp()
2395 * Decode the MSR_HWP_CAPABILITIES
2396 */
2397int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2398{
2399 unsigned long long msr;
2400 int cpu;
2401
2402 if (!has_hwp)
2403 return 0;
2404
2405 cpu = t->cpu_id;
2406
2407 /* MSR_HWP_CAPABILITIES is per-package */
2408 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
2409 return 0;
2410
2411 if (cpu_migrate(cpu)) {
b7d8c148 2412 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
7f5c258e
LB
2413 return -1;
2414 }
2415
2416 if (get_msr(cpu, MSR_PM_ENABLE, &msr))
2417 return 0;
2418
b7d8c148 2419 fprintf(outf, "cpu%d: MSR_PM_ENABLE: 0x%08llx (%sHWP)\n",
7f5c258e
LB
2420 cpu, msr, (msr & (1 << 0)) ? "" : "No-");
2421
2422 /* MSR_PM_ENABLE[1] == 1 if HWP is enabled and MSRs visible */
2423 if ((msr & (1 << 0)) == 0)
2424 return 0;
2425
2426 if (get_msr(cpu, MSR_HWP_CAPABILITIES, &msr))
2427 return 0;
2428
b7d8c148 2429 fprintf(outf, "cpu%d: MSR_HWP_CAPABILITIES: 0x%08llx "
7f5c258e
LB
2430 "(high 0x%x guar 0x%x eff 0x%x low 0x%x)\n",
2431 cpu, msr,
2432 (unsigned int)HWP_HIGHEST_PERF(msr),
2433 (unsigned int)HWP_GUARANTEED_PERF(msr),
2434 (unsigned int)HWP_MOSTEFFICIENT_PERF(msr),
2435 (unsigned int)HWP_LOWEST_PERF(msr));
2436
2437 if (get_msr(cpu, MSR_HWP_REQUEST, &msr))
2438 return 0;
2439
b7d8c148 2440 fprintf(outf, "cpu%d: MSR_HWP_REQUEST: 0x%08llx "
7f5c258e
LB
2441 "(min 0x%x max 0x%x des 0x%x epp 0x%x window 0x%x pkg 0x%x)\n",
2442 cpu, msr,
2443 (unsigned int)(((msr) >> 0) & 0xff),
2444 (unsigned int)(((msr) >> 8) & 0xff),
2445 (unsigned int)(((msr) >> 16) & 0xff),
2446 (unsigned int)(((msr) >> 24) & 0xff),
2447 (unsigned int)(((msr) >> 32) & 0xff3),
2448 (unsigned int)(((msr) >> 42) & 0x1));
2449
2450 if (has_hwp_pkg) {
2451 if (get_msr(cpu, MSR_HWP_REQUEST_PKG, &msr))
2452 return 0;
2453
b7d8c148 2454 fprintf(outf, "cpu%d: MSR_HWP_REQUEST_PKG: 0x%08llx "
7f5c258e
LB
2455 "(min 0x%x max 0x%x des 0x%x epp 0x%x window 0x%x)\n",
2456 cpu, msr,
2457 (unsigned int)(((msr) >> 0) & 0xff),
2458 (unsigned int)(((msr) >> 8) & 0xff),
2459 (unsigned int)(((msr) >> 16) & 0xff),
2460 (unsigned int)(((msr) >> 24) & 0xff),
2461 (unsigned int)(((msr) >> 32) & 0xff3));
2462 }
2463 if (has_hwp_notify) {
2464 if (get_msr(cpu, MSR_HWP_INTERRUPT, &msr))
2465 return 0;
2466
b7d8c148 2467 fprintf(outf, "cpu%d: MSR_HWP_INTERRUPT: 0x%08llx "
7f5c258e
LB
2468 "(%s_Guaranteed_Perf_Change, %s_Excursion_Min)\n",
2469 cpu, msr,
2470 ((msr) & 0x1) ? "EN" : "Dis",
2471 ((msr) & 0x2) ? "EN" : "Dis");
2472 }
2473 if (get_msr(cpu, MSR_HWP_STATUS, &msr))
2474 return 0;
2475
b7d8c148 2476 fprintf(outf, "cpu%d: MSR_HWP_STATUS: 0x%08llx "
7f5c258e
LB
2477 "(%sGuaranteed_Perf_Change, %sExcursion_Min)\n",
2478 cpu, msr,
2479 ((msr) & 0x1) ? "" : "No-",
2480 ((msr) & 0x2) ? "" : "No-");
889facbe
LB
2481
2482 return 0;
2483}
2484
3a9a941d
LB
2485/*
2486 * print_perf_limit()
2487 */
2488int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2489{
2490 unsigned long long msr;
2491 int cpu;
2492
2493 cpu = t->cpu_id;
2494
2495 /* per-package */
2496 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
2497 return 0;
2498
2499 if (cpu_migrate(cpu)) {
b7d8c148 2500 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
3a9a941d
LB
2501 return -1;
2502 }
2503
2504 if (do_core_perf_limit_reasons) {
2505 get_msr(cpu, MSR_CORE_PERF_LIMIT_REASONS, &msr);
b7d8c148
LB
2506 fprintf(outf, "cpu%d: MSR_CORE_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
2507 fprintf(outf, " (Active: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)",
e33cbe85 2508 (msr & 1 << 15) ? "bit15, " : "",
3a9a941d 2509 (msr & 1 << 14) ? "bit14, " : "",
e33cbe85
LB
2510 (msr & 1 << 13) ? "Transitions, " : "",
2511 (msr & 1 << 12) ? "MultiCoreTurbo, " : "",
2512 (msr & 1 << 11) ? "PkgPwrL2, " : "",
2513 (msr & 1 << 10) ? "PkgPwrL1, " : "",
2514 (msr & 1 << 9) ? "CorePwr, " : "",
2515 (msr & 1 << 8) ? "Amps, " : "",
2516 (msr & 1 << 6) ? "VR-Therm, " : "",
2517 (msr & 1 << 5) ? "Auto-HWP, " : "",
2518 (msr & 1 << 4) ? "Graphics, " : "",
2519 (msr & 1 << 2) ? "bit2, " : "",
2520 (msr & 1 << 1) ? "ThermStatus, " : "",
2521 (msr & 1 << 0) ? "PROCHOT, " : "");
b7d8c148 2522 fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n",
e33cbe85 2523 (msr & 1 << 31) ? "bit31, " : "",
3a9a941d 2524 (msr & 1 << 30) ? "bit30, " : "",
e33cbe85
LB
2525 (msr & 1 << 29) ? "Transitions, " : "",
2526 (msr & 1 << 28) ? "MultiCoreTurbo, " : "",
2527 (msr & 1 << 27) ? "PkgPwrL2, " : "",
2528 (msr & 1 << 26) ? "PkgPwrL1, " : "",
2529 (msr & 1 << 25) ? "CorePwr, " : "",
2530 (msr & 1 << 24) ? "Amps, " : "",
2531 (msr & 1 << 22) ? "VR-Therm, " : "",
2532 (msr & 1 << 21) ? "Auto-HWP, " : "",
2533 (msr & 1 << 20) ? "Graphics, " : "",
2534 (msr & 1 << 18) ? "bit18, " : "",
2535 (msr & 1 << 17) ? "ThermStatus, " : "",
2536 (msr & 1 << 16) ? "PROCHOT, " : "");
3a9a941d
LB
2537
2538 }
2539 if (do_gfx_perf_limit_reasons) {
2540 get_msr(cpu, MSR_GFX_PERF_LIMIT_REASONS, &msr);
b7d8c148
LB
2541 fprintf(outf, "cpu%d: MSR_GFX_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
2542 fprintf(outf, " (Active: %s%s%s%s%s%s%s%s)",
3a9a941d
LB
2543 (msr & 1 << 0) ? "PROCHOT, " : "",
2544 (msr & 1 << 1) ? "ThermStatus, " : "",
2545 (msr & 1 << 4) ? "Graphics, " : "",
2546 (msr & 1 << 6) ? "VR-Therm, " : "",
2547 (msr & 1 << 8) ? "Amps, " : "",
2548 (msr & 1 << 9) ? "GFXPwr, " : "",
2549 (msr & 1 << 10) ? "PkgPwrL1, " : "",
2550 (msr & 1 << 11) ? "PkgPwrL2, " : "");
b7d8c148 2551 fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s)\n",
3a9a941d
LB
2552 (msr & 1 << 16) ? "PROCHOT, " : "",
2553 (msr & 1 << 17) ? "ThermStatus, " : "",
2554 (msr & 1 << 20) ? "Graphics, " : "",
2555 (msr & 1 << 22) ? "VR-Therm, " : "",
2556 (msr & 1 << 24) ? "Amps, " : "",
2557 (msr & 1 << 25) ? "GFXPwr, " : "",
2558 (msr & 1 << 26) ? "PkgPwrL1, " : "",
2559 (msr & 1 << 27) ? "PkgPwrL2, " : "");
2560 }
2561 if (do_ring_perf_limit_reasons) {
2562 get_msr(cpu, MSR_RING_PERF_LIMIT_REASONS, &msr);
b7d8c148
LB
2563 fprintf(outf, "cpu%d: MSR_RING_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
2564 fprintf(outf, " (Active: %s%s%s%s%s%s)",
3a9a941d
LB
2565 (msr & 1 << 0) ? "PROCHOT, " : "",
2566 (msr & 1 << 1) ? "ThermStatus, " : "",
2567 (msr & 1 << 6) ? "VR-Therm, " : "",
2568 (msr & 1 << 8) ? "Amps, " : "",
2569 (msr & 1 << 10) ? "PkgPwrL1, " : "",
2570 (msr & 1 << 11) ? "PkgPwrL2, " : "");
b7d8c148 2571 fprintf(outf, " (Logged: %s%s%s%s%s%s)\n",
3a9a941d
LB
2572 (msr & 1 << 16) ? "PROCHOT, " : "",
2573 (msr & 1 << 17) ? "ThermStatus, " : "",
2574 (msr & 1 << 22) ? "VR-Therm, " : "",
2575 (msr & 1 << 24) ? "Amps, " : "",
2576 (msr & 1 << 26) ? "PkgPwrL1, " : "",
2577 (msr & 1 << 27) ? "PkgPwrL2, " : "");
2578 }
2579 return 0;
2580}
2581
889facbe
LB
2582#define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */
2583#define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */
2584
1b69317d 2585double get_tdp(unsigned int model)
144b44b1
LB
2586{
2587 unsigned long long msr;
2588
2589 if (do_rapl & RAPL_PKG_POWER_INFO)
7ce7d5de 2590 if (!get_msr(base_cpu, MSR_PKG_POWER_INFO, &msr))
144b44b1
LB
2591 return ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units;
2592
2593 switch (model) {
869ce69e
LB
2594 case INTEL_FAM6_ATOM_SILVERMONT1:
2595 case INTEL_FAM6_ATOM_SILVERMONT2:
144b44b1
LB
2596 return 30.0;
2597 default:
2598 return 135.0;
2599 }
2600}
2601
40ee8e3b
AS
2602/*
2603 * rapl_dram_energy_units_probe()
2604 * Energy units are either hard-coded, or come from RAPL Energy Unit MSR.
2605 */
2606static double
2607rapl_dram_energy_units_probe(int model, double rapl_energy_units)
2608{
2609 /* only called for genuine_intel, family 6 */
2610
2611 switch (model) {
869ce69e
LB
2612 case INTEL_FAM6_HASWELL_X: /* HSX */
2613 case INTEL_FAM6_BROADWELL_X: /* BDX */
2614 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2615 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
005c82d6 2616 case INTEL_FAM6_XEON_PHI_KNM:
40ee8e3b
AS
2617 return (rapl_dram_energy_units = 15.3 / 1000000);
2618 default:
2619 return (rapl_energy_units);
2620 }
2621}
2622
144b44b1 2623
889facbe
LB
2624/*
2625 * rapl_probe()
2626 *
144b44b1 2627 * sets do_rapl, rapl_power_units, rapl_energy_units, rapl_time_units
889facbe
LB
2628 */
2629void rapl_probe(unsigned int family, unsigned int model)
2630{
2631 unsigned long long msr;
144b44b1 2632 unsigned int time_unit;
889facbe
LB
2633 double tdp;
2634
2635 if (!genuine_intel)
2636 return;
2637
2638 if (family != 6)
2639 return;
2640
2641 switch (model) {
869ce69e
LB
2642 case INTEL_FAM6_SANDYBRIDGE:
2643 case INTEL_FAM6_IVYBRIDGE:
2644 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2645 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2646 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
2647 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2648 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
144b44b1 2649 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO;
889facbe 2650 break;
869ce69e 2651 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
e4085d54
LB
2652 do_rapl = RAPL_PKG | RAPL_PKG_POWER_INFO;
2653 break;
869ce69e
LB
2654 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2655 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2656 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2657 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
0b2bb692
LB
2658 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
2659 break;
869ce69e
LB
2660 case INTEL_FAM6_HASWELL_X: /* HSX */
2661 case INTEL_FAM6_BROADWELL_X: /* BDX */
2662 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2663 case INTEL_FAM6_SKYLAKE_X: /* SKX */
2664 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
005c82d6 2665 case INTEL_FAM6_XEON_PHI_KNM:
0b2bb692 2666 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
e6f9bb3c 2667 break;
869ce69e
LB
2668 case INTEL_FAM6_SANDYBRIDGE_X:
2669 case INTEL_FAM6_IVYBRIDGE_X:
0b2bb692 2670 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_PKG_PERF_STATUS | RAPL_DRAM_PERF_STATUS | RAPL_PKG_POWER_INFO;
144b44b1 2671 break;
869ce69e
LB
2672 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
2673 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
9148494c 2674 do_rapl = RAPL_PKG | RAPL_CORES;
889facbe 2675 break;
869ce69e 2676 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
0f644909
JP
2677 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO | RAPL_CORES_ENERGY_STATUS;
2678 break;
889facbe
LB
2679 default:
2680 return;
2681 }
2682
2683 /* units on package 0, verify later other packages match */
7ce7d5de 2684 if (get_msr(base_cpu, MSR_RAPL_POWER_UNIT, &msr))
889facbe
LB
2685 return;
2686
2687 rapl_power_units = 1.0 / (1 << (msr & 0xF));
869ce69e 2688 if (model == INTEL_FAM6_ATOM_SILVERMONT1)
144b44b1
LB
2689 rapl_energy_units = 1.0 * (1 << (msr >> 8 & 0x1F)) / 1000000;
2690 else
2691 rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F));
889facbe 2692
40ee8e3b
AS
2693 rapl_dram_energy_units = rapl_dram_energy_units_probe(model, rapl_energy_units);
2694
144b44b1
LB
2695 time_unit = msr >> 16 & 0xF;
2696 if (time_unit == 0)
2697 time_unit = 0xA;
889facbe 2698
144b44b1 2699 rapl_time_units = 1.0 / (1 << (time_unit));
889facbe 2700
144b44b1 2701 tdp = get_tdp(model);
889facbe 2702
144b44b1 2703 rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
d8af6f5f 2704 if (debug)
b7d8c148 2705 fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
889facbe
LB
2706
2707 return;
2708}
2709
1b69317d 2710void perf_limit_reasons_probe(unsigned int family, unsigned int model)
3a9a941d
LB
2711{
2712 if (!genuine_intel)
2713 return;
2714
2715 if (family != 6)
2716 return;
2717
2718 switch (model) {
869ce69e
LB
2719 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2720 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2721 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
3a9a941d 2722 do_gfx_perf_limit_reasons = 1;
869ce69e 2723 case INTEL_FAM6_HASWELL_X: /* HSX */
3a9a941d
LB
2724 do_core_perf_limit_reasons = 1;
2725 do_ring_perf_limit_reasons = 1;
2726 default:
2727 return;
2728 }
2729}
2730
889facbe
LB
2731int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2732{
2733 unsigned long long msr;
2734 unsigned int dts;
2735 int cpu;
2736
2737 if (!(do_dts || do_ptm))
2738 return 0;
2739
2740 cpu = t->cpu_id;
2741
2742 /* DTS is per-core, no need to print for each thread */
2743 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
2744 return 0;
2745
2746 if (cpu_migrate(cpu)) {
b7d8c148 2747 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
889facbe
LB
2748 return -1;
2749 }
2750
2751 if (do_ptm && (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) {
2752 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
2753 return 0;
2754
2755 dts = (msr >> 16) & 0x7F;
b7d8c148 2756 fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_STATUS: 0x%08llx (%d C)\n",
889facbe
LB
2757 cpu, msr, tcc_activation_temp - dts);
2758
2759#ifdef THERM_DEBUG
2760 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, &msr))
2761 return 0;
2762
2763 dts = (msr >> 16) & 0x7F;
2764 dts2 = (msr >> 8) & 0x7F;
b7d8c148 2765 fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
889facbe
LB
2766 cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
2767#endif
2768 }
2769
2770
2771 if (do_dts) {
2772 unsigned int resolution;
2773
2774 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
2775 return 0;
2776
2777 dts = (msr >> 16) & 0x7F;
2778 resolution = (msr >> 27) & 0xF;
b7d8c148 2779 fprintf(outf, "cpu%d: MSR_IA32_THERM_STATUS: 0x%08llx (%d C +/- %d)\n",
889facbe
LB
2780 cpu, msr, tcc_activation_temp - dts, resolution);
2781
2782#ifdef THERM_DEBUG
2783 if (get_msr(cpu, MSR_IA32_THERM_INTERRUPT, &msr))
2784 return 0;
2785
2786 dts = (msr >> 16) & 0x7F;
2787 dts2 = (msr >> 8) & 0x7F;
b7d8c148 2788 fprintf(outf, "cpu%d: MSR_IA32_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
889facbe
LB
2789 cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
2790#endif
2791 }
2792
2793 return 0;
2794}
36229897 2795
889facbe
LB
2796void print_power_limit_msr(int cpu, unsigned long long msr, char *label)
2797{
b7d8c148 2798 fprintf(outf, "cpu%d: %s: %sabled (%f Watts, %f sec, clamp %sabled)\n",
889facbe
LB
2799 cpu, label,
2800 ((msr >> 15) & 1) ? "EN" : "DIS",
2801 ((msr >> 0) & 0x7FFF) * rapl_power_units,
2802 (1.0 + (((msr >> 22) & 0x3)/4.0)) * (1 << ((msr >> 17) & 0x1F)) * rapl_time_units,
2803 (((msr >> 16) & 1) ? "EN" : "DIS"));
2804
2805 return;
2806}
2807
2808int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2809{
2810 unsigned long long msr;
2811 int cpu;
889facbe
LB
2812
2813 if (!do_rapl)
2814 return 0;
2815
2816 /* RAPL counters are per package, so print only for 1st thread/package */
2817 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
2818 return 0;
2819
2820 cpu = t->cpu_id;
2821 if (cpu_migrate(cpu)) {
b7d8c148 2822 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
889facbe
LB
2823 return -1;
2824 }
2825
2826 if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr))
2827 return -1;
2828
d8af6f5f 2829 if (debug) {
b7d8c148 2830 fprintf(outf, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx "
889facbe 2831 "(%f Watts, %f Joules, %f sec.)\n", cpu, msr,
144b44b1 2832 rapl_power_units, rapl_energy_units, rapl_time_units);
889facbe 2833 }
144b44b1
LB
2834 if (do_rapl & RAPL_PKG_POWER_INFO) {
2835
889facbe
LB
2836 if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr))
2837 return -5;
2838
2839
b7d8c148 2840 fprintf(outf, "cpu%d: MSR_PKG_POWER_INFO: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
889facbe
LB
2841 cpu, msr,
2842 ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
2843 ((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
2844 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units,
2845 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
2846
144b44b1
LB
2847 }
2848 if (do_rapl & RAPL_PKG) {
2849
889facbe
LB
2850 if (get_msr(cpu, MSR_PKG_POWER_LIMIT, &msr))
2851 return -9;
2852
b7d8c148 2853 fprintf(outf, "cpu%d: MSR_PKG_POWER_LIMIT: 0x%08llx (%slocked)\n",
889facbe
LB
2854 cpu, msr, (msr >> 63) & 1 ? "": "UN");
2855
2856 print_power_limit_msr(cpu, msr, "PKG Limit #1");
b7d8c148 2857 fprintf(outf, "cpu%d: PKG Limit #2: %sabled (%f Watts, %f* sec, clamp %sabled)\n",
889facbe
LB
2858 cpu,
2859 ((msr >> 47) & 1) ? "EN" : "DIS",
2860 ((msr >> 32) & 0x7FFF) * rapl_power_units,
2861 (1.0 + (((msr >> 54) & 0x3)/4.0)) * (1 << ((msr >> 49) & 0x1F)) * rapl_time_units,
2862 ((msr >> 48) & 1) ? "EN" : "DIS");
2863 }
2864
0b2bb692 2865 if (do_rapl & RAPL_DRAM_POWER_INFO) {
889facbe
LB
2866 if (get_msr(cpu, MSR_DRAM_POWER_INFO, &msr))
2867 return -6;
2868
b7d8c148 2869 fprintf(outf, "cpu%d: MSR_DRAM_POWER_INFO,: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
889facbe
LB
2870 cpu, msr,
2871 ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
2872 ((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
2873 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units,
2874 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
0b2bb692
LB
2875 }
2876 if (do_rapl & RAPL_DRAM) {
889facbe
LB
2877 if (get_msr(cpu, MSR_DRAM_POWER_LIMIT, &msr))
2878 return -9;
b7d8c148 2879 fprintf(outf, "cpu%d: MSR_DRAM_POWER_LIMIT: 0x%08llx (%slocked)\n",
889facbe
LB
2880 cpu, msr, (msr >> 31) & 1 ? "": "UN");
2881
2882 print_power_limit_msr(cpu, msr, "DRAM Limit");
2883 }
144b44b1 2884 if (do_rapl & RAPL_CORE_POLICY) {
d8af6f5f 2885 if (debug) {
889facbe
LB
2886 if (get_msr(cpu, MSR_PP0_POLICY, &msr))
2887 return -7;
2888
b7d8c148 2889 fprintf(outf, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF);
144b44b1
LB
2890 }
2891 }
9148494c 2892 if (do_rapl & RAPL_CORES_POWER_LIMIT) {
d8af6f5f 2893 if (debug) {
889facbe
LB
2894 if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr))
2895 return -9;
b7d8c148 2896 fprintf(outf, "cpu%d: MSR_PP0_POWER_LIMIT: 0x%08llx (%slocked)\n",
889facbe
LB
2897 cpu, msr, (msr >> 31) & 1 ? "": "UN");
2898 print_power_limit_msr(cpu, msr, "Cores Limit");
2899 }
2900 }
2901 if (do_rapl & RAPL_GFX) {
d8af6f5f 2902 if (debug) {
889facbe
LB
2903 if (get_msr(cpu, MSR_PP1_POLICY, &msr))
2904 return -8;
2905
b7d8c148 2906 fprintf(outf, "cpu%d: MSR_PP1_POLICY: %lld\n", cpu, msr & 0xF);
889facbe
LB
2907
2908 if (get_msr(cpu, MSR_PP1_POWER_LIMIT, &msr))
2909 return -9;
b7d8c148 2910 fprintf(outf, "cpu%d: MSR_PP1_POWER_LIMIT: 0x%08llx (%slocked)\n",
889facbe
LB
2911 cpu, msr, (msr >> 31) & 1 ? "": "UN");
2912 print_power_limit_msr(cpu, msr, "GFX Limit");
2913 }
2914 }
2915 return 0;
2916}
2917
d7899447
LB
2918/*
2919 * SNB adds support for additional MSRs:
2920 *
2921 * MSR_PKG_C7_RESIDENCY 0x000003fa
2922 * MSR_CORE_C7_RESIDENCY 0x000003fe
2923 * MSR_PKG_C2_RESIDENCY 0x0000060d
2924 */
103a8fea 2925
d7899447 2926int has_snb_msrs(unsigned int family, unsigned int model)
103a8fea
LB
2927{
2928 if (!genuine_intel)
2929 return 0;
2930
2931 switch (model) {
869ce69e
LB
2932 case INTEL_FAM6_SANDYBRIDGE:
2933 case INTEL_FAM6_SANDYBRIDGE_X:
2934 case INTEL_FAM6_IVYBRIDGE: /* IVB */
2935 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
2936 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2937 case INTEL_FAM6_HASWELL_X: /* HSW */
2938 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2939 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
2940 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2941 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
2942 case INTEL_FAM6_BROADWELL_X: /* BDX */
2943 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2944 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2945 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2946 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2947 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
2948 case INTEL_FAM6_SKYLAKE_X: /* SKX */
2949 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
5bbac26e 2950 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
103a8fea
LB
2951 return 1;
2952 }
2953 return 0;
2954}
2955
d7899447
LB
2956/*
2957 * HSW adds support for additional MSRs:
2958 *
5a63426e
LB
2959 * MSR_PKG_C8_RESIDENCY 0x00000630
2960 * MSR_PKG_C9_RESIDENCY 0x00000631
2961 * MSR_PKG_C10_RESIDENCY 0x00000632
2962 *
2963 * MSR_PKGC8_IRTL 0x00000633
2964 * MSR_PKGC9_IRTL 0x00000634
2965 * MSR_PKGC10_IRTL 0x00000635
2966 *
d7899447
LB
2967 */
2968int has_hsw_msrs(unsigned int family, unsigned int model)
ca58710f
KCA
2969{
2970 if (!genuine_intel)
2971 return 0;
2972
2973 switch (model) {
869ce69e
LB
2974 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2975 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2976 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2977 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2978 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2979 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
2980 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
0b2bb692
LB
2981 return 1;
2982 }
2983 return 0;
2984}
2985
2986/*
2987 * SKL adds support for additional MSRS:
2988 *
2989 * MSR_PKG_WEIGHTED_CORE_C0_RES 0x00000658
2990 * MSR_PKG_ANY_CORE_C0_RES 0x00000659
2991 * MSR_PKG_ANY_GFXE_C0_RES 0x0000065A
2992 * MSR_PKG_BOTH_CORE_GFXE_C0_RES 0x0000065B
2993 */
2994int has_skl_msrs(unsigned int family, unsigned int model)
2995{
2996 if (!genuine_intel)
2997 return 0;
2998
2999 switch (model) {
869ce69e
LB
3000 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
3001 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
3002 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3003 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
ca58710f
KCA
3004 return 1;
3005 }
3006 return 0;
3007}
3008
3009
0b2bb692 3010
144b44b1
LB
3011int is_slm(unsigned int family, unsigned int model)
3012{
3013 if (!genuine_intel)
3014 return 0;
3015 switch (model) {
869ce69e
LB
3016 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
3017 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
144b44b1
LB
3018 return 1;
3019 }
3020 return 0;
3021}
3022
fb5d4327
DC
3023int is_knl(unsigned int family, unsigned int model)
3024{
3025 if (!genuine_intel)
3026 return 0;
3027 switch (model) {
869ce69e 3028 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
005c82d6 3029 case INTEL_FAM6_XEON_PHI_KNM:
fb5d4327
DC
3030 return 1;
3031 }
3032 return 0;
3033}
3034
b2b34dfe
HC
3035unsigned int get_aperf_mperf_multiplier(unsigned int family, unsigned int model)
3036{
3037 if (is_knl(family, model))
3038 return 1024;
3039 return 1;
3040}
3041
144b44b1
LB
3042#define SLM_BCLK_FREQS 5
3043double slm_freq_table[SLM_BCLK_FREQS] = { 83.3, 100.0, 133.3, 116.7, 80.0};
3044
3045double slm_bclk(void)
3046{
3047 unsigned long long msr = 3;
3048 unsigned int i;
3049 double freq;
3050
7ce7d5de 3051 if (get_msr(base_cpu, MSR_FSB_FREQ, &msr))
b7d8c148 3052 fprintf(outf, "SLM BCLK: unknown\n");
144b44b1
LB
3053
3054 i = msr & 0xf;
3055 if (i >= SLM_BCLK_FREQS) {
b7d8c148 3056 fprintf(outf, "SLM BCLK[%d] invalid\n", i);
0a91e551 3057 i = 3;
144b44b1
LB
3058 }
3059 freq = slm_freq_table[i];
3060
b7d8c148 3061 fprintf(outf, "SLM BCLK: %.1f Mhz\n", freq);
144b44b1
LB
3062
3063 return freq;
3064}
3065
103a8fea
LB
3066double discover_bclk(unsigned int family, unsigned int model)
3067{
121b48bb 3068 if (has_snb_msrs(family, model) || is_knl(family, model))
103a8fea 3069 return 100.00;
144b44b1
LB
3070 else if (is_slm(family, model))
3071 return slm_bclk();
103a8fea
LB
3072 else
3073 return 133.33;
3074}
3075
889facbe
LB
3076/*
3077 * MSR_IA32_TEMPERATURE_TARGET indicates the temperature where
3078 * the Thermal Control Circuit (TCC) activates.
3079 * This is usually equal to tjMax.
3080 *
3081 * Older processors do not have this MSR, so there we guess,
3082 * but also allow cmdline over-ride with -T.
3083 *
3084 * Several MSR temperature values are in units of degrees-C
3085 * below this value, including the Digital Thermal Sensor (DTS),
3086 * Package Thermal Management Sensor (PTM), and thermal event thresholds.
3087 */
3088int set_temperature_target(struct thread_data *t, struct core_data *c, struct pkg_data *p)
3089{
3090 unsigned long long msr;
3091 unsigned int target_c_local;
3092 int cpu;
3093
3094 /* tcc_activation_temp is used only for dts or ptm */
3095 if (!(do_dts || do_ptm))
3096 return 0;
3097
3098 /* this is a per-package concept */
3099 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
3100 return 0;
3101
3102 cpu = t->cpu_id;
3103 if (cpu_migrate(cpu)) {
b7d8c148 3104 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
889facbe
LB
3105 return -1;
3106 }
3107
3108 if (tcc_activation_temp_override != 0) {
3109 tcc_activation_temp = tcc_activation_temp_override;
b7d8c148 3110 fprintf(outf, "cpu%d: Using cmdline TCC Target (%d C)\n",
889facbe
LB
3111 cpu, tcc_activation_temp);
3112 return 0;
3113 }
3114
3115 /* Temperature Target MSR is Nehalem and newer only */
d7899447 3116 if (!do_nhm_platform_info)
889facbe
LB
3117 goto guess;
3118
7ce7d5de 3119 if (get_msr(base_cpu, MSR_IA32_TEMPERATURE_TARGET, &msr))
889facbe
LB
3120 goto guess;
3121
3482124a 3122 target_c_local = (msr >> 16) & 0xFF;
889facbe 3123
d8af6f5f 3124 if (debug)
b7d8c148 3125 fprintf(outf, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
889facbe
LB
3126 cpu, msr, target_c_local);
3127
3482124a 3128 if (!target_c_local)
889facbe
LB
3129 goto guess;
3130
3131 tcc_activation_temp = target_c_local;
3132
3133 return 0;
3134
3135guess:
3136 tcc_activation_temp = TJMAX_DEFAULT;
b7d8c148 3137 fprintf(outf, "cpu%d: Guessing tjMax %d C, Please use -T to specify\n",
889facbe
LB
3138 cpu, tcc_activation_temp);
3139
3140 return 0;
3141}
69807a63 3142
aa8d8cc7
LB
3143void decode_feature_control_msr(void)
3144{
3145 unsigned long long msr;
3146
3147 if (!get_msr(base_cpu, MSR_IA32_FEATURE_CONTROL, &msr))
3148 fprintf(outf, "cpu%d: MSR_IA32_FEATURE_CONTROL: 0x%08llx (%sLocked %s)\n",
3149 base_cpu, msr,
3150 msr & FEATURE_CONTROL_LOCKED ? "" : "UN-",
3151 msr & (1 << 18) ? "SGX" : "");
3152}
3153
69807a63
LB
3154void decode_misc_enable_msr(void)
3155{
3156 unsigned long long msr;
3157
3158 if (!get_msr(base_cpu, MSR_IA32_MISC_ENABLE, &msr))
b7d8c148 3159 fprintf(outf, "cpu%d: MSR_IA32_MISC_ENABLE: 0x%08llx (%s %s %s)\n",
69807a63
LB
3160 base_cpu, msr,
3161 msr & (1 << 3) ? "TCC" : "",
3162 msr & (1 << 16) ? "EIST" : "",
3163 msr & (1 << 18) ? "MONITOR" : "");
3164}
3165
f0057310
LB
3166/*
3167 * Decode MSR_MISC_PWR_MGMT
3168 *
3169 * Decode the bits according to the Nehalem documentation
3170 * bit[0] seems to continue to have same meaning going forward
3171 * bit[1] less so...
3172 */
3173void decode_misc_pwr_mgmt_msr(void)
3174{
3175 unsigned long long msr;
3176
3177 if (!do_nhm_platform_info)
3178 return;
3179
3180 if (!get_msr(base_cpu, MSR_MISC_PWR_MGMT, &msr))
ddadb8ad 3181 fprintf(outf, "cpu%d: MSR_MISC_PWR_MGMT: 0x%08llx (%sable-EIST_Coordination %sable-EPB %sable-OOB)\n",
f0057310
LB
3182 base_cpu, msr,
3183 msr & (1 << 0) ? "DIS" : "EN",
ddadb8ad
SP
3184 msr & (1 << 1) ? "EN" : "DIS",
3185 msr & (1 << 8) ? "EN" : "DIS");
f0057310 3186}
7f5c258e 3187
fcd17211 3188void process_cpuid()
103a8fea 3189{
61a87ba7 3190 unsigned int eax, ebx, ecx, edx, max_level, max_extended_level;
103a8fea
LB
3191 unsigned int fms, family, model, stepping;
3192
3193 eax = ebx = ecx = edx = 0;
3194
5aea2f7f 3195 __cpuid(0, max_level, ebx, ecx, edx);
103a8fea
LB
3196
3197 if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)
3198 genuine_intel = 1;
3199
d8af6f5f 3200 if (debug)
b7d8c148 3201 fprintf(outf, "CPUID(0): %.4s%.4s%.4s ",
103a8fea
LB
3202 (char *)&ebx, (char *)&edx, (char *)&ecx);
3203
5aea2f7f 3204 __cpuid(1, fms, ebx, ecx, edx);
103a8fea
LB
3205 family = (fms >> 8) & 0xf;
3206 model = (fms >> 4) & 0xf;
3207 stepping = fms & 0xf;
3208 if (family == 6 || family == 0xf)
3209 model += ((fms >> 16) & 0xf) << 4;
3210
69807a63 3211 if (debug) {
b7d8c148 3212 fprintf(outf, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
103a8fea 3213 max_level, family, model, stepping, family, model, stepping);
aa8d8cc7 3214 fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s\n",
69807a63
LB
3215 ecx & (1 << 0) ? "SSE3" : "-",
3216 ecx & (1 << 3) ? "MONITOR" : "-",
aa8d8cc7 3217 ecx & (1 << 6) ? "SMX" : "-",
69807a63
LB
3218 ecx & (1 << 7) ? "EIST" : "-",
3219 ecx & (1 << 8) ? "TM2" : "-",
3220 edx & (1 << 4) ? "TSC" : "-",
3221 edx & (1 << 5) ? "MSR" : "-",
3222 edx & (1 << 22) ? "ACPI-TM" : "-",
3223 edx & (1 << 29) ? "TM" : "-");
3224 }
103a8fea 3225
b2c95d90
JT
3226 if (!(edx & (1 << 5)))
3227 errx(1, "CPUID: no MSR");
103a8fea
LB
3228
3229 /*
3230 * check max extended function levels of CPUID.
3231 * This is needed to check for invariant TSC.
3232 * This check is valid for both Intel and AMD.
3233 */
3234 ebx = ecx = edx = 0;
5aea2f7f 3235 __cpuid(0x80000000, max_extended_level, ebx, ecx, edx);
103a8fea 3236
61a87ba7 3237 if (max_extended_level >= 0x80000007) {
103a8fea 3238
d7899447
LB
3239 /*
3240 * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8
3241 * this check is valid for both Intel and AMD
3242 */
5aea2f7f 3243 __cpuid(0x80000007, eax, ebx, ecx, edx);
d7899447
LB
3244 has_invariant_tsc = edx & (1 << 8);
3245 }
103a8fea
LB
3246
3247 /*
3248 * APERF/MPERF is advertised by CPUID.EAX=0x6: ECX.bit0
3249 * this check is valid for both Intel and AMD
3250 */
3251
5aea2f7f 3252 __cpuid(0x6, eax, ebx, ecx, edx);
8209e054 3253 has_aperf = ecx & (1 << 0);
889facbe
LB
3254 do_dts = eax & (1 << 0);
3255 do_ptm = eax & (1 << 6);
7f5c258e
LB
3256 has_hwp = eax & (1 << 7);
3257 has_hwp_notify = eax & (1 << 8);
3258 has_hwp_activity_window = eax & (1 << 9);
3259 has_hwp_epp = eax & (1 << 10);
3260 has_hwp_pkg = eax & (1 << 11);
889facbe
LB
3261 has_epb = ecx & (1 << 3);
3262
d8af6f5f 3263 if (debug)
b7d8c148 3264 fprintf(outf, "CPUID(6): %sAPERF, %sDTS, %sPTM, %sHWP, "
7f5c258e
LB
3265 "%sHWPnotify, %sHWPwindow, %sHWPepp, %sHWPpkg, %sEPB\n",
3266 has_aperf ? "" : "No-",
3267 do_dts ? "" : "No-",
3268 do_ptm ? "" : "No-",
3269 has_hwp ? "" : "No-",
3270 has_hwp_notify ? "" : "No-",
3271 has_hwp_activity_window ? "" : "No-",
3272 has_hwp_epp ? "" : "No-",
3273 has_hwp_pkg ? "" : "No-",
3274 has_epb ? "" : "No-");
103a8fea 3275
69807a63
LB
3276 if (debug)
3277 decode_misc_enable_msr();
3278
8ae72255 3279 if (max_level >= 0x7 && debug) {
aa8d8cc7 3280 int has_sgx;
103a8fea 3281
aa8d8cc7
LB
3282 ecx = 0;
3283
3284 __cpuid_count(0x7, 0, eax, ebx, ecx, edx);
3285
3286 has_sgx = ebx & (1 << 2);
3287 fprintf(outf, "CPUID(7): %sSGX\n", has_sgx ? "" : "No-");
3288
3289 if (has_sgx)
3290 decode_feature_control_msr();
3291 }
3292
61a87ba7 3293 if (max_level >= 0x15) {
8a5bdf41
LB
3294 unsigned int eax_crystal;
3295 unsigned int ebx_tsc;
3296
3297 /*
3298 * CPUID 15H TSC/Crystal ratio, possibly Crystal Hz
3299 */
3300 eax_crystal = ebx_tsc = crystal_hz = edx = 0;
5aea2f7f 3301 __cpuid(0x15, eax_crystal, ebx_tsc, crystal_hz, edx);
8a5bdf41
LB
3302
3303 if (ebx_tsc != 0) {
3304
3305 if (debug && (ebx != 0))
b7d8c148 3306 fprintf(outf, "CPUID(0x15): eax_crystal: %d ebx_tsc: %d ecx_crystal_hz: %d\n",
8a5bdf41
LB
3307 eax_crystal, ebx_tsc, crystal_hz);
3308
3309 if (crystal_hz == 0)
3310 switch(model) {
869ce69e
LB
3311 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
3312 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
3313 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3314 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
e8efbc80
LB
3315 crystal_hz = 24000000; /* 24.0 MHz */
3316 break;
869ce69e 3317 case INTEL_FAM6_SKYLAKE_X: /* SKX */
ec53e594
LB
3318 crystal_hz = 25000000; /* 25.0 MHz */
3319 break;
869ce69e
LB
3320 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
3321 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
e8efbc80 3322 crystal_hz = 19200000; /* 19.2 MHz */
8a5bdf41
LB
3323 break;
3324 default:
3325 crystal_hz = 0;
3326 }
3327
3328 if (crystal_hz) {
3329 tsc_hz = (unsigned long long) crystal_hz * ebx_tsc / eax_crystal;
3330 if (debug)
b7d8c148 3331 fprintf(outf, "TSC: %lld MHz (%d Hz * %d / %d / 1000000)\n",
8a5bdf41
LB
3332 tsc_hz / 1000000, crystal_hz, ebx_tsc, eax_crystal);
3333 }
3334 }
3335 }
61a87ba7
LB
3336 if (max_level >= 0x16) {
3337 unsigned int base_mhz, max_mhz, bus_mhz, edx;
3338
3339 /*
3340 * CPUID 16H Base MHz, Max MHz, Bus MHz
3341 */
3342 base_mhz = max_mhz = bus_mhz = edx = 0;
3343
5aea2f7f 3344 __cpuid(0x16, base_mhz, max_mhz, bus_mhz, edx);
61a87ba7 3345 if (debug)
b7d8c148 3346 fprintf(outf, "CPUID(0x16): base_mhz: %d max_mhz: %d bus_mhz: %d\n",
61a87ba7
LB
3347 base_mhz, max_mhz, bus_mhz);
3348 }
8a5bdf41 3349
b2b34dfe
HC
3350 if (has_aperf)
3351 aperf_mperf_multiplier = get_aperf_mperf_multiplier(family, model);
3352
ee7e38e3 3353 do_nhm_platform_info = do_nhm_cstates = do_smi = probe_nhm_msrs(family, model);
d7899447 3354 do_snb_cstates = has_snb_msrs(family, model);
5a63426e 3355 do_irtl_snb = has_snb_msrs(family, model);
ee7e38e3
LB
3356 do_pc2 = do_snb_cstates && (pkg_cstate_limit >= PCL__2);
3357 do_pc3 = (pkg_cstate_limit >= PCL__3);
3358 do_pc6 = (pkg_cstate_limit >= PCL__6);
3359 do_pc7 = do_snb_cstates && (pkg_cstate_limit >= PCL__7);
d7899447 3360 do_c8_c9_c10 = has_hsw_msrs(family, model);
5a63426e 3361 do_irtl_hsw = has_hsw_msrs(family, model);
0b2bb692 3362 do_skl_residency = has_skl_msrs(family, model);
144b44b1 3363 do_slm_cstates = is_slm(family, model);
fb5d4327 3364 do_knl_cstates = is_knl(family, model);
103a8fea 3365
f0057310
LB
3366 if (debug)
3367 decode_misc_pwr_mgmt_msr();
3368
889facbe 3369 rapl_probe(family, model);
3a9a941d 3370 perf_limit_reasons_probe(family, model);
889facbe 3371
fcd17211 3372 if (debug)
1b69317d 3373 dump_cstate_pstate_config_info(family, model);
fcd17211 3374
a2b7b749
LB
3375 if (has_skl_msrs(family, model))
3376 calculate_tsc_tweak();
3377
fdf676e5
LB
3378 do_gfx_rc6_ms = !access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK);
3379
27d47356
LB
3380 do_gfx_mhz = !access("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", R_OK);
3381
889facbe 3382 return;
103a8fea
LB
3383}
3384
d8af6f5f 3385void help()
103a8fea 3386{
b7d8c148 3387 fprintf(outf,
d8af6f5f
LB
3388 "Usage: turbostat [OPTIONS][(--interval seconds) | COMMAND ...]\n"
3389 "\n"
3390 "Turbostat forks the specified COMMAND and prints statistics\n"
3391 "when COMMAND completes.\n"
3392 "If no COMMAND is specified, turbostat wakes every 5-seconds\n"
3393 "to print statistics, until interrupted.\n"
3394 "--debug run in \"debug\" mode\n"
3395 "--interval sec Override default 5-second measurement interval\n"
3396 "--help print this help message\n"
3397 "--counter msr print 32-bit counter at address \"msr\"\n"
3398 "--Counter msr print 64-bit Counter at address \"msr\"\n"
b7d8c148 3399 "--out file create or truncate \"file\" for all output\n"
d8af6f5f
LB
3400 "--msr msr print 32-bit value at address \"msr\"\n"
3401 "--MSR msr print 64-bit Value at address \"msr\"\n"
3402 "--version print version information\n"
3403 "\n"
3404 "For more help, run \"man turbostat\"\n");
103a8fea
LB
3405}
3406
3407
3408/*
3409 * in /dev/cpu/ return success for names that are numbers
3410 * ie. filter out ".", "..", "microcode".
3411 */
3412int dir_filter(const struct dirent *dirp)
3413{
3414 if (isdigit(dirp->d_name[0]))
3415 return 1;
3416 else
3417 return 0;
3418}
3419
3420int open_dev_cpu_msr(int dummy1)
3421{
3422 return 0;
3423}
3424
c98d5d94
LB
3425void topology_probe()
3426{
3427 int i;
3428 int max_core_id = 0;
3429 int max_package_id = 0;
3430 int max_siblings = 0;
3431 struct cpu_topology {
3432 int core_id;
3433 int physical_package_id;
3434 } *cpus;
3435
3436 /* Initialize num_cpus, max_cpu_num */
3437 topo.num_cpus = 0;
3438 topo.max_cpu_num = 0;
3439 for_all_proc_cpus(count_cpus);
3440 if (!summary_only && topo.num_cpus > 1)
3441 show_cpu = 1;
3442
d8af6f5f 3443 if (debug > 1)
b7d8c148 3444 fprintf(outf, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num);
c98d5d94
LB
3445
3446 cpus = calloc(1, (topo.max_cpu_num + 1) * sizeof(struct cpu_topology));
b2c95d90
JT
3447 if (cpus == NULL)
3448 err(1, "calloc cpus");
c98d5d94
LB
3449
3450 /*
3451 * Allocate and initialize cpu_present_set
3452 */
3453 cpu_present_set = CPU_ALLOC((topo.max_cpu_num + 1));
b2c95d90
JT
3454 if (cpu_present_set == NULL)
3455 err(3, "CPU_ALLOC");
c98d5d94
LB
3456 cpu_present_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
3457 CPU_ZERO_S(cpu_present_setsize, cpu_present_set);
3458 for_all_proc_cpus(mark_cpu_present);
3459
3460 /*
3461 * Allocate and initialize cpu_affinity_set
3462 */
3463 cpu_affinity_set = CPU_ALLOC((topo.max_cpu_num + 1));
b2c95d90
JT
3464 if (cpu_affinity_set == NULL)
3465 err(3, "CPU_ALLOC");
c98d5d94
LB
3466 cpu_affinity_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
3467 CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
3468
3469
3470 /*
3471 * For online cpus
3472 * find max_core_id, max_package_id
3473 */
3474 for (i = 0; i <= topo.max_cpu_num; ++i) {
3475 int siblings;
3476
3477 if (cpu_is_not_present(i)) {
d8af6f5f 3478 if (debug > 1)
b7d8c148 3479 fprintf(outf, "cpu%d NOT PRESENT\n", i);
c98d5d94
LB
3480 continue;
3481 }
3482 cpus[i].core_id = get_core_id(i);
3483 if (cpus[i].core_id > max_core_id)
3484 max_core_id = cpus[i].core_id;
3485
3486 cpus[i].physical_package_id = get_physical_package_id(i);
3487 if (cpus[i].physical_package_id > max_package_id)
3488 max_package_id = cpus[i].physical_package_id;
3489
3490 siblings = get_num_ht_siblings(i);
3491 if (siblings > max_siblings)
3492 max_siblings = siblings;
d8af6f5f 3493 if (debug > 1)
b7d8c148 3494 fprintf(outf, "cpu %d pkg %d core %d\n",
c98d5d94
LB
3495 i, cpus[i].physical_package_id, cpus[i].core_id);
3496 }
3497 topo.num_cores_per_pkg = max_core_id + 1;
d8af6f5f 3498 if (debug > 1)
b7d8c148 3499 fprintf(outf, "max_core_id %d, sizing for %d cores per package\n",
c98d5d94 3500 max_core_id, topo.num_cores_per_pkg);
1cc21f7b 3501 if (debug && !summary_only && topo.num_cores_per_pkg > 1)
c98d5d94
LB
3502 show_core = 1;
3503
3504 topo.num_packages = max_package_id + 1;
d8af6f5f 3505 if (debug > 1)
b7d8c148 3506 fprintf(outf, "max_package_id %d, sizing for %d packages\n",
c98d5d94 3507 max_package_id, topo.num_packages);
1cc21f7b 3508 if (debug && !summary_only && topo.num_packages > 1)
c98d5d94
LB
3509 show_pkg = 1;
3510
3511 topo.num_threads_per_core = max_siblings;
d8af6f5f 3512 if (debug > 1)
b7d8c148 3513 fprintf(outf, "max_siblings %d\n", max_siblings);
c98d5d94
LB
3514
3515 free(cpus);
3516}
3517
3518void
3519allocate_counters(struct thread_data **t, struct core_data **c, struct pkg_data **p)
3520{
3521 int i;
3522
3523 *t = calloc(topo.num_threads_per_core * topo.num_cores_per_pkg *
3524 topo.num_packages, sizeof(struct thread_data));
3525 if (*t == NULL)
3526 goto error;
3527
3528 for (i = 0; i < topo.num_threads_per_core *
3529 topo.num_cores_per_pkg * topo.num_packages; i++)
3530 (*t)[i].cpu_id = -1;
3531
3532 *c = calloc(topo.num_cores_per_pkg * topo.num_packages,
3533 sizeof(struct core_data));
3534 if (*c == NULL)
3535 goto error;
3536
3537 for (i = 0; i < topo.num_cores_per_pkg * topo.num_packages; i++)
3538 (*c)[i].core_id = -1;
3539
3540 *p = calloc(topo.num_packages, sizeof(struct pkg_data));
3541 if (*p == NULL)
3542 goto error;
3543
3544 for (i = 0; i < topo.num_packages; i++)
3545 (*p)[i].package_id = i;
3546
3547 return;
3548error:
b2c95d90 3549 err(1, "calloc counters");
c98d5d94
LB
3550}
3551/*
3552 * init_counter()
3553 *
3554 * set cpu_id, core_num, pkg_num
3555 * set FIRST_THREAD_IN_CORE and FIRST_CORE_IN_PACKAGE
3556 *
3557 * increment topo.num_cores when 1st core in pkg seen
3558 */
3559void init_counter(struct thread_data *thread_base, struct core_data *core_base,
3560 struct pkg_data *pkg_base, int thread_num, int core_num,
3561 int pkg_num, int cpu_id)
3562{
3563 struct thread_data *t;
3564 struct core_data *c;
3565 struct pkg_data *p;
3566
3567 t = GET_THREAD(thread_base, thread_num, core_num, pkg_num);
3568 c = GET_CORE(core_base, core_num, pkg_num);
3569 p = GET_PKG(pkg_base, pkg_num);
3570
3571 t->cpu_id = cpu_id;
3572 if (thread_num == 0) {
3573 t->flags |= CPU_IS_FIRST_THREAD_IN_CORE;
3574 if (cpu_is_first_core_in_package(cpu_id))
3575 t->flags |= CPU_IS_FIRST_CORE_IN_PACKAGE;
3576 }
3577
3578 c->core_id = core_num;
3579 p->package_id = pkg_num;
3580}
3581
3582
3583int initialize_counters(int cpu_id)
3584{
3585 int my_thread_id, my_core_id, my_package_id;
3586
3587 my_package_id = get_physical_package_id(cpu_id);
3588 my_core_id = get_core_id(cpu_id);
e275b388
DC
3589 my_thread_id = get_cpu_position_in_core(cpu_id);
3590 if (!my_thread_id)
c98d5d94 3591 topo.num_cores++;
c98d5d94
LB
3592
3593 init_counter(EVEN_COUNTERS, my_thread_id, my_core_id, my_package_id, cpu_id);
3594 init_counter(ODD_COUNTERS, my_thread_id, my_core_id, my_package_id, cpu_id);
3595 return 0;
3596}
3597
3598void allocate_output_buffer()
3599{
3b4d5c7f 3600 output_buffer = calloc(1, (1 + topo.num_cpus) * 1024);
c98d5d94 3601 outp = output_buffer;
b2c95d90
JT
3602 if (outp == NULL)
3603 err(-1, "calloc output buffer");
c98d5d94 3604}
36229897
LB
3605void allocate_fd_percpu(void)
3606{
01a67adf 3607 fd_percpu = calloc(topo.max_cpu_num + 1, sizeof(int));
36229897
LB
3608 if (fd_percpu == NULL)
3609 err(-1, "calloc fd_percpu");
3610}
562a2d37
LB
3611void allocate_irq_buffers(void)
3612{
3613 irq_column_2_cpu = calloc(topo.num_cpus, sizeof(int));
3614 if (irq_column_2_cpu == NULL)
3615 err(-1, "calloc %d", topo.num_cpus);
c98d5d94 3616
01a67adf 3617 irqs_per_cpu = calloc(topo.max_cpu_num + 1, sizeof(int));
562a2d37 3618 if (irqs_per_cpu == NULL)
01a67adf 3619 err(-1, "calloc %d", topo.max_cpu_num + 1);
562a2d37 3620}
c98d5d94
LB
3621void setup_all_buffers(void)
3622{
3623 topology_probe();
562a2d37 3624 allocate_irq_buffers();
36229897 3625 allocate_fd_percpu();
c98d5d94
LB
3626 allocate_counters(&thread_even, &core_even, &package_even);
3627 allocate_counters(&thread_odd, &core_odd, &package_odd);
3628 allocate_output_buffer();
3629 for_all_proc_cpus(initialize_counters);
3630}
3b4d5c7f 3631
7ce7d5de
PB
3632void set_base_cpu(void)
3633{
3634 base_cpu = sched_getcpu();
3635 if (base_cpu < 0)
3636 err(-ENODEV, "No valid cpus found");
3637
3638 if (debug > 1)
b7d8c148 3639 fprintf(outf, "base_cpu = %d\n", base_cpu);
7ce7d5de
PB
3640}
3641
103a8fea
LB
3642void turbostat_init()
3643{
7ce7d5de
PB
3644 setup_all_buffers();
3645 set_base_cpu();
103a8fea 3646 check_dev_msr();
98481e79 3647 check_permissions();
fcd17211 3648 process_cpuid();
103a8fea 3649
103a8fea 3650
7f5c258e
LB
3651 if (debug)
3652 for_all_cpus(print_hwp, ODD_COUNTERS);
3653
d8af6f5f 3654 if (debug)
889facbe
LB
3655 for_all_cpus(print_epb, ODD_COUNTERS);
3656
d8af6f5f 3657 if (debug)
3a9a941d
LB
3658 for_all_cpus(print_perf_limit, ODD_COUNTERS);
3659
d8af6f5f 3660 if (debug)
889facbe
LB
3661 for_all_cpus(print_rapl, ODD_COUNTERS);
3662
3663 for_all_cpus(set_temperature_target, ODD_COUNTERS);
3664
d8af6f5f 3665 if (debug)
889facbe 3666 for_all_cpus(print_thermal, ODD_COUNTERS);
5a63426e
LB
3667
3668 if (debug && do_irtl_snb)
3669 print_irtl();
103a8fea
LB
3670}
3671
3672int fork_it(char **argv)
3673{
103a8fea 3674 pid_t child_pid;
d91bb17c 3675 int status;
d15cf7c1 3676
d91bb17c
LB
3677 status = for_all_cpus(get_counters, EVEN_COUNTERS);
3678 if (status)
3679 exit(status);
c98d5d94
LB
3680 /* clear affinity side-effect of get_counters() */
3681 sched_setaffinity(0, cpu_present_setsize, cpu_present_set);
103a8fea
LB
3682 gettimeofday(&tv_even, (struct timezone *)NULL);
3683
3684 child_pid = fork();
3685 if (!child_pid) {
3686 /* child */
3687 execvp(argv[0], argv);
3688 } else {
103a8fea
LB
3689
3690 /* parent */
b2c95d90
JT
3691 if (child_pid == -1)
3692 err(1, "fork");
103a8fea
LB
3693
3694 signal(SIGINT, SIG_IGN);
3695 signal(SIGQUIT, SIG_IGN);
b2c95d90
JT
3696 if (waitpid(child_pid, &status, 0) == -1)
3697 err(status, "waitpid");
103a8fea 3698 }
c98d5d94
LB
3699 /*
3700 * n.b. fork_it() does not check for errors from for_all_cpus()
3701 * because re-starting is problematic when forking
3702 */
3703 for_all_cpus(get_counters, ODD_COUNTERS);
103a8fea 3704 gettimeofday(&tv_odd, (struct timezone *)NULL);
103a8fea 3705 timersub(&tv_odd, &tv_even, &tv_delta);
ba3dec99
LB
3706 if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS))
3707 fprintf(outf, "%s: Counter reset detected\n", progname);
3708 else {
3709 compute_average(EVEN_COUNTERS);
3710 format_all_counters(EVEN_COUNTERS);
3711 }
103a8fea 3712
b7d8c148
LB
3713 fprintf(outf, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0);
3714
3715 flush_output_stderr();
103a8fea 3716
d91bb17c 3717 return status;
103a8fea
LB
3718}
3719
3b4d5c7f
AS
3720int get_and_dump_counters(void)
3721{
3722 int status;
3723
3724 status = for_all_cpus(get_counters, ODD_COUNTERS);
3725 if (status)
3726 return status;
3727
3728 status = for_all_cpus(dump_counters, ODD_COUNTERS);
3729 if (status)
3730 return status;
3731
b7d8c148 3732 flush_output_stdout();
3b4d5c7f
AS
3733
3734 return status;
3735}
3736
d8af6f5f 3737void print_version() {
3d109de2 3738 fprintf(outf, "turbostat version 4.14 22 Apr 2016"
d8af6f5f
LB
3739 " - Len Brown <lenb@kernel.org>\n");
3740}
3741
103a8fea
LB
3742void cmdline(int argc, char **argv)
3743{
3744 int opt;
d8af6f5f
LB
3745 int option_index = 0;
3746 static struct option long_options[] = {
3747 {"Counter", required_argument, 0, 'C'},
3748 {"counter", required_argument, 0, 'c'},
3749 {"Dump", no_argument, 0, 'D'},
3750 {"debug", no_argument, 0, 'd'},
3751 {"interval", required_argument, 0, 'i'},
3752 {"help", no_argument, 0, 'h'},
3753 {"Joules", no_argument, 0, 'J'},
3754 {"MSR", required_argument, 0, 'M'},
3755 {"msr", required_argument, 0, 'm'},
b7d8c148 3756 {"out", required_argument, 0, 'o'},
d8af6f5f
LB
3757 {"Package", no_argument, 0, 'p'},
3758 {"processor", no_argument, 0, 'p'},
3759 {"Summary", no_argument, 0, 'S'},
3760 {"TCC", required_argument, 0, 'T'},
3761 {"version", no_argument, 0, 'v' },
3762 {0, 0, 0, 0 }
3763 };
103a8fea
LB
3764
3765 progname = argv[0];
3766
b7d8c148 3767 while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:JM:m:o:PpST:v",
d8af6f5f 3768 long_options, &option_index)) != -1) {
103a8fea 3769 switch (opt) {
d8af6f5f
LB
3770 case 'C':
3771 sscanf(optarg, "%x", &extra_delta_offset64);
c98d5d94 3772 break;
d8af6f5f
LB
3773 case 'c':
3774 sscanf(optarg, "%x", &extra_delta_offset32);
c98d5d94 3775 break;
d8af6f5f 3776 case 'D':
3b4d5c7f
AS
3777 dump_only++;
3778 break;
d8af6f5f
LB
3779 case 'd':
3780 debug++;
103a8fea 3781 break;
d8af6f5f
LB
3782 case 'h':
3783 default:
3784 help();
3785 exit(1);
103a8fea 3786 case 'i':
2a0609c0
LB
3787 {
3788 double interval = strtod(optarg, NULL);
3789
3790 if (interval < 0.001) {
b7d8c148 3791 fprintf(outf, "interval %f seconds is too small\n",
2a0609c0
LB
3792 interval);
3793 exit(2);
3794 }
3795
3796 interval_ts.tv_sec = interval;
3797 interval_ts.tv_nsec = (interval - interval_ts.tv_sec) * 1000000000;
3798 }
103a8fea 3799 break;
d8af6f5f
LB
3800 case 'J':
3801 rapl_joules++;
8e180f3c 3802 break;
d8af6f5f
LB
3803 case 'M':
3804 sscanf(optarg, "%x", &extra_msr_offset64);
8e180f3c 3805 break;
2f32edf1
LB
3806 case 'm':
3807 sscanf(optarg, "%x", &extra_msr_offset32);
2f32edf1 3808 break;
b7d8c148
LB
3809 case 'o':
3810 outf = fopen_or_die(optarg, "w");
3811 break;
d8af6f5f
LB
3812 case 'P':
3813 show_pkg_only++;
3814 break;
3815 case 'p':
3816 show_core_only++;
103a8fea 3817 break;
d8af6f5f
LB
3818 case 'S':
3819 summary_only++;
889facbe
LB
3820 break;
3821 case 'T':
3822 tcc_activation_temp_override = atoi(optarg);
3823 break;
d8af6f5f
LB
3824 case 'v':
3825 print_version();
3826 exit(0);
5c56be9a 3827 break;
103a8fea
LB
3828 }
3829 }
3830}
3831
3832int main(int argc, char **argv)
3833{
b7d8c148
LB
3834 outf = stderr;
3835
103a8fea
LB
3836 cmdline(argc, argv);
3837
d8af6f5f
LB
3838 if (debug)
3839 print_version();
103a8fea
LB
3840
3841 turbostat_init();
3842
3b4d5c7f
AS
3843 /* dump counters and exit */
3844 if (dump_only)
3845 return get_and_dump_counters();
3846
103a8fea
LB
3847 /*
3848 * if any params left, it must be a command to fork
3849 */
3850 if (argc - optind)
3851 return fork_it(argv + optind);
3852 else
3853 turbostat_loop();
3854
3855 return 0;
3856}