tools/power turbostat: if --num_iterations, print for specific number of iterations
[linux-block.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>
b9ad8ee0 32#include <sys/select.h>
103a8fea
LB
33#include <sys/resource.h>
34#include <fcntl.h>
35#include <signal.h>
36#include <sys/time.h>
37#include <stdlib.h>
d8af6f5f 38#include <getopt.h>
103a8fea
LB
39#include <dirent.h>
40#include <string.h>
41#include <ctype.h>
88c3281f 42#include <sched.h>
2a0609c0 43#include <time.h>
2b92865e 44#include <cpuid.h>
98481e79
LB
45#include <linux/capability.h>
46#include <errno.h>
103a8fea 47
103a8fea 48char *proc_stat = "/proc/stat";
b7d8c148 49FILE *outf;
36229897 50int *fd_percpu;
b9ad8ee0 51struct timeval interval_tv = {5, 0};
47936f94 52struct timespec interval_ts = {5, 0};
b9ad8ee0 53struct timespec one_msec = {0, 1000000};
023fe0ac 54unsigned int num_iterations;
d8af6f5f 55unsigned int debug;
96e47158 56unsigned int quiet;
3f44a5c6 57unsigned int shown;
0de6c0df 58unsigned int sums_need_wide_columns;
d8af6f5f
LB
59unsigned int rapl_joules;
60unsigned int summary_only;
c8ade361 61unsigned int list_header_only;
d8af6f5f 62unsigned int dump_only;
103a8fea 63unsigned int do_snb_cstates;
fb5d4327 64unsigned int do_knl_cstates;
144b44b1 65unsigned int do_slm_cstates;
997e5395 66unsigned int do_cnl_cstates;
144b44b1 67unsigned int use_c1_residency_msr;
103a8fea 68unsigned int has_aperf;
889facbe 69unsigned int has_epb;
5a63426e
LB
70unsigned int do_irtl_snb;
71unsigned int do_irtl_hsw;
fc04cc67 72unsigned int units = 1000000; /* MHz etc */
103a8fea
LB
73unsigned int genuine_intel;
74unsigned int has_invariant_tsc;
d7899447 75unsigned int do_nhm_platform_info;
cf4cbe53 76unsigned int no_MSR_MISC_PWR_MGMT;
b2b34dfe 77unsigned int aperf_mperf_multiplier = 1;
103a8fea 78double bclk;
a2b7b749 79double base_hz;
21ed5574 80unsigned int has_base_hz;
a2b7b749 81double tsc_tweak = 1.0;
c98d5d94
LB
82unsigned int show_pkg_only;
83unsigned int show_core_only;
84char *output_buffer, *outp;
889facbe
LB
85unsigned int do_rapl;
86unsigned int do_dts;
87unsigned int do_ptm;
fdf676e5 88unsigned long long gfx_cur_rc6_ms;
be0e54c4
LB
89unsigned long long cpuidle_cur_cpu_lpi_us;
90unsigned long long cpuidle_cur_sys_lpi_us;
27d47356 91unsigned int gfx_cur_mhz;
889facbe
LB
92unsigned int tcc_activation_temp;
93unsigned int tcc_activation_temp_override;
40ee8e3b
AS
94double rapl_power_units, rapl_time_units;
95double rapl_dram_energy_units, rapl_energy_units;
889facbe 96double rapl_joule_counter_range;
3a9a941d 97unsigned int do_core_perf_limit_reasons;
ac980e13 98unsigned int has_automatic_cstate_conversion;
3a9a941d
LB
99unsigned int do_gfx_perf_limit_reasons;
100unsigned int do_ring_perf_limit_reasons;
8a5bdf41
LB
101unsigned int crystal_hz;
102unsigned long long tsc_hz;
7ce7d5de 103int base_cpu;
21ed5574 104double discover_bclk(unsigned int family, unsigned int model);
7f5c258e
LB
105unsigned int has_hwp; /* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */
106 /* IA32_HWP_REQUEST, IA32_HWP_STATUS */
107unsigned int has_hwp_notify; /* IA32_HWP_INTERRUPT */
108unsigned int has_hwp_activity_window; /* IA32_HWP_REQUEST[bits 41:32] */
109unsigned int has_hwp_epp; /* IA32_HWP_REQUEST[bits 31:24] */
110unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */
33148d67 111unsigned int has_misc_feature_control;
889facbe 112
e6f9bb3c
LB
113#define RAPL_PKG (1 << 0)
114 /* 0x610 MSR_PKG_POWER_LIMIT */
115 /* 0x611 MSR_PKG_ENERGY_STATUS */
116#define RAPL_PKG_PERF_STATUS (1 << 1)
117 /* 0x613 MSR_PKG_PERF_STATUS */
118#define RAPL_PKG_POWER_INFO (1 << 2)
119 /* 0x614 MSR_PKG_POWER_INFO */
120
121#define RAPL_DRAM (1 << 3)
122 /* 0x618 MSR_DRAM_POWER_LIMIT */
123 /* 0x619 MSR_DRAM_ENERGY_STATUS */
e6f9bb3c
LB
124#define RAPL_DRAM_PERF_STATUS (1 << 4)
125 /* 0x61b MSR_DRAM_PERF_STATUS */
0b2bb692
LB
126#define RAPL_DRAM_POWER_INFO (1 << 5)
127 /* 0x61c MSR_DRAM_POWER_INFO */
e6f9bb3c 128
9148494c 129#define RAPL_CORES_POWER_LIMIT (1 << 6)
e6f9bb3c 130 /* 0x638 MSR_PP0_POWER_LIMIT */
0b2bb692 131#define RAPL_CORE_POLICY (1 << 7)
e6f9bb3c
LB
132 /* 0x63a MSR_PP0_POLICY */
133
0b2bb692 134#define RAPL_GFX (1 << 8)
e6f9bb3c
LB
135 /* 0x640 MSR_PP1_POWER_LIMIT */
136 /* 0x641 MSR_PP1_ENERGY_STATUS */
137 /* 0x642 MSR_PP1_POLICY */
9148494c
JP
138
139#define RAPL_CORES_ENERGY_STATUS (1 << 9)
140 /* 0x639 MSR_PP0_ENERGY_STATUS */
141#define RAPL_CORES (RAPL_CORES_ENERGY_STATUS | RAPL_CORES_POWER_LIMIT)
889facbe
LB
142#define TJMAX_DEFAULT 100
143
144#define MAX(a, b) ((a) > (b) ? (a) : (b))
103a8fea 145
388e9c81
LB
146/*
147 * buffer size used by sscanf() for added column names
148 * Usually truncated to 7 characters, but also handles 18 columns for raw 64-bit counters
149 */
150#define NAME_BYTES 20
495c7654 151#define PATH_BYTES 128
388e9c81 152
103a8fea
LB
153int backwards_count;
154char *progname;
103a8fea 155
1ef7d21a
LB
156#define CPU_SUBSET_MAXCPUS 1024 /* need to use before probe... */
157cpu_set_t *cpu_present_set, *cpu_affinity_set, *cpu_subset;
158size_t cpu_present_setsize, cpu_affinity_setsize, cpu_subset_size;
0748eaf0
LB
159#define MAX_ADDED_COUNTERS 8
160#define MAX_ADDED_THREAD_COUNTERS 24
c98d5d94
LB
161
162struct thread_data {
f4fdf2b4
LB
163 struct timeval tv_begin;
164 struct timeval tv_end;
c98d5d94
LB
165 unsigned long long tsc;
166 unsigned long long aperf;
167 unsigned long long mperf;
144b44b1 168 unsigned long long c1;
0de6c0df 169 unsigned long long irq_count;
1ed51011 170 unsigned int smi_count;
c98d5d94
LB
171 unsigned int cpu_id;
172 unsigned int flags;
173#define CPU_IS_FIRST_THREAD_IN_CORE 0x2
174#define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4
0748eaf0 175 unsigned long long counter[MAX_ADDED_THREAD_COUNTERS];
c98d5d94
LB
176} *thread_even, *thread_odd;
177
178struct core_data {
179 unsigned long long c3;
180 unsigned long long c6;
181 unsigned long long c7;
0539ba11 182 unsigned long long mc6_us; /* duplicate as per-core for now, even though per module */
889facbe 183 unsigned int core_temp_c;
c98d5d94 184 unsigned int core_id;
678a3bd1 185 unsigned long long counter[MAX_ADDED_COUNTERS];
c98d5d94
LB
186} *core_even, *core_odd;
187
188struct pkg_data {
189 unsigned long long pc2;
190 unsigned long long pc3;
191 unsigned long long pc6;
192 unsigned long long pc7;
ca58710f
KCA
193 unsigned long long pc8;
194 unsigned long long pc9;
195 unsigned long long pc10;
be0e54c4
LB
196 unsigned long long cpu_lpi;
197 unsigned long long sys_lpi;
0b2bb692
LB
198 unsigned long long pkg_wtd_core_c0;
199 unsigned long long pkg_any_core_c0;
200 unsigned long long pkg_any_gfxe_c0;
201 unsigned long long pkg_both_core_gfxe_c0;
9185e988 202 long long gfx_rc6_ms;
27d47356 203 unsigned int gfx_mhz;
c98d5d94 204 unsigned int package_id;
889facbe
LB
205 unsigned int energy_pkg; /* MSR_PKG_ENERGY_STATUS */
206 unsigned int energy_dram; /* MSR_DRAM_ENERGY_STATUS */
207 unsigned int energy_cores; /* MSR_PP0_ENERGY_STATUS */
208 unsigned int energy_gfx; /* MSR_PP1_ENERGY_STATUS */
209 unsigned int rapl_pkg_perf_status; /* MSR_PKG_PERF_STATUS */
210 unsigned int rapl_dram_perf_status; /* MSR_DRAM_PERF_STATUS */
211 unsigned int pkg_temp_c;
678a3bd1 212 unsigned long long counter[MAX_ADDED_COUNTERS];
c98d5d94
LB
213} *package_even, *package_odd;
214
215#define ODD_COUNTERS thread_odd, core_odd, package_odd
216#define EVEN_COUNTERS thread_even, core_even, package_even
217
218#define GET_THREAD(thread_base, thread_no, core_no, pkg_no) \
219 (thread_base + (pkg_no) * topo.num_cores_per_pkg * \
220 topo.num_threads_per_core + \
221 (core_no) * topo.num_threads_per_core + (thread_no))
222#define GET_CORE(core_base, core_no, pkg_no) \
223 (core_base + (pkg_no) * topo.num_cores_per_pkg + (core_no))
224#define GET_PKG(pkg_base, pkg_no) (pkg_base + pkg_no)
225
388e9c81 226enum counter_scope {SCOPE_CPU, SCOPE_CORE, SCOPE_PACKAGE};
41618e63 227enum counter_type {COUNTER_ITEMS, COUNTER_CYCLES, COUNTER_SECONDS, COUNTER_USEC};
388e9c81
LB
228enum counter_format {FORMAT_RAW, FORMAT_DELTA, FORMAT_PERCENT};
229
230struct msr_counter {
231 unsigned int msr_num;
232 char name[NAME_BYTES];
495c7654 233 char path[PATH_BYTES];
388e9c81
LB
234 unsigned int width;
235 enum counter_type type;
236 enum counter_format format;
237 struct msr_counter *next;
812db3f7
LB
238 unsigned int flags;
239#define FLAGS_HIDE (1 << 0)
240#define FLAGS_SHOW (1 << 1)
41618e63 241#define SYSFS_PERCPU (1 << 1)
388e9c81
LB
242};
243
244struct sys_counters {
678a3bd1
LB
245 unsigned int added_thread_counters;
246 unsigned int added_core_counters;
247 unsigned int added_package_counters;
388e9c81
LB
248 struct msr_counter *tp;
249 struct msr_counter *cp;
250 struct msr_counter *pp;
251} sys;
252
c98d5d94
LB
253struct system_summary {
254 struct thread_data threads;
255 struct core_data cores;
256 struct pkg_data packages;
388e9c81 257} average;
c98d5d94
LB
258
259
260struct topo_params {
261 int num_packages;
262 int num_cpus;
263 int num_cores;
264 int max_cpu_num;
265 int num_cores_per_pkg;
266 int num_threads_per_core;
267} topo;
268
269struct timeval tv_even, tv_odd, tv_delta;
270
562a2d37
LB
271int *irq_column_2_cpu; /* /proc/interrupts column numbers */
272int *irqs_per_cpu; /* indexed by cpu_num */
273
c98d5d94
LB
274void setup_all_buffers(void);
275
276int cpu_is_not_present(int cpu)
d15cf7c1 277{
c98d5d94 278 return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set);
d15cf7c1 279}
88c3281f 280/*
c98d5d94
LB
281 * run func(thread, core, package) in topology order
282 * skip non-present cpus
88c3281f 283 */
c98d5d94
LB
284
285int for_all_cpus(int (func)(struct thread_data *, struct core_data *, struct pkg_data *),
286 struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base)
88c3281f 287{
c98d5d94 288 int retval, pkg_no, core_no, thread_no;
d15cf7c1 289
c98d5d94
LB
290 for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) {
291 for (core_no = 0; core_no < topo.num_cores_per_pkg; ++core_no) {
292 for (thread_no = 0; thread_no <
293 topo.num_threads_per_core; ++thread_no) {
294 struct thread_data *t;
295 struct core_data *c;
296 struct pkg_data *p;
88c3281f 297
c98d5d94
LB
298 t = GET_THREAD(thread_base, thread_no, core_no, pkg_no);
299
300 if (cpu_is_not_present(t->cpu_id))
301 continue;
302
303 c = GET_CORE(core_base, core_no, pkg_no);
304 p = GET_PKG(pkg_base, pkg_no);
305
306 retval = func(t, c, p);
307 if (retval)
308 return retval;
309 }
310 }
311 }
312 return 0;
88c3281f
LB
313}
314
315int cpu_migrate(int cpu)
316{
c98d5d94
LB
317 CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
318 CPU_SET_S(cpu, cpu_affinity_setsize, cpu_affinity_set);
319 if (sched_setaffinity(0, cpu_affinity_setsize, cpu_affinity_set) == -1)
88c3281f
LB
320 return -1;
321 else
322 return 0;
323}
36229897 324int get_msr_fd(int cpu)
103a8fea 325{
103a8fea
LB
326 char pathname[32];
327 int fd;
328
36229897
LB
329 fd = fd_percpu[cpu];
330
331 if (fd)
332 return fd;
333
103a8fea
LB
334 sprintf(pathname, "/dev/cpu/%d/msr", cpu);
335 fd = open(pathname, O_RDONLY);
15aaa346 336 if (fd < 0)
98481e79 337 err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, or run as root", pathname);
103a8fea 338
36229897
LB
339 fd_percpu[cpu] = fd;
340
341 return fd;
342}
343
344int get_msr(int cpu, off_t offset, unsigned long long *msr)
345{
346 ssize_t retval;
347
348 retval = pread(get_msr_fd(cpu), msr, sizeof(*msr), offset);
15aaa346 349
98481e79 350 if (retval != sizeof *msr)
cf4cbe53 351 err(-1, "cpu%d: msr offset 0x%llx read failed", cpu, (unsigned long long)offset);
15aaa346
LB
352
353 return 0;
103a8fea
LB
354}
355
fc04cc67 356/*
812db3f7
LB
357 * Each string in this array is compared in --show and --hide cmdline.
358 * Thus, strings that are proper sub-sets must follow their more specific peers.
fc04cc67 359 */
812db3f7 360struct msr_counter bic[] = {
3f44a5c6
LB
361 { 0x0, "usec" },
362 { 0x0, "Time_Of_Day_Seconds" },
812db3f7
LB
363 { 0x0, "Package" },
364 { 0x0, "Avg_MHz" },
365 { 0x0, "Bzy_MHz" },
366 { 0x0, "TSC_MHz" },
367 { 0x0, "IRQ" },
495c7654 368 { 0x0, "SMI", "", 32, 0, FORMAT_DELTA, NULL},
812db3f7
LB
369 { 0x0, "Busy%" },
370 { 0x0, "CPU%c1" },
371 { 0x0, "CPU%c3" },
372 { 0x0, "CPU%c6" },
373 { 0x0, "CPU%c7" },
374 { 0x0, "ThreadC" },
375 { 0x0, "CoreTmp" },
376 { 0x0, "CoreCnt" },
377 { 0x0, "PkgTmp" },
378 { 0x0, "GFX%rc6" },
379 { 0x0, "GFXMHz" },
380 { 0x0, "Pkg%pc2" },
381 { 0x0, "Pkg%pc3" },
382 { 0x0, "Pkg%pc6" },
383 { 0x0, "Pkg%pc7" },
0f47c08d
LB
384 { 0x0, "Pkg%pc8" },
385 { 0x0, "Pkg%pc9" },
4bd1f8f2 386 { 0x0, "Pk%pc10" },
be0e54c4
LB
387 { 0x0, "CPU%LPI" },
388 { 0x0, "SYS%LPI" },
812db3f7
LB
389 { 0x0, "PkgWatt" },
390 { 0x0, "CorWatt" },
391 { 0x0, "GFXWatt" },
392 { 0x0, "PkgCnt" },
393 { 0x0, "RAMWatt" },
394 { 0x0, "PKG_%" },
395 { 0x0, "RAM_%" },
396 { 0x0, "Pkg_J" },
397 { 0x0, "Cor_J" },
398 { 0x0, "GFX_J" },
399 { 0x0, "RAM_J" },
400 { 0x0, "Core" },
401 { 0x0, "CPU" },
0539ba11 402 { 0x0, "Mod%c6" },
41618e63 403 { 0x0, "sysfs" },
a99d8730
LB
404 { 0x0, "Totl%C0" },
405 { 0x0, "Any%C0" },
406 { 0x0, "GFX%C0" },
407 { 0x0, "CPUGFX%" },
be0e54c4 408 { 0x0, "Node%" },
812db3f7
LB
409};
410
a99d8730
LB
411
412
812db3f7 413#define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter))
3f44a5c6
LB
414#define BIC_USEC (1ULL << 0)
415#define BIC_TOD (1ULL << 1)
416#define BIC_Package (1ULL << 2)
417#define BIC_Avg_MHz (1ULL << 3)
418#define BIC_Bzy_MHz (1ULL << 4)
419#define BIC_TSC_MHz (1ULL << 5)
420#define BIC_IRQ (1ULL << 6)
421#define BIC_SMI (1ULL << 7)
422#define BIC_Busy (1ULL << 8)
423#define BIC_CPU_c1 (1ULL << 9)
424#define BIC_CPU_c3 (1ULL << 10)
425#define BIC_CPU_c6 (1ULL << 11)
426#define BIC_CPU_c7 (1ULL << 12)
427#define BIC_ThreadC (1ULL << 13)
428#define BIC_CoreTmp (1ULL << 14)
429#define BIC_CoreCnt (1ULL << 15)
430#define BIC_PkgTmp (1ULL << 16)
431#define BIC_GFX_rc6 (1ULL << 17)
432#define BIC_GFXMHz (1ULL << 18)
433#define BIC_Pkgpc2 (1ULL << 19)
434#define BIC_Pkgpc3 (1ULL << 20)
435#define BIC_Pkgpc6 (1ULL << 21)
436#define BIC_Pkgpc7 (1ULL << 22)
437#define BIC_Pkgpc8 (1ULL << 23)
438#define BIC_Pkgpc9 (1ULL << 24)
439#define BIC_Pkgpc10 (1ULL << 25)
be0e54c4
LB
440#define BIC_CPU_LPI (1ULL << 26)
441#define BIC_SYS_LPI (1ULL << 27)
3f44a5c6
LB
442#define BIC_PkgWatt (1ULL << 26)
443#define BIC_CorWatt (1ULL << 27)
444#define BIC_GFXWatt (1ULL << 28)
445#define BIC_PkgCnt (1ULL << 29)
446#define BIC_RAMWatt (1ULL << 30)
447#define BIC_PKG__ (1ULL << 31)
448#define BIC_RAM__ (1ULL << 32)
449#define BIC_Pkg_J (1ULL << 33)
450#define BIC_Cor_J (1ULL << 34)
451#define BIC_GFX_J (1ULL << 35)
452#define BIC_RAM_J (1ULL << 36)
453#define BIC_Core (1ULL << 37)
454#define BIC_CPU (1ULL << 38)
455#define BIC_Mod_c6 (1ULL << 39)
456#define BIC_sysfs (1ULL << 40)
457#define BIC_Totl_c0 (1ULL << 41)
458#define BIC_Any_c0 (1ULL << 42)
459#define BIC_GFX_c0 (1ULL << 43)
460#define BIC_CPUGFX (1ULL << 44)
461
462#define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD)
463
464unsigned long long bic_enabled = (0xFFFFFFFFFFFFFFFFULL & ~BIC_DISABLED_BY_DEFAULT);
465unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs;
812db3f7
LB
466
467#define DO_BIC(COUNTER_NAME) (bic_enabled & bic_present & COUNTER_NAME)
3f44a5c6 468#define ENABLE_BIC(COUNTER_NAME) (bic_enabled |= COUNTER_NAME)
812db3f7 469#define BIC_PRESENT(COUNTER_BIT) (bic_present |= COUNTER_BIT)
0f47c08d 470#define BIC_NOT_PRESENT(COUNTER_BIT) (bic_present &= ~COUNTER_BIT)
812db3f7 471
3f44a5c6 472
dd778a5e
LB
473#define MAX_DEFERRED 16
474char *deferred_skip_names[MAX_DEFERRED];
475int deferred_skip_index;
476
477/*
478 * HIDE_LIST - hide this list of counters, show the rest [default]
479 * SHOW_LIST - show this list of counters, hide the rest
480 */
481enum show_hide_mode { SHOW_LIST, HIDE_LIST } global_show_hide_mode = HIDE_LIST;
482
483void help(void)
484{
485 fprintf(outf,
486 "Usage: turbostat [OPTIONS][(--interval seconds) | COMMAND ...]\n"
487 "\n"
488 "Turbostat forks the specified COMMAND and prints statistics\n"
489 "when COMMAND completes.\n"
490 "If no COMMAND is specified, turbostat wakes every 5-seconds\n"
491 "to print statistics, until interrupted.\n"
492 "--add add a counter\n"
493 " eg. --add msr0x10,u64,cpu,delta,MY_TSC\n"
494 "--cpu cpu-set limit output to summary plus cpu-set:\n"
495 " {core | package | j,k,l..m,n-p }\n"
496 "--quiet skip decoding system configuration header\n"
b9ad8ee0 497 "--interval sec.subsec Override default 5-second measurement interval\n"
dd778a5e
LB
498 "--help print this help message\n"
499 "--list list column headers only\n"
023fe0ac 500 "--num_iterations num number of the measurement iterations\n"
dd778a5e
LB
501 "--out file create or truncate \"file\" for all output\n"
502 "--version print version information\n"
503 "\n"
504 "For more help, run \"man turbostat\"\n");
505}
506
812db3f7
LB
507/*
508 * bic_lookup
509 * for all the strings in comma separate name_list,
510 * set the approprate bit in return value.
511 */
dd778a5e 512unsigned long long bic_lookup(char *name_list, enum show_hide_mode mode)
812db3f7
LB
513{
514 int i;
515 unsigned long long retval = 0;
516
517 while (name_list) {
518 char *comma;
519
520 comma = strchr(name_list, ',');
521
522 if (comma)
523 *comma = '\0';
524
3f44a5c6
LB
525 if (!strcmp(name_list, "all"))
526 return ~0;
527
812db3f7
LB
528 for (i = 0; i < MAX_BIC; ++i) {
529 if (!strcmp(name_list, bic[i].name)) {
530 retval |= (1ULL << i);
531 break;
532 }
533 }
534 if (i == MAX_BIC) {
dd778a5e
LB
535 if (mode == SHOW_LIST) {
536 fprintf(stderr, "Invalid counter name: %s\n", name_list);
537 exit(-1);
538 }
539 deferred_skip_names[deferred_skip_index++] = name_list;
540 if (debug)
541 fprintf(stderr, "deferred \"%s\"\n", name_list);
542 if (deferred_skip_index >= MAX_DEFERRED) {
543 fprintf(stderr, "More than max %d un-recognized --skip options '%s'\n",
544 MAX_DEFERRED, name_list);
545 help();
546 exit(1);
547 }
812db3f7
LB
548 }
549
550 name_list = comma;
551 if (name_list)
552 name_list++;
553
554 }
555 return retval;
556}
fc04cc67 557
dd778a5e 558
c8ade361 559void print_header(char *delim)
103a8fea 560{
388e9c81 561 struct msr_counter *mp;
6168c2e0 562 int printed = 0;
388e9c81 563
3f44a5c6
LB
564 if (DO_BIC(BIC_USEC))
565 outp += sprintf(outp, "%susec", (printed++ ? delim : ""));
566 if (DO_BIC(BIC_TOD))
567 outp += sprintf(outp, "%sTime_Of_Day_Seconds", (printed++ ? delim : ""));
812db3f7 568 if (DO_BIC(BIC_Package))
6168c2e0 569 outp += sprintf(outp, "%sPackage", (printed++ ? delim : ""));
812db3f7 570 if (DO_BIC(BIC_Core))
6168c2e0 571 outp += sprintf(outp, "%sCore", (printed++ ? delim : ""));
812db3f7 572 if (DO_BIC(BIC_CPU))
6168c2e0 573 outp += sprintf(outp, "%sCPU", (printed++ ? delim : ""));
812db3f7 574 if (DO_BIC(BIC_Avg_MHz))
6168c2e0 575 outp += sprintf(outp, "%sAvg_MHz", (printed++ ? delim : ""));
812db3f7 576 if (DO_BIC(BIC_Busy))
6168c2e0 577 outp += sprintf(outp, "%sBusy%%", (printed++ ? delim : ""));
812db3f7 578 if (DO_BIC(BIC_Bzy_MHz))
6168c2e0 579 outp += sprintf(outp, "%sBzy_MHz", (printed++ ? delim : ""));
812db3f7 580 if (DO_BIC(BIC_TSC_MHz))
6168c2e0 581 outp += sprintf(outp, "%sTSC_MHz", (printed++ ? delim : ""));
1cc21f7b 582
0de6c0df
LB
583 if (DO_BIC(BIC_IRQ)) {
584 if (sums_need_wide_columns)
6168c2e0 585 outp += sprintf(outp, "%s IRQ", (printed++ ? delim : ""));
0de6c0df 586 else
6168c2e0 587 outp += sprintf(outp, "%sIRQ", (printed++ ? delim : ""));
0de6c0df
LB
588 }
589
812db3f7 590 if (DO_BIC(BIC_SMI))
6168c2e0 591 outp += sprintf(outp, "%sSMI", (printed++ ? delim : ""));
1cc21f7b 592
388e9c81 593 for (mp = sys.tp; mp; mp = mp->next) {
dd778a5e 594
388e9c81
LB
595 if (mp->format == FORMAT_RAW) {
596 if (mp->width == 64)
dd778a5e 597 outp += sprintf(outp, "%s%18.18s", (printed++ ? delim : ""), mp->name);
388e9c81 598 else
dd778a5e 599 outp += sprintf(outp, "%s%10.10s", (printed++ ? delim : ""), mp->name);
388e9c81 600 } else {
0de6c0df 601 if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
dd778a5e 602 outp += sprintf(outp, "%s%8s", (printed++ ? delim : ""), mp->name);
0de6c0df 603 else
dd778a5e 604 outp += sprintf(outp, "%s%s", (printed++ ? delim : ""), mp->name);
388e9c81
LB
605 }
606 }
607
41618e63 608 if (DO_BIC(BIC_CPU_c1))
6168c2e0 609 outp += sprintf(outp, "%sCPU%%c1", (printed++ ? delim : ""));
997e5395 610 if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates && !do_cnl_cstates)
6168c2e0 611 outp += sprintf(outp, "%sCPU%%c3", (printed++ ? delim : ""));
812db3f7 612 if (DO_BIC(BIC_CPU_c6))
6168c2e0 613 outp += sprintf(outp, "%sCPU%%c6", (printed++ ? delim : ""));
812db3f7 614 if (DO_BIC(BIC_CPU_c7))
6168c2e0 615 outp += sprintf(outp, "%sCPU%%c7", (printed++ ? delim : ""));
678a3bd1 616
0539ba11 617 if (DO_BIC(BIC_Mod_c6))
6168c2e0 618 outp += sprintf(outp, "%sMod%%c6", (printed++ ? delim : ""));
678a3bd1 619
812db3f7 620 if (DO_BIC(BIC_CoreTmp))
6168c2e0 621 outp += sprintf(outp, "%sCoreTmp", (printed++ ? delim : ""));
388e9c81
LB
622
623 for (mp = sys.cp; mp; mp = mp->next) {
624 if (mp->format == FORMAT_RAW) {
625 if (mp->width == 64)
c8ade361 626 outp += sprintf(outp, "%s%18.18s", delim, mp->name);
388e9c81 627 else
c8ade361 628 outp += sprintf(outp, "%s%10.10s", delim, mp->name);
388e9c81 629 } else {
0de6c0df
LB
630 if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
631 outp += sprintf(outp, "%s%8s", delim, mp->name);
632 else
633 outp += sprintf(outp, "%s%s", delim, mp->name);
388e9c81
LB
634 }
635 }
636
812db3f7 637 if (DO_BIC(BIC_PkgTmp))
6168c2e0 638 outp += sprintf(outp, "%sPkgTmp", (printed++ ? delim : ""));
889facbe 639
812db3f7 640 if (DO_BIC(BIC_GFX_rc6))
6168c2e0 641 outp += sprintf(outp, "%sGFX%%rc6", (printed++ ? delim : ""));
fdf676e5 642
812db3f7 643 if (DO_BIC(BIC_GFXMHz))
6168c2e0 644 outp += sprintf(outp, "%sGFXMHz", (printed++ ? delim : ""));
27d47356 645
a99d8730 646 if (DO_BIC(BIC_Totl_c0))
6168c2e0 647 outp += sprintf(outp, "%sTotl%%C0", (printed++ ? delim : ""));
a99d8730 648 if (DO_BIC(BIC_Any_c0))
6168c2e0 649 outp += sprintf(outp, "%sAny%%C0", (printed++ ? delim : ""));
a99d8730 650 if (DO_BIC(BIC_GFX_c0))
6168c2e0 651 outp += sprintf(outp, "%sGFX%%C0", (printed++ ? delim : ""));
a99d8730 652 if (DO_BIC(BIC_CPUGFX))
6168c2e0 653 outp += sprintf(outp, "%sCPUGFX%%", (printed++ ? delim : ""));
0b2bb692 654
0f47c08d 655 if (DO_BIC(BIC_Pkgpc2))
6168c2e0 656 outp += sprintf(outp, "%sPkg%%pc2", (printed++ ? delim : ""));
0f47c08d 657 if (DO_BIC(BIC_Pkgpc3))
6168c2e0 658 outp += sprintf(outp, "%sPkg%%pc3", (printed++ ? delim : ""));
0f47c08d 659 if (DO_BIC(BIC_Pkgpc6))
6168c2e0 660 outp += sprintf(outp, "%sPkg%%pc6", (printed++ ? delim : ""));
0f47c08d 661 if (DO_BIC(BIC_Pkgpc7))
6168c2e0 662 outp += sprintf(outp, "%sPkg%%pc7", (printed++ ? delim : ""));
0f47c08d 663 if (DO_BIC(BIC_Pkgpc8))
6168c2e0 664 outp += sprintf(outp, "%sPkg%%pc8", (printed++ ? delim : ""));
0f47c08d 665 if (DO_BIC(BIC_Pkgpc9))
6168c2e0 666 outp += sprintf(outp, "%sPkg%%pc9", (printed++ ? delim : ""));
0f47c08d 667 if (DO_BIC(BIC_Pkgpc10))
6168c2e0 668 outp += sprintf(outp, "%sPk%%pc10", (printed++ ? delim : ""));
be0e54c4
LB
669 if (DO_BIC(BIC_CPU_LPI))
670 outp += sprintf(outp, "%sCPU%%LPI", (printed++ ? delim : ""));
671 if (DO_BIC(BIC_SYS_LPI))
672 outp += sprintf(outp, "%sSYS%%LPI", (printed++ ? delim : ""));
103a8fea 673
5c56be9a 674 if (do_rapl && !rapl_joules) {
812db3f7 675 if (DO_BIC(BIC_PkgWatt))
6168c2e0 676 outp += sprintf(outp, "%sPkgWatt", (printed++ ? delim : ""));
812db3f7 677 if (DO_BIC(BIC_CorWatt))
6168c2e0 678 outp += sprintf(outp, "%sCorWatt", (printed++ ? delim : ""));
812db3f7 679 if (DO_BIC(BIC_GFXWatt))
6168c2e0 680 outp += sprintf(outp, "%sGFXWatt", (printed++ ? delim : ""));
812db3f7 681 if (DO_BIC(BIC_RAMWatt))
6168c2e0 682 outp += sprintf(outp, "%sRAMWatt", (printed++ ? delim : ""));
812db3f7 683 if (DO_BIC(BIC_PKG__))
6168c2e0 684 outp += sprintf(outp, "%sPKG_%%", (printed++ ? delim : ""));
812db3f7 685 if (DO_BIC(BIC_RAM__))
6168c2e0 686 outp += sprintf(outp, "%sRAM_%%", (printed++ ? delim : ""));
d7899447 687 } else if (do_rapl && rapl_joules) {
812db3f7 688 if (DO_BIC(BIC_Pkg_J))
6168c2e0 689 outp += sprintf(outp, "%sPkg_J", (printed++ ? delim : ""));
812db3f7 690 if (DO_BIC(BIC_Cor_J))
6168c2e0 691 outp += sprintf(outp, "%sCor_J", (printed++ ? delim : ""));
812db3f7 692 if (DO_BIC(BIC_GFX_J))
6168c2e0 693 outp += sprintf(outp, "%sGFX_J", (printed++ ? delim : ""));
812db3f7 694 if (DO_BIC(BIC_RAM_J))
6168c2e0 695 outp += sprintf(outp, "%sRAM_J", (printed++ ? delim : ""));
812db3f7 696 if (DO_BIC(BIC_PKG__))
6168c2e0 697 outp += sprintf(outp, "%sPKG_%%", (printed++ ? delim : ""));
812db3f7 698 if (DO_BIC(BIC_RAM__))
6168c2e0 699 outp += sprintf(outp, "%sRAM_%%", (printed++ ? delim : ""));
5c56be9a 700 }
388e9c81
LB
701 for (mp = sys.pp; mp; mp = mp->next) {
702 if (mp->format == FORMAT_RAW) {
703 if (mp->width == 64)
c8ade361 704 outp += sprintf(outp, "%s%18.18s", delim, mp->name);
388e9c81 705 else
c8ade361 706 outp += sprintf(outp, "%s%10.10s", delim, mp->name);
388e9c81 707 } else {
0de6c0df
LB
708 if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
709 outp += sprintf(outp, "%s%8s", delim, mp->name);
710 else
711 outp += sprintf(outp, "%s%s", delim, mp->name);
388e9c81
LB
712 }
713 }
714
c98d5d94 715 outp += sprintf(outp, "\n");
103a8fea
LB
716}
717
c98d5d94
LB
718int dump_counters(struct thread_data *t, struct core_data *c,
719 struct pkg_data *p)
103a8fea 720{
388e9c81
LB
721 int i;
722 struct msr_counter *mp;
723
3b4d5c7f 724 outp += sprintf(outp, "t %p, c %p, p %p\n", t, c, p);
c98d5d94
LB
725
726 if (t) {
3b4d5c7f
AS
727 outp += sprintf(outp, "CPU: %d flags 0x%x\n",
728 t->cpu_id, t->flags);
729 outp += sprintf(outp, "TSC: %016llX\n", t->tsc);
730 outp += sprintf(outp, "aperf: %016llX\n", t->aperf);
731 outp += sprintf(outp, "mperf: %016llX\n", t->mperf);
732 outp += sprintf(outp, "c1: %016llX\n", t->c1);
6886fee4 733
812db3f7 734 if (DO_BIC(BIC_IRQ))
0de6c0df 735 outp += sprintf(outp, "IRQ: %lld\n", t->irq_count);
812db3f7 736 if (DO_BIC(BIC_SMI))
218f0e8d 737 outp += sprintf(outp, "SMI: %d\n", t->smi_count);
388e9c81
LB
738
739 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
740 outp += sprintf(outp, "tADDED [%d] msr0x%x: %08llX\n",
741 i, mp->msr_num, t->counter[i]);
742 }
c98d5d94 743 }
103a8fea 744
c98d5d94 745 if (c) {
3b4d5c7f
AS
746 outp += sprintf(outp, "core: %d\n", c->core_id);
747 outp += sprintf(outp, "c3: %016llX\n", c->c3);
748 outp += sprintf(outp, "c6: %016llX\n", c->c6);
749 outp += sprintf(outp, "c7: %016llX\n", c->c7);
750 outp += sprintf(outp, "DTS: %dC\n", c->core_temp_c);
388e9c81
LB
751
752 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
753 outp += sprintf(outp, "cADDED [%d] msr0x%x: %08llX\n",
754 i, mp->msr_num, c->counter[i]);
755 }
0539ba11 756 outp += sprintf(outp, "mc6_us: %016llX\n", c->mc6_us);
c98d5d94 757 }
103a8fea 758
c98d5d94 759 if (p) {
3b4d5c7f 760 outp += sprintf(outp, "package: %d\n", p->package_id);
0b2bb692
LB
761
762 outp += sprintf(outp, "Weighted cores: %016llX\n", p->pkg_wtd_core_c0);
763 outp += sprintf(outp, "Any cores: %016llX\n", p->pkg_any_core_c0);
764 outp += sprintf(outp, "Any GFX: %016llX\n", p->pkg_any_gfxe_c0);
765 outp += sprintf(outp, "CPU + GFX: %016llX\n", p->pkg_both_core_gfxe_c0);
766
3b4d5c7f 767 outp += sprintf(outp, "pc2: %016llX\n", p->pc2);
0f47c08d 768 if (DO_BIC(BIC_Pkgpc3))
ee7e38e3 769 outp += sprintf(outp, "pc3: %016llX\n", p->pc3);
0f47c08d 770 if (DO_BIC(BIC_Pkgpc6))
ee7e38e3 771 outp += sprintf(outp, "pc6: %016llX\n", p->pc6);
0f47c08d 772 if (DO_BIC(BIC_Pkgpc7))
ee7e38e3 773 outp += sprintf(outp, "pc7: %016llX\n", p->pc7);
3b4d5c7f
AS
774 outp += sprintf(outp, "pc8: %016llX\n", p->pc8);
775 outp += sprintf(outp, "pc9: %016llX\n", p->pc9);
776 outp += sprintf(outp, "pc10: %016llX\n", p->pc10);
be0e54c4
LB
777 outp += sprintf(outp, "pc10: %016llX\n", p->pc10);
778 outp += sprintf(outp, "cpu_lpi: %016llX\n", p->cpu_lpi);
779 outp += sprintf(outp, "sys_lpi: %016llX\n", p->sys_lpi);
3b4d5c7f
AS
780 outp += sprintf(outp, "Joules PKG: %0X\n", p->energy_pkg);
781 outp += sprintf(outp, "Joules COR: %0X\n", p->energy_cores);
782 outp += sprintf(outp, "Joules GFX: %0X\n", p->energy_gfx);
783 outp += sprintf(outp, "Joules RAM: %0X\n", p->energy_dram);
784 outp += sprintf(outp, "Throttle PKG: %0X\n",
785 p->rapl_pkg_perf_status);
786 outp += sprintf(outp, "Throttle RAM: %0X\n",
787 p->rapl_dram_perf_status);
788 outp += sprintf(outp, "PTM: %dC\n", p->pkg_temp_c);
388e9c81
LB
789
790 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
791 outp += sprintf(outp, "pADDED [%d] msr0x%x: %08llX\n",
792 i, mp->msr_num, p->counter[i]);
793 }
c98d5d94 794 }
3b4d5c7f
AS
795
796 outp += sprintf(outp, "\n");
797
c98d5d94 798 return 0;
103a8fea
LB
799}
800
e23da037
LB
801/*
802 * column formatting convention & formats
e23da037 803 */
c98d5d94
LB
804int format_counters(struct thread_data *t, struct core_data *c,
805 struct pkg_data *p)
103a8fea 806{
008d396e 807 double interval_float, tsc;
fc04cc67 808 char *fmt8;
388e9c81
LB
809 int i;
810 struct msr_counter *mp;
6168c2e0
LB
811 char *delim = "\t";
812 int printed = 0;
103a8fea 813
c98d5d94
LB
814 /* if showing only 1st thread in core and this isn't one, bail out */
815 if (show_core_only && !(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
816 return 0;
817
818 /* if showing only 1st thread in pkg and this isn't one, bail out */
819 if (show_pkg_only && !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
820 return 0;
821
1ef7d21a
LB
822 /*if not summary line and --cpu is used */
823 if ((t != &average.threads) &&
824 (cpu_subset && !CPU_ISSET_S(t->cpu_id, cpu_subset_size, cpu_subset)))
825 return 0;
826
3f44a5c6 827 if (DO_BIC(BIC_USEC)) {
f4fdf2b4
LB
828 /* on each row, print how many usec each timestamp took to gather */
829 struct timeval tv;
830
831 timersub(&t->tv_end, &t->tv_begin, &tv);
832 outp += sprintf(outp, "%5ld\t", tv.tv_sec * 1000000 + tv.tv_usec);
833 }
834
3f44a5c6
LB
835 /* Time_Of_Day_Seconds: on each row, print sec.usec last timestamp taken */
836 if (DO_BIC(BIC_TOD))
837 outp += sprintf(outp, "%10ld.%06ld\t", t->tv_end.tv_sec, t->tv_end.tv_usec);
838
103a8fea
LB
839 interval_float = tv_delta.tv_sec + tv_delta.tv_usec/1000000.0;
840
008d396e
LB
841 tsc = t->tsc * tsc_tweak;
842
c98d5d94
LB
843 /* topo columns, print blanks on 1st (average) line */
844 if (t == &average.threads) {
812db3f7 845 if (DO_BIC(BIC_Package))
6168c2e0 846 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
812db3f7 847 if (DO_BIC(BIC_Core))
6168c2e0 848 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
812db3f7 849 if (DO_BIC(BIC_CPU))
6168c2e0 850 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
103a8fea 851 } else {
812db3f7 852 if (DO_BIC(BIC_Package)) {
c98d5d94 853 if (p)
6168c2e0 854 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->package_id);
c98d5d94 855 else
6168c2e0 856 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
c98d5d94 857 }
812db3f7 858 if (DO_BIC(BIC_Core)) {
c98d5d94 859 if (c)
6168c2e0 860 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), c->core_id);
c98d5d94 861 else
6168c2e0 862 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
c98d5d94 863 }
812db3f7 864 if (DO_BIC(BIC_CPU))
6168c2e0 865 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->cpu_id);
103a8fea 866 }
fc04cc67 867
812db3f7 868 if (DO_BIC(BIC_Avg_MHz))
6168c2e0 869 outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""),
fc04cc67
LB
870 1.0 / units * t->aperf / interval_float);
871
812db3f7 872 if (DO_BIC(BIC_Busy))
6168c2e0 873 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * t->mperf/tsc);
103a8fea 874
812db3f7 875 if (DO_BIC(BIC_Bzy_MHz)) {
21ed5574 876 if (has_base_hz)
6168c2e0 877 outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), base_hz / units * t->aperf / t->mperf);
21ed5574 878 else
6168c2e0 879 outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""),
008d396e 880 tsc / units * t->aperf / t->mperf / interval_float);
21ed5574 881 }
103a8fea 882
812db3f7 883 if (DO_BIC(BIC_TSC_MHz))
6168c2e0 884 outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), 1.0 * t->tsc/units/interval_float);
103a8fea 885
562a2d37 886 /* IRQ */
0de6c0df
LB
887 if (DO_BIC(BIC_IRQ)) {
888 if (sums_need_wide_columns)
6168c2e0 889 outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), t->irq_count);
0de6c0df 890 else
6168c2e0 891 outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), t->irq_count);
0de6c0df 892 }
562a2d37 893
1cc21f7b 894 /* SMI */
812db3f7 895 if (DO_BIC(BIC_SMI))
6168c2e0 896 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->smi_count);
1cc21f7b 897
678a3bd1 898 /* Added counters */
388e9c81
LB
899 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
900 if (mp->format == FORMAT_RAW) {
901 if (mp->width == 32)
5f3aea57 902 outp += sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int) t->counter[i]);
388e9c81 903 else
6168c2e0 904 outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), t->counter[i]);
388e9c81 905 } else if (mp->format == FORMAT_DELTA) {
0de6c0df 906 if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
6168c2e0 907 outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), t->counter[i]);
0de6c0df 908 else
6168c2e0 909 outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), t->counter[i]);
388e9c81 910 } else if (mp->format == FORMAT_PERCENT) {
41618e63 911 if (mp->type == COUNTER_USEC)
6168c2e0 912 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), t->counter[i]/interval_float/10000);
41618e63 913 else
6168c2e0 914 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * t->counter[i]/tsc);
388e9c81
LB
915 }
916 }
917
41618e63
LB
918 /* C1 */
919 if (DO_BIC(BIC_CPU_c1))
6168c2e0 920 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * t->c1/tsc);
41618e63
LB
921
922
678a3bd1
LB
923 /* print per-core data only for 1st thread in core */
924 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
925 goto done;
926
997e5395 927 if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates && !do_cnl_cstates)
6168c2e0 928 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c3/tsc);
812db3f7 929 if (DO_BIC(BIC_CPU_c6))
6168c2e0 930 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c6/tsc);
812db3f7 931 if (DO_BIC(BIC_CPU_c7))
6168c2e0 932 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c7/tsc);
678a3bd1 933
0539ba11
LB
934 /* Mod%c6 */
935 if (DO_BIC(BIC_Mod_c6))
6168c2e0 936 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->mc6_us / tsc);
0539ba11 937
812db3f7 938 if (DO_BIC(BIC_CoreTmp))
6168c2e0 939 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), c->core_temp_c);
889facbe 940
388e9c81
LB
941 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
942 if (mp->format == FORMAT_RAW) {
943 if (mp->width == 32)
5f3aea57 944 outp += sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int) c->counter[i]);
388e9c81 945 else
6168c2e0 946 outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), c->counter[i]);
388e9c81 947 } else if (mp->format == FORMAT_DELTA) {
0de6c0df 948 if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
6168c2e0 949 outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), c->counter[i]);
0de6c0df 950 else
6168c2e0 951 outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), c->counter[i]);
388e9c81 952 } else if (mp->format == FORMAT_PERCENT) {
6168c2e0 953 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->counter[i]/tsc);
388e9c81
LB
954 }
955 }
956
c98d5d94
LB
957 /* print per-package data only for 1st core in package */
958 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
959 goto done;
960
0b2bb692 961 /* PkgTmp */
812db3f7 962 if (DO_BIC(BIC_PkgTmp))
6168c2e0 963 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->pkg_temp_c);
889facbe 964
fdf676e5 965 /* GFXrc6 */
812db3f7 966 if (DO_BIC(BIC_GFX_rc6)) {
ba3dec99 967 if (p->gfx_rc6_ms == -1) { /* detect GFX counter reset */
6168c2e0 968 outp += sprintf(outp, "%s**.**", (printed++ ? delim : ""));
9185e988 969 } else {
6168c2e0 970 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""),
9185e988
LB
971 p->gfx_rc6_ms / 10.0 / interval_float);
972 }
973 }
fdf676e5 974
27d47356 975 /* GFXMHz */
812db3f7 976 if (DO_BIC(BIC_GFXMHz))
6168c2e0 977 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->gfx_mhz);
27d47356 978
0b2bb692 979 /* Totl%C0, Any%C0 GFX%C0 CPUGFX% */
a99d8730 980 if (DO_BIC(BIC_Totl_c0))
6168c2e0 981 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_wtd_core_c0/tsc);
a99d8730 982 if (DO_BIC(BIC_Any_c0))
6168c2e0 983 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_any_core_c0/tsc);
a99d8730 984 if (DO_BIC(BIC_GFX_c0))
6168c2e0 985 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_any_gfxe_c0/tsc);
a99d8730 986 if (DO_BIC(BIC_CPUGFX))
6168c2e0 987 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_both_core_gfxe_c0/tsc);
0b2bb692 988
0f47c08d 989 if (DO_BIC(BIC_Pkgpc2))
6168c2e0 990 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc2/tsc);
0f47c08d 991 if (DO_BIC(BIC_Pkgpc3))
6168c2e0 992 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc3/tsc);
0f47c08d 993 if (DO_BIC(BIC_Pkgpc6))
6168c2e0 994 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc6/tsc);
0f47c08d 995 if (DO_BIC(BIC_Pkgpc7))
6168c2e0 996 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc7/tsc);
0f47c08d 997 if (DO_BIC(BIC_Pkgpc8))
6168c2e0 998 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc8/tsc);
0f47c08d 999 if (DO_BIC(BIC_Pkgpc9))
6168c2e0 1000 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc9/tsc);
0f47c08d 1001 if (DO_BIC(BIC_Pkgpc10))
6168c2e0 1002 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc10/tsc);
889facbe 1003
be0e54c4
LB
1004 if (DO_BIC(BIC_CPU_LPI))
1005 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->cpu_lpi / 1000000.0 / interval_float);
1006 if (DO_BIC(BIC_SYS_LPI))
1007 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->sys_lpi / 1000000.0 / interval_float);
1008
889facbe
LB
1009 /*
1010 * If measurement interval exceeds minimum RAPL Joule Counter range,
1011 * indicate that results are suspect by printing "**" in fraction place.
1012 */
fc04cc67 1013 if (interval_float < rapl_joule_counter_range)
6168c2e0 1014 fmt8 = "%s%.2f";
fc04cc67 1015 else
e975db5d 1016 fmt8 = "%6.0f**";
889facbe 1017
812db3f7 1018 if (DO_BIC(BIC_PkgWatt))
6168c2e0 1019 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units / interval_float);
812db3f7 1020 if (DO_BIC(BIC_CorWatt))
6168c2e0 1021 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units / interval_float);
812db3f7 1022 if (DO_BIC(BIC_GFXWatt))
6168c2e0 1023 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units / interval_float);
812db3f7 1024 if (DO_BIC(BIC_RAMWatt))
6168c2e0 1025 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_dram * rapl_dram_energy_units / interval_float);
812db3f7 1026 if (DO_BIC(BIC_Pkg_J))
6168c2e0 1027 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units);
812db3f7 1028 if (DO_BIC(BIC_Cor_J))
6168c2e0 1029 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units);
812db3f7 1030 if (DO_BIC(BIC_GFX_J))
6168c2e0 1031 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units);
812db3f7 1032 if (DO_BIC(BIC_RAM_J))
6168c2e0 1033 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_dram * rapl_dram_energy_units);
812db3f7 1034 if (DO_BIC(BIC_PKG__))
6168c2e0 1035 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
812db3f7 1036 if (DO_BIC(BIC_RAM__))
6168c2e0 1037 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
812db3f7 1038
388e9c81
LB
1039 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
1040 if (mp->format == FORMAT_RAW) {
1041 if (mp->width == 32)
5f3aea57 1042 outp += sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int) p->counter[i]);
388e9c81 1043 else
6168c2e0 1044 outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), p->counter[i]);
388e9c81 1045 } else if (mp->format == FORMAT_DELTA) {
0de6c0df 1046 if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
6168c2e0 1047 outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), p->counter[i]);
0de6c0df 1048 else
6168c2e0 1049 outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), p->counter[i]);
388e9c81 1050 } else if (mp->format == FORMAT_PERCENT) {
6168c2e0 1051 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->counter[i]/tsc);
388e9c81
LB
1052 }
1053 }
1054
c98d5d94 1055done:
94d6ab4b
LB
1056 if (*(outp - 1) != '\n')
1057 outp += sprintf(outp, "\n");
c98d5d94
LB
1058
1059 return 0;
103a8fea
LB
1060}
1061
b7d8c148 1062void flush_output_stdout(void)
c98d5d94 1063{
b7d8c148
LB
1064 FILE *filep;
1065
1066 if (outf == stderr)
1067 filep = stdout;
1068 else
1069 filep = outf;
1070
1071 fputs(output_buffer, filep);
1072 fflush(filep);
1073
c98d5d94
LB
1074 outp = output_buffer;
1075}
b7d8c148 1076void flush_output_stderr(void)
c98d5d94 1077{
b7d8c148
LB
1078 fputs(output_buffer, outf);
1079 fflush(outf);
c98d5d94
LB
1080 outp = output_buffer;
1081}
1082void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
103a8fea 1083{
e23da037 1084 static int printed;
103a8fea 1085
e23da037 1086 if (!printed || !summary_only)
c8ade361 1087 print_header("\t");
103a8fea 1088
c98d5d94
LB
1089 if (topo.num_cpus > 1)
1090 format_counters(&average.threads, &average.cores,
1091 &average.packages);
103a8fea 1092
e23da037
LB
1093 printed = 1;
1094
1095 if (summary_only)
1096 return;
1097
c98d5d94 1098 for_all_cpus(format_counters, t, c, p);
103a8fea
LB
1099}
1100
889facbe
LB
1101#define DELTA_WRAP32(new, old) \
1102 if (new > old) { \
1103 old = new - old; \
1104 } else { \
1105 old = 0x100000000 + new - old; \
1106 }
1107
ba3dec99 1108int
c98d5d94
LB
1109delta_package(struct pkg_data *new, struct pkg_data *old)
1110{
388e9c81
LB
1111 int i;
1112 struct msr_counter *mp;
0b2bb692 1113
a99d8730
LB
1114
1115 if (DO_BIC(BIC_Totl_c0))
0b2bb692 1116 old->pkg_wtd_core_c0 = new->pkg_wtd_core_c0 - old->pkg_wtd_core_c0;
a99d8730 1117 if (DO_BIC(BIC_Any_c0))
0b2bb692 1118 old->pkg_any_core_c0 = new->pkg_any_core_c0 - old->pkg_any_core_c0;
a99d8730 1119 if (DO_BIC(BIC_GFX_c0))
0b2bb692 1120 old->pkg_any_gfxe_c0 = new->pkg_any_gfxe_c0 - old->pkg_any_gfxe_c0;
a99d8730 1121 if (DO_BIC(BIC_CPUGFX))
0b2bb692 1122 old->pkg_both_core_gfxe_c0 = new->pkg_both_core_gfxe_c0 - old->pkg_both_core_gfxe_c0;
a99d8730 1123
c98d5d94 1124 old->pc2 = new->pc2 - old->pc2;
0f47c08d 1125 if (DO_BIC(BIC_Pkgpc3))
ee7e38e3 1126 old->pc3 = new->pc3 - old->pc3;
0f47c08d 1127 if (DO_BIC(BIC_Pkgpc6))
ee7e38e3 1128 old->pc6 = new->pc6 - old->pc6;
0f47c08d 1129 if (DO_BIC(BIC_Pkgpc7))
ee7e38e3 1130 old->pc7 = new->pc7 - old->pc7;
ca58710f
KCA
1131 old->pc8 = new->pc8 - old->pc8;
1132 old->pc9 = new->pc9 - old->pc9;
1133 old->pc10 = new->pc10 - old->pc10;
be0e54c4
LB
1134 old->cpu_lpi = new->cpu_lpi - old->cpu_lpi;
1135 old->sys_lpi = new->sys_lpi - old->sys_lpi;
889facbe
LB
1136 old->pkg_temp_c = new->pkg_temp_c;
1137
9185e988
LB
1138 /* flag an error when rc6 counter resets/wraps */
1139 if (old->gfx_rc6_ms > new->gfx_rc6_ms)
1140 old->gfx_rc6_ms = -1;
1141 else
1142 old->gfx_rc6_ms = new->gfx_rc6_ms - old->gfx_rc6_ms;
1143
27d47356
LB
1144 old->gfx_mhz = new->gfx_mhz;
1145
889facbe
LB
1146 DELTA_WRAP32(new->energy_pkg, old->energy_pkg);
1147 DELTA_WRAP32(new->energy_cores, old->energy_cores);
1148 DELTA_WRAP32(new->energy_gfx, old->energy_gfx);
1149 DELTA_WRAP32(new->energy_dram, old->energy_dram);
1150 DELTA_WRAP32(new->rapl_pkg_perf_status, old->rapl_pkg_perf_status);
1151 DELTA_WRAP32(new->rapl_dram_perf_status, old->rapl_dram_perf_status);
ba3dec99 1152
388e9c81
LB
1153 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
1154 if (mp->format == FORMAT_RAW)
1155 old->counter[i] = new->counter[i];
1156 else
1157 old->counter[i] = new->counter[i] - old->counter[i];
1158 }
1159
ba3dec99 1160 return 0;
c98d5d94 1161}
103a8fea 1162
c98d5d94
LB
1163void
1164delta_core(struct core_data *new, struct core_data *old)
103a8fea 1165{
388e9c81
LB
1166 int i;
1167 struct msr_counter *mp;
1168
c98d5d94
LB
1169 old->c3 = new->c3 - old->c3;
1170 old->c6 = new->c6 - old->c6;
1171 old->c7 = new->c7 - old->c7;
889facbe 1172 old->core_temp_c = new->core_temp_c;
0539ba11 1173 old->mc6_us = new->mc6_us - old->mc6_us;
388e9c81
LB
1174
1175 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
1176 if (mp->format == FORMAT_RAW)
1177 old->counter[i] = new->counter[i];
1178 else
1179 old->counter[i] = new->counter[i] - old->counter[i];
1180 }
c98d5d94 1181}
103a8fea 1182
c3ae331d
LB
1183/*
1184 * old = new - old
1185 */
ba3dec99 1186int
c98d5d94
LB
1187delta_thread(struct thread_data *new, struct thread_data *old,
1188 struct core_data *core_delta)
1189{
388e9c81
LB
1190 int i;
1191 struct msr_counter *mp;
1192
3f44a5c6
LB
1193 /*
1194 * the timestamps from start of measurement interval are in "old"
1195 * the timestamp from end of measurement interval are in "new"
1196 * over-write old w/ new so we can print end of interval values
1197 */
1198
1199 old->tv_begin = new->tv_begin;
1200 old->tv_end = new->tv_end;
1201
c98d5d94
LB
1202 old->tsc = new->tsc - old->tsc;
1203
1204 /* check for TSC < 1 Mcycles over interval */
b2c95d90
JT
1205 if (old->tsc < (1000 * 1000))
1206 errx(-3, "Insanely slow TSC rate, TSC stops in idle?\n"
1207 "You can disable all c-states by booting with \"idle=poll\"\n"
1208 "or just the deep ones with \"processor.max_cstate=1\"");
103a8fea 1209
c98d5d94 1210 old->c1 = new->c1 - old->c1;
103a8fea 1211
812db3f7 1212 if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz)) {
a729617c
LB
1213 if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) {
1214 old->aperf = new->aperf - old->aperf;
1215 old->mperf = new->mperf - old->mperf;
1216 } else {
ba3dec99 1217 return -1;
103a8fea 1218 }
c98d5d94 1219 }
103a8fea 1220
103a8fea 1221
144b44b1
LB
1222 if (use_c1_residency_msr) {
1223 /*
1224 * Some models have a dedicated C1 residency MSR,
1225 * which should be more accurate than the derivation below.
1226 */
1227 } else {
1228 /*
1229 * As counter collection is not atomic,
1230 * it is possible for mperf's non-halted cycles + idle states
1231 * to exceed TSC's all cycles: show c1 = 0% in that case.
1232 */
95149369 1233 if ((old->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > (old->tsc * tsc_tweak))
144b44b1
LB
1234 old->c1 = 0;
1235 else {
1236 /* normal case, derive c1 */
008d396e 1237 old->c1 = (old->tsc * tsc_tweak) - old->mperf - core_delta->c3
c98d5d94 1238 - core_delta->c6 - core_delta->c7;
144b44b1 1239 }
c98d5d94 1240 }
c3ae331d 1241
c98d5d94 1242 if (old->mperf == 0) {
b7d8c148
LB
1243 if (debug > 1)
1244 fprintf(outf, "cpu%d MPERF 0!\n", old->cpu_id);
c98d5d94 1245 old->mperf = 1; /* divide by 0 protection */
103a8fea 1246 }
c98d5d94 1247
812db3f7 1248 if (DO_BIC(BIC_IRQ))
562a2d37
LB
1249 old->irq_count = new->irq_count - old->irq_count;
1250
812db3f7 1251 if (DO_BIC(BIC_SMI))
1ed51011 1252 old->smi_count = new->smi_count - old->smi_count;
ba3dec99 1253
388e9c81
LB
1254 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
1255 if (mp->format == FORMAT_RAW)
1256 old->counter[i] = new->counter[i];
1257 else
1258 old->counter[i] = new->counter[i] - old->counter[i];
1259 }
ba3dec99 1260 return 0;
c98d5d94
LB
1261}
1262
1263int delta_cpu(struct thread_data *t, struct core_data *c,
1264 struct pkg_data *p, struct thread_data *t2,
1265 struct core_data *c2, struct pkg_data *p2)
1266{
ba3dec99
LB
1267 int retval = 0;
1268
c98d5d94
LB
1269 /* calculate core delta only for 1st thread in core */
1270 if (t->flags & CPU_IS_FIRST_THREAD_IN_CORE)
1271 delta_core(c, c2);
1272
1273 /* always calculate thread delta */
ba3dec99
LB
1274 retval = delta_thread(t, t2, c2); /* c2 is core delta */
1275 if (retval)
1276 return retval;
c98d5d94
LB
1277
1278 /* calculate package delta only for 1st core in package */
1279 if (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)
ba3dec99 1280 retval = delta_package(p, p2);
c98d5d94 1281
ba3dec99 1282 return retval;
103a8fea
LB
1283}
1284
c98d5d94
LB
1285void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1286{
388e9c81
LB
1287 int i;
1288 struct msr_counter *mp;
1289
3f44a5c6
LB
1290 t->tv_begin.tv_sec = 0;
1291 t->tv_begin.tv_usec = 0;
1292 t->tv_end.tv_sec = 0;
1293 t->tv_end.tv_usec = 0;
1294
c98d5d94
LB
1295 t->tsc = 0;
1296 t->aperf = 0;
1297 t->mperf = 0;
1298 t->c1 = 0;
1299
562a2d37
LB
1300 t->irq_count = 0;
1301 t->smi_count = 0;
1302
c98d5d94
LB
1303 /* tells format_counters to dump all fields from this set */
1304 t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE;
1305
1306 c->c3 = 0;
1307 c->c6 = 0;
1308 c->c7 = 0;
0539ba11 1309 c->mc6_us = 0;
889facbe 1310 c->core_temp_c = 0;
c98d5d94 1311
0b2bb692
LB
1312 p->pkg_wtd_core_c0 = 0;
1313 p->pkg_any_core_c0 = 0;
1314 p->pkg_any_gfxe_c0 = 0;
1315 p->pkg_both_core_gfxe_c0 = 0;
1316
c98d5d94 1317 p->pc2 = 0;
0f47c08d 1318 if (DO_BIC(BIC_Pkgpc3))
ee7e38e3 1319 p->pc3 = 0;
0f47c08d 1320 if (DO_BIC(BIC_Pkgpc6))
ee7e38e3 1321 p->pc6 = 0;
0f47c08d 1322 if (DO_BIC(BIC_Pkgpc7))
ee7e38e3 1323 p->pc7 = 0;
ca58710f
KCA
1324 p->pc8 = 0;
1325 p->pc9 = 0;
1326 p->pc10 = 0;
be0e54c4
LB
1327 p->cpu_lpi = 0;
1328 p->sys_lpi = 0;
889facbe
LB
1329
1330 p->energy_pkg = 0;
1331 p->energy_dram = 0;
1332 p->energy_cores = 0;
1333 p->energy_gfx = 0;
1334 p->rapl_pkg_perf_status = 0;
1335 p->rapl_dram_perf_status = 0;
1336 p->pkg_temp_c = 0;
27d47356 1337
fdf676e5 1338 p->gfx_rc6_ms = 0;
27d47356 1339 p->gfx_mhz = 0;
388e9c81
LB
1340 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next)
1341 t->counter[i] = 0;
1342
1343 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next)
1344 c->counter[i] = 0;
1345
1346 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next)
1347 p->counter[i] = 0;
c98d5d94
LB
1348}
1349int sum_counters(struct thread_data *t, struct core_data *c,
1350 struct pkg_data *p)
103a8fea 1351{
388e9c81
LB
1352 int i;
1353 struct msr_counter *mp;
1354
3f44a5c6
LB
1355 /* remember first tv_begin */
1356 if (average.threads.tv_begin.tv_sec == 0)
1357 average.threads.tv_begin = t->tv_begin;
1358
1359 /* remember last tv_end */
1360 average.threads.tv_end = t->tv_end;
1361
c98d5d94
LB
1362 average.threads.tsc += t->tsc;
1363 average.threads.aperf += t->aperf;
1364 average.threads.mperf += t->mperf;
1365 average.threads.c1 += t->c1;
103a8fea 1366
562a2d37
LB
1367 average.threads.irq_count += t->irq_count;
1368 average.threads.smi_count += t->smi_count;
1369
388e9c81
LB
1370 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
1371 if (mp->format == FORMAT_RAW)
1372 continue;
1373 average.threads.counter[i] += t->counter[i];
1374 }
1375
c98d5d94
LB
1376 /* sum per-core values only for 1st thread in core */
1377 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
1378 return 0;
103a8fea 1379
c98d5d94
LB
1380 average.cores.c3 += c->c3;
1381 average.cores.c6 += c->c6;
1382 average.cores.c7 += c->c7;
0539ba11 1383 average.cores.mc6_us += c->mc6_us;
c98d5d94 1384
889facbe
LB
1385 average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c);
1386
388e9c81
LB
1387 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
1388 if (mp->format == FORMAT_RAW)
1389 continue;
1390 average.cores.counter[i] += c->counter[i];
1391 }
1392
c98d5d94
LB
1393 /* sum per-pkg values only for 1st core in pkg */
1394 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
1395 return 0;
1396
a99d8730 1397 if (DO_BIC(BIC_Totl_c0))
0b2bb692 1398 average.packages.pkg_wtd_core_c0 += p->pkg_wtd_core_c0;
a99d8730 1399 if (DO_BIC(BIC_Any_c0))
0b2bb692 1400 average.packages.pkg_any_core_c0 += p->pkg_any_core_c0;
a99d8730 1401 if (DO_BIC(BIC_GFX_c0))
0b2bb692 1402 average.packages.pkg_any_gfxe_c0 += p->pkg_any_gfxe_c0;
a99d8730 1403 if (DO_BIC(BIC_CPUGFX))
0b2bb692 1404 average.packages.pkg_both_core_gfxe_c0 += p->pkg_both_core_gfxe_c0;
0b2bb692 1405
c98d5d94 1406 average.packages.pc2 += p->pc2;
0f47c08d 1407 if (DO_BIC(BIC_Pkgpc3))
ee7e38e3 1408 average.packages.pc3 += p->pc3;
0f47c08d 1409 if (DO_BIC(BIC_Pkgpc6))
ee7e38e3 1410 average.packages.pc6 += p->pc6;
0f47c08d 1411 if (DO_BIC(BIC_Pkgpc7))
ee7e38e3 1412 average.packages.pc7 += p->pc7;
ca58710f
KCA
1413 average.packages.pc8 += p->pc8;
1414 average.packages.pc9 += p->pc9;
1415 average.packages.pc10 += p->pc10;
c98d5d94 1416
be0e54c4
LB
1417 average.packages.cpu_lpi = p->cpu_lpi;
1418 average.packages.sys_lpi = p->sys_lpi;
1419
889facbe
LB
1420 average.packages.energy_pkg += p->energy_pkg;
1421 average.packages.energy_dram += p->energy_dram;
1422 average.packages.energy_cores += p->energy_cores;
1423 average.packages.energy_gfx += p->energy_gfx;
1424
fdf676e5 1425 average.packages.gfx_rc6_ms = p->gfx_rc6_ms;
27d47356
LB
1426 average.packages.gfx_mhz = p->gfx_mhz;
1427
889facbe
LB
1428 average.packages.pkg_temp_c = MAX(average.packages.pkg_temp_c, p->pkg_temp_c);
1429
1430 average.packages.rapl_pkg_perf_status += p->rapl_pkg_perf_status;
1431 average.packages.rapl_dram_perf_status += p->rapl_dram_perf_status;
388e9c81
LB
1432
1433 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
1434 if (mp->format == FORMAT_RAW)
1435 continue;
1436 average.packages.counter[i] += p->counter[i];
1437 }
c98d5d94
LB
1438 return 0;
1439}
1440/*
1441 * sum the counters for all cpus in the system
1442 * compute the weighted average
1443 */
1444void compute_average(struct thread_data *t, struct core_data *c,
1445 struct pkg_data *p)
1446{
388e9c81
LB
1447 int i;
1448 struct msr_counter *mp;
1449
c98d5d94
LB
1450 clear_counters(&average.threads, &average.cores, &average.packages);
1451
1452 for_all_cpus(sum_counters, t, c, p);
1453
1454 average.threads.tsc /= topo.num_cpus;
1455 average.threads.aperf /= topo.num_cpus;
1456 average.threads.mperf /= topo.num_cpus;
1457 average.threads.c1 /= topo.num_cpus;
1458
0de6c0df
LB
1459 if (average.threads.irq_count > 9999999)
1460 sums_need_wide_columns = 1;
1461
c98d5d94
LB
1462 average.cores.c3 /= topo.num_cores;
1463 average.cores.c6 /= topo.num_cores;
1464 average.cores.c7 /= topo.num_cores;
0539ba11 1465 average.cores.mc6_us /= topo.num_cores;
c98d5d94 1466
a99d8730 1467 if (DO_BIC(BIC_Totl_c0))
0b2bb692 1468 average.packages.pkg_wtd_core_c0 /= topo.num_packages;
a99d8730 1469 if (DO_BIC(BIC_Any_c0))
0b2bb692 1470 average.packages.pkg_any_core_c0 /= topo.num_packages;
a99d8730 1471 if (DO_BIC(BIC_GFX_c0))
0b2bb692 1472 average.packages.pkg_any_gfxe_c0 /= topo.num_packages;
a99d8730 1473 if (DO_BIC(BIC_CPUGFX))
0b2bb692 1474 average.packages.pkg_both_core_gfxe_c0 /= topo.num_packages;
0b2bb692 1475
c98d5d94 1476 average.packages.pc2 /= topo.num_packages;
0f47c08d 1477 if (DO_BIC(BIC_Pkgpc3))
ee7e38e3 1478 average.packages.pc3 /= topo.num_packages;
0f47c08d 1479 if (DO_BIC(BIC_Pkgpc6))
ee7e38e3 1480 average.packages.pc6 /= topo.num_packages;
0f47c08d 1481 if (DO_BIC(BIC_Pkgpc7))
ee7e38e3 1482 average.packages.pc7 /= topo.num_packages;
ca58710f
KCA
1483
1484 average.packages.pc8 /= topo.num_packages;
1485 average.packages.pc9 /= topo.num_packages;
1486 average.packages.pc10 /= topo.num_packages;
388e9c81
LB
1487
1488 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
1489 if (mp->format == FORMAT_RAW)
1490 continue;
0de6c0df
LB
1491 if (mp->type == COUNTER_ITEMS) {
1492 if (average.threads.counter[i] > 9999999)
1493 sums_need_wide_columns = 1;
41618e63 1494 continue;
0de6c0df 1495 }
388e9c81
LB
1496 average.threads.counter[i] /= topo.num_cpus;
1497 }
1498 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
1499 if (mp->format == FORMAT_RAW)
1500 continue;
0de6c0df
LB
1501 if (mp->type == COUNTER_ITEMS) {
1502 if (average.cores.counter[i] > 9999999)
1503 sums_need_wide_columns = 1;
1504 }
388e9c81
LB
1505 average.cores.counter[i] /= topo.num_cores;
1506 }
1507 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
1508 if (mp->format == FORMAT_RAW)
1509 continue;
0de6c0df
LB
1510 if (mp->type == COUNTER_ITEMS) {
1511 if (average.packages.counter[i] > 9999999)
1512 sums_need_wide_columns = 1;
1513 }
388e9c81
LB
1514 average.packages.counter[i] /= topo.num_packages;
1515 }
103a8fea
LB
1516}
1517
c98d5d94 1518static unsigned long long rdtsc(void)
103a8fea 1519{
c98d5d94 1520 unsigned int low, high;
15aaa346 1521
c98d5d94 1522 asm volatile("rdtsc" : "=a" (low), "=d" (high));
15aaa346 1523
c98d5d94
LB
1524 return low | ((unsigned long long)high) << 32;
1525}
15aaa346 1526
495c7654
LB
1527/*
1528 * Open a file, and exit on failure
1529 */
1530FILE *fopen_or_die(const char *path, const char *mode)
1531{
1532 FILE *filep = fopen(path, mode);
1533
1534 if (!filep)
1535 err(1, "%s: open failed", path);
1536 return filep;
1537}
1538/*
1539 * snapshot_sysfs_counter()
1540 *
1541 * return snapshot of given counter
1542 */
1543unsigned long long snapshot_sysfs_counter(char *path)
1544{
1545 FILE *fp;
1546 int retval;
1547 unsigned long long counter;
1548
1549 fp = fopen_or_die(path, "r");
1550
1551 retval = fscanf(fp, "%lld", &counter);
1552 if (retval != 1)
1553 err(1, "snapshot_sysfs_counter(%s)", path);
1554
1555 fclose(fp);
1556
1557 return counter;
1558}
1559
1560int get_mp(int cpu, struct msr_counter *mp, unsigned long long *counterp)
1561{
1562 if (mp->msr_num != 0) {
1563 if (get_msr(cpu, mp->msr_num, counterp))
1564 return -1;
1565 } else {
46c27978 1566 char path[128 + PATH_BYTES];
41618e63
LB
1567
1568 if (mp->flags & SYSFS_PERCPU) {
1569 sprintf(path, "/sys/devices/system/cpu/cpu%d/%s",
1570 cpu, mp->path);
1571
1572 *counterp = snapshot_sysfs_counter(path);
1573 } else {
1574 *counterp = snapshot_sysfs_counter(mp->path);
1575 }
495c7654
LB
1576 }
1577
1578 return 0;
1579}
1580
c98d5d94
LB
1581/*
1582 * get_counters(...)
1583 * migrate to cpu
1584 * acquire and record local counters for that cpu
1585 */
1586int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1587{
1588 int cpu = t->cpu_id;
889facbe 1589 unsigned long long msr;
0102b067 1590 int aperf_mperf_retry_count = 0;
388e9c81
LB
1591 struct msr_counter *mp;
1592 int i;
88c3281f 1593
f4fdf2b4
LB
1594
1595 gettimeofday(&t->tv_begin, (struct timezone *)NULL);
1596
e52966c0 1597 if (cpu_migrate(cpu)) {
b7d8c148 1598 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
c98d5d94 1599 return -1;
e52966c0 1600 }
15aaa346 1601
0102b067 1602retry:
c98d5d94
LB
1603 t->tsc = rdtsc(); /* we are running on local CPU of interest */
1604
812db3f7 1605 if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz)) {
0102b067
LB
1606 unsigned long long tsc_before, tsc_between, tsc_after, aperf_time, mperf_time;
1607
1608 /*
1609 * The TSC, APERF and MPERF must be read together for
1610 * APERF/MPERF and MPERF/TSC to give accurate results.
1611 *
1612 * Unfortunately, APERF and MPERF are read by
1613 * individual system call, so delays may occur
1614 * between them. If the time to read them
1615 * varies by a large amount, we re-read them.
1616 */
1617
1618 /*
1619 * This initial dummy APERF read has been seen to
1620 * reduce jitter in the subsequent reads.
1621 */
1622
1623 if (get_msr(cpu, MSR_IA32_APERF, &t->aperf))
1624 return -3;
1625
1626 t->tsc = rdtsc(); /* re-read close to APERF */
1627
1628 tsc_before = t->tsc;
1629
9c63a650 1630 if (get_msr(cpu, MSR_IA32_APERF, &t->aperf))
c98d5d94 1631 return -3;
0102b067
LB
1632
1633 tsc_between = rdtsc();
1634
9c63a650 1635 if (get_msr(cpu, MSR_IA32_MPERF, &t->mperf))
c98d5d94 1636 return -4;
0102b067
LB
1637
1638 tsc_after = rdtsc();
1639
1640 aperf_time = tsc_between - tsc_before;
1641 mperf_time = tsc_after - tsc_between;
1642
1643 /*
1644 * If the system call latency to read APERF and MPERF
1645 * differ by more than 2x, then try again.
1646 */
1647 if ((aperf_time > (2 * mperf_time)) || (mperf_time > (2 * aperf_time))) {
1648 aperf_mperf_retry_count++;
1649 if (aperf_mperf_retry_count < 5)
1650 goto retry;
1651 else
1652 warnx("cpu%d jitter %lld %lld",
1653 cpu, aperf_time, mperf_time);
1654 }
1655 aperf_mperf_retry_count = 0;
1656
b2b34dfe
HC
1657 t->aperf = t->aperf * aperf_mperf_multiplier;
1658 t->mperf = t->mperf * aperf_mperf_multiplier;
c98d5d94
LB
1659 }
1660
812db3f7 1661 if (DO_BIC(BIC_IRQ))
562a2d37 1662 t->irq_count = irqs_per_cpu[cpu];
812db3f7 1663 if (DO_BIC(BIC_SMI)) {
1ed51011
LB
1664 if (get_msr(cpu, MSR_SMI_COUNT, &msr))
1665 return -5;
1666 t->smi_count = msr & 0xFFFFFFFF;
1667 }
0539ba11 1668 if (DO_BIC(BIC_CPU_c1) && use_c1_residency_msr) {
144b44b1
LB
1669 if (get_msr(cpu, MSR_CORE_C1_RES, &t->c1))
1670 return -6;
1671 }
1672
388e9c81 1673 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
495c7654 1674 if (get_mp(cpu, mp, &t->counter[i]))
388e9c81
LB
1675 return -10;
1676 }
1677
c98d5d94
LB
1678 /* collect core counters only for 1st thread in core */
1679 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
f4fdf2b4 1680 goto done;
c98d5d94 1681
997e5395 1682 if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates && !do_cnl_cstates) {
c98d5d94
LB
1683 if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3))
1684 return -6;
144b44b1
LB
1685 }
1686
812db3f7 1687 if (DO_BIC(BIC_CPU_c6) && !do_knl_cstates) {
c98d5d94
LB
1688 if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6))
1689 return -7;
fb5d4327
DC
1690 } else if (do_knl_cstates) {
1691 if (get_msr(cpu, MSR_KNL_CORE_C6_RESIDENCY, &c->c6))
1692 return -7;
c98d5d94
LB
1693 }
1694
812db3f7 1695 if (DO_BIC(BIC_CPU_c7))
c98d5d94
LB
1696 if (get_msr(cpu, MSR_CORE_C7_RESIDENCY, &c->c7))
1697 return -8;
1698
0539ba11
LB
1699 if (DO_BIC(BIC_Mod_c6))
1700 if (get_msr(cpu, MSR_MODULE_C6_RES_MS, &c->mc6_us))
1701 return -8;
1702
812db3f7 1703 if (DO_BIC(BIC_CoreTmp)) {
889facbe
LB
1704 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
1705 return -9;
1706 c->core_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F);
1707 }
1708
388e9c81 1709 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
495c7654 1710 if (get_mp(cpu, mp, &c->counter[i]))
388e9c81
LB
1711 return -10;
1712 }
889facbe 1713
c98d5d94
LB
1714 /* collect package counters only for 1st core in package */
1715 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
f4fdf2b4 1716 goto done;
c98d5d94 1717
a99d8730 1718 if (DO_BIC(BIC_Totl_c0)) {
0b2bb692
LB
1719 if (get_msr(cpu, MSR_PKG_WEIGHTED_CORE_C0_RES, &p->pkg_wtd_core_c0))
1720 return -10;
a99d8730
LB
1721 }
1722 if (DO_BIC(BIC_Any_c0)) {
0b2bb692
LB
1723 if (get_msr(cpu, MSR_PKG_ANY_CORE_C0_RES, &p->pkg_any_core_c0))
1724 return -11;
a99d8730
LB
1725 }
1726 if (DO_BIC(BIC_GFX_c0)) {
0b2bb692
LB
1727 if (get_msr(cpu, MSR_PKG_ANY_GFXE_C0_RES, &p->pkg_any_gfxe_c0))
1728 return -12;
a99d8730
LB
1729 }
1730 if (DO_BIC(BIC_CPUGFX)) {
0b2bb692
LB
1731 if (get_msr(cpu, MSR_PKG_BOTH_CORE_GFXE_C0_RES, &p->pkg_both_core_gfxe_c0))
1732 return -13;
1733 }
0f47c08d 1734 if (DO_BIC(BIC_Pkgpc3))
c98d5d94
LB
1735 if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3))
1736 return -9;
0f47c08d 1737 if (DO_BIC(BIC_Pkgpc6)) {
0539ba11
LB
1738 if (do_slm_cstates) {
1739 if (get_msr(cpu, MSR_ATOM_PKG_C6_RESIDENCY, &p->pc6))
1740 return -10;
1741 } else {
1742 if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6))
1743 return -10;
1744 }
1745 }
1746
0f47c08d 1747 if (DO_BIC(BIC_Pkgpc2))
c98d5d94
LB
1748 if (get_msr(cpu, MSR_PKG_C2_RESIDENCY, &p->pc2))
1749 return -11;
0f47c08d 1750 if (DO_BIC(BIC_Pkgpc7))
c98d5d94
LB
1751 if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7))
1752 return -12;
0f47c08d 1753 if (DO_BIC(BIC_Pkgpc8))
ca58710f
KCA
1754 if (get_msr(cpu, MSR_PKG_C8_RESIDENCY, &p->pc8))
1755 return -13;
0f47c08d 1756 if (DO_BIC(BIC_Pkgpc9))
ca58710f
KCA
1757 if (get_msr(cpu, MSR_PKG_C9_RESIDENCY, &p->pc9))
1758 return -13;
0f47c08d 1759 if (DO_BIC(BIC_Pkgpc10))
ca58710f
KCA
1760 if (get_msr(cpu, MSR_PKG_C10_RESIDENCY, &p->pc10))
1761 return -13;
0f47c08d 1762
be0e54c4
LB
1763 if (DO_BIC(BIC_CPU_LPI))
1764 p->cpu_lpi = cpuidle_cur_cpu_lpi_us;
1765 if (DO_BIC(BIC_SYS_LPI))
1766 p->sys_lpi = cpuidle_cur_sys_lpi_us;
1767
889facbe
LB
1768 if (do_rapl & RAPL_PKG) {
1769 if (get_msr(cpu, MSR_PKG_ENERGY_STATUS, &msr))
1770 return -13;
1771 p->energy_pkg = msr & 0xFFFFFFFF;
1772 }
9148494c 1773 if (do_rapl & RAPL_CORES_ENERGY_STATUS) {
889facbe
LB
1774 if (get_msr(cpu, MSR_PP0_ENERGY_STATUS, &msr))
1775 return -14;
1776 p->energy_cores = msr & 0xFFFFFFFF;
1777 }
1778 if (do_rapl & RAPL_DRAM) {
1779 if (get_msr(cpu, MSR_DRAM_ENERGY_STATUS, &msr))
1780 return -15;
1781 p->energy_dram = msr & 0xFFFFFFFF;
1782 }
1783 if (do_rapl & RAPL_GFX) {
1784 if (get_msr(cpu, MSR_PP1_ENERGY_STATUS, &msr))
1785 return -16;
1786 p->energy_gfx = msr & 0xFFFFFFFF;
1787 }
1788 if (do_rapl & RAPL_PKG_PERF_STATUS) {
1789 if (get_msr(cpu, MSR_PKG_PERF_STATUS, &msr))
1790 return -16;
1791 p->rapl_pkg_perf_status = msr & 0xFFFFFFFF;
1792 }
1793 if (do_rapl & RAPL_DRAM_PERF_STATUS) {
1794 if (get_msr(cpu, MSR_DRAM_PERF_STATUS, &msr))
1795 return -16;
1796 p->rapl_dram_perf_status = msr & 0xFFFFFFFF;
1797 }
812db3f7 1798 if (DO_BIC(BIC_PkgTmp)) {
889facbe
LB
1799 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
1800 return -17;
1801 p->pkg_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F);
1802 }
fdf676e5 1803
812db3f7 1804 if (DO_BIC(BIC_GFX_rc6))
fdf676e5
LB
1805 p->gfx_rc6_ms = gfx_cur_rc6_ms;
1806
812db3f7 1807 if (DO_BIC(BIC_GFXMHz))
27d47356
LB
1808 p->gfx_mhz = gfx_cur_mhz;
1809
388e9c81 1810 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
495c7654 1811 if (get_mp(cpu, mp, &p->counter[i]))
388e9c81
LB
1812 return -10;
1813 }
f4fdf2b4
LB
1814done:
1815 gettimeofday(&t->tv_end, (struct timezone *)NULL);
388e9c81 1816
15aaa346 1817 return 0;
103a8fea
LB
1818}
1819
ee7e38e3
LB
1820/*
1821 * MSR_PKG_CST_CONFIG_CONTROL decoding for pkg_cstate_limit:
1822 * If you change the values, note they are used both in comparisons
1823 * (>= PCL__7) and to index pkg_cstate_limit_strings[].
1824 */
1825
1826#define PCLUKN 0 /* Unknown */
1827#define PCLRSV 1 /* Reserved */
1828#define PCL__0 2 /* PC0 */
1829#define PCL__1 3 /* PC1 */
1830#define PCL__2 4 /* PC2 */
1831#define PCL__3 5 /* PC3 */
1832#define PCL__4 6 /* PC4 */
1833#define PCL__6 7 /* PC6 */
1834#define PCL_6N 8 /* PC6 No Retention */
1835#define PCL_6R 9 /* PC6 Retention */
1836#define PCL__7 10 /* PC7 */
1837#define PCL_7S 11 /* PC7 Shrink */
0b2bb692
LB
1838#define PCL__8 12 /* PC8 */
1839#define PCL__9 13 /* PC9 */
1840#define PCLUNL 14 /* Unlimited */
ee7e38e3
LB
1841
1842int pkg_cstate_limit = PCLUKN;
1843char *pkg_cstate_limit_strings[] = { "reserved", "unknown", "pc0", "pc1", "pc2",
0b2bb692 1844 "pc3", "pc4", "pc6", "pc6n", "pc6r", "pc7", "pc7s", "pc8", "pc9", "unlimited"};
ee7e38e3 1845
e9257f5f
LB
1846int 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};
1847int 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};
1848int 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};
0539ba11 1849int slv_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7};
f2642888 1850int amt_pkg_cstate_limits[16] = {PCLUNL, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
e9257f5f 1851int 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 1852int bxt_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
2085e124 1853int skx_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
ee7e38e3 1854
a2b7b749
LB
1855
1856static void
1857calculate_tsc_tweak()
1858{
a2b7b749
LB
1859 tsc_tweak = base_hz / tsc_hz;
1860}
1861
fcd17211
LB
1862static void
1863dump_nhm_platform_info(void)
103a8fea
LB
1864{
1865 unsigned long long msr;
1866 unsigned int ratio;
1867
ec0adc53 1868 get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
103a8fea 1869
b7d8c148 1870 fprintf(outf, "cpu%d: MSR_PLATFORM_INFO: 0x%08llx\n", base_cpu, msr);
6574a5d5 1871
103a8fea 1872 ratio = (msr >> 40) & 0xFF;
710f273b 1873 fprintf(outf, "%d * %.1f = %.1f MHz max efficiency frequency\n",
103a8fea
LB
1874 ratio, bclk, ratio * bclk);
1875
1876 ratio = (msr >> 8) & 0xFF;
710f273b 1877 fprintf(outf, "%d * %.1f = %.1f MHz base frequency\n",
103a8fea
LB
1878 ratio, bclk, ratio * bclk);
1879
7ce7d5de 1880 get_msr(base_cpu, MSR_IA32_POWER_CTL, &msr);
b7d8c148 1881 fprintf(outf, "cpu%d: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n",
bfae2052 1882 base_cpu, msr, msr & 0x2 ? "EN" : "DIS");
67920418 1883
fcd17211
LB
1884 return;
1885}
1886
1887static void
1888dump_hsw_turbo_ratio_limits(void)
1889{
1890 unsigned long long msr;
1891 unsigned int ratio;
1892
7ce7d5de 1893 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT2, &msr);
fcd17211 1894
b7d8c148 1895 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT2: 0x%08llx\n", base_cpu, msr);
fcd17211
LB
1896
1897 ratio = (msr >> 8) & 0xFF;
1898 if (ratio)
710f273b 1899 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 18 active cores\n",
fcd17211
LB
1900 ratio, bclk, ratio * bclk);
1901
1902 ratio = (msr >> 0) & 0xFF;
1903 if (ratio)
710f273b 1904 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 17 active cores\n",
fcd17211
LB
1905 ratio, bclk, ratio * bclk);
1906 return;
1907}
1908
1909static void
1910dump_ivt_turbo_ratio_limits(void)
1911{
1912 unsigned long long msr;
1913 unsigned int ratio;
6574a5d5 1914
7ce7d5de 1915 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &msr);
6574a5d5 1916
b7d8c148 1917 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, msr);
6574a5d5
LB
1918
1919 ratio = (msr >> 56) & 0xFF;
1920 if (ratio)
710f273b 1921 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 16 active cores\n",
6574a5d5
LB
1922 ratio, bclk, ratio * bclk);
1923
1924 ratio = (msr >> 48) & 0xFF;
1925 if (ratio)
710f273b 1926 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 15 active cores\n",
6574a5d5
LB
1927 ratio, bclk, ratio * bclk);
1928
1929 ratio = (msr >> 40) & 0xFF;
1930 if (ratio)
710f273b 1931 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 14 active cores\n",
6574a5d5
LB
1932 ratio, bclk, ratio * bclk);
1933
1934 ratio = (msr >> 32) & 0xFF;
1935 if (ratio)
710f273b 1936 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 13 active cores\n",
6574a5d5
LB
1937 ratio, bclk, ratio * bclk);
1938
1939 ratio = (msr >> 24) & 0xFF;
1940 if (ratio)
710f273b 1941 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 12 active cores\n",
6574a5d5
LB
1942 ratio, bclk, ratio * bclk);
1943
1944 ratio = (msr >> 16) & 0xFF;
1945 if (ratio)
710f273b 1946 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 11 active cores\n",
6574a5d5
LB
1947 ratio, bclk, ratio * bclk);
1948
1949 ratio = (msr >> 8) & 0xFF;
1950 if (ratio)
710f273b 1951 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 10 active cores\n",
6574a5d5
LB
1952 ratio, bclk, ratio * bclk);
1953
1954 ratio = (msr >> 0) & 0xFF;
1955 if (ratio)
710f273b 1956 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 9 active cores\n",
6574a5d5 1957 ratio, bclk, ratio * bclk);
fcd17211
LB
1958 return;
1959}
31e07522
LB
1960int has_turbo_ratio_group_limits(int family, int model)
1961{
1962
1963 if (!genuine_intel)
1964 return 0;
1965
1966 switch (model) {
1967 case INTEL_FAM6_ATOM_GOLDMONT:
1968 case INTEL_FAM6_SKYLAKE_X:
1969 case INTEL_FAM6_ATOM_DENVERTON:
1970 return 1;
1971 }
1972 return 0;
1973}
6574a5d5 1974
fcd17211 1975static void
31e07522 1976dump_turbo_ratio_limits(int family, int model)
fcd17211 1977{
31e07522
LB
1978 unsigned long long msr, core_counts;
1979 unsigned int ratio, group_size;
103a8fea 1980
7ce7d5de 1981 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
b7d8c148 1982 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", base_cpu, msr);
6574a5d5 1983
31e07522
LB
1984 if (has_turbo_ratio_group_limits(family, model)) {
1985 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &core_counts);
1986 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, core_counts);
1987 } else {
1988 core_counts = 0x0807060504030201;
1989 }
1990
6574a5d5 1991 ratio = (msr >> 56) & 0xFF;
31e07522 1992 group_size = (core_counts >> 56) & 0xFF;
6574a5d5 1993 if (ratio)
31e07522
LB
1994 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1995 ratio, bclk, ratio * bclk, group_size);
6574a5d5
LB
1996
1997 ratio = (msr >> 48) & 0xFF;
31e07522 1998 group_size = (core_counts >> 48) & 0xFF;
6574a5d5 1999 if (ratio)
31e07522
LB
2000 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
2001 ratio, bclk, ratio * bclk, group_size);
6574a5d5
LB
2002
2003 ratio = (msr >> 40) & 0xFF;
31e07522 2004 group_size = (core_counts >> 40) & 0xFF;
6574a5d5 2005 if (ratio)
31e07522
LB
2006 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
2007 ratio, bclk, ratio * bclk, group_size);
6574a5d5
LB
2008
2009 ratio = (msr >> 32) & 0xFF;
31e07522 2010 group_size = (core_counts >> 32) & 0xFF;
6574a5d5 2011 if (ratio)
31e07522
LB
2012 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
2013 ratio, bclk, ratio * bclk, group_size);
6574a5d5 2014
103a8fea 2015 ratio = (msr >> 24) & 0xFF;
31e07522 2016 group_size = (core_counts >> 24) & 0xFF;
103a8fea 2017 if (ratio)
31e07522
LB
2018 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
2019 ratio, bclk, ratio * bclk, group_size);
103a8fea
LB
2020
2021 ratio = (msr >> 16) & 0xFF;
31e07522 2022 group_size = (core_counts >> 16) & 0xFF;
103a8fea 2023 if (ratio)
31e07522
LB
2024 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
2025 ratio, bclk, ratio * bclk, group_size);
103a8fea
LB
2026
2027 ratio = (msr >> 8) & 0xFF;
31e07522 2028 group_size = (core_counts >> 8) & 0xFF;
103a8fea 2029 if (ratio)
31e07522
LB
2030 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
2031 ratio, bclk, ratio * bclk, group_size);
103a8fea
LB
2032
2033 ratio = (msr >> 0) & 0xFF;
31e07522 2034 group_size = (core_counts >> 0) & 0xFF;
103a8fea 2035 if (ratio)
31e07522
LB
2036 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
2037 ratio, bclk, ratio * bclk, group_size);
fcd17211
LB
2038 return;
2039}
3a9a941d 2040
0f7887c4
LB
2041static void
2042dump_atom_turbo_ratio_limits(void)
2043{
2044 unsigned long long msr;
2045 unsigned int ratio;
2046
2047 get_msr(base_cpu, MSR_ATOM_CORE_RATIOS, &msr);
2048 fprintf(outf, "cpu%d: MSR_ATOM_CORE_RATIOS: 0x%08llx\n", base_cpu, msr & 0xFFFFFFFF);
2049
2050 ratio = (msr >> 0) & 0x3F;
2051 if (ratio)
2052 fprintf(outf, "%d * %.1f = %.1f MHz minimum operating frequency\n",
2053 ratio, bclk, ratio * bclk);
2054
2055 ratio = (msr >> 8) & 0x3F;
2056 if (ratio)
2057 fprintf(outf, "%d * %.1f = %.1f MHz low frequency mode (LFM)\n",
2058 ratio, bclk, ratio * bclk);
2059
2060 ratio = (msr >> 16) & 0x3F;
2061 if (ratio)
2062 fprintf(outf, "%d * %.1f = %.1f MHz base frequency\n",
2063 ratio, bclk, ratio * bclk);
2064
2065 get_msr(base_cpu, MSR_ATOM_CORE_TURBO_RATIOS, &msr);
2066 fprintf(outf, "cpu%d: MSR_ATOM_CORE_TURBO_RATIOS: 0x%08llx\n", base_cpu, msr & 0xFFFFFFFF);
2067
2068 ratio = (msr >> 24) & 0x3F;
2069 if (ratio)
2070 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 4 active cores\n",
2071 ratio, bclk, ratio * bclk);
2072
2073 ratio = (msr >> 16) & 0x3F;
2074 if (ratio)
2075 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 3 active cores\n",
2076 ratio, bclk, ratio * bclk);
2077
2078 ratio = (msr >> 8) & 0x3F;
2079 if (ratio)
2080 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 2 active cores\n",
2081 ratio, bclk, ratio * bclk);
2082
2083 ratio = (msr >> 0) & 0x3F;
2084 if (ratio)
2085 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 1 active core\n",
2086 ratio, bclk, ratio * bclk);
2087}
2088
fb5d4327
DC
2089static void
2090dump_knl_turbo_ratio_limits(void)
2091{
cbf97aba
HC
2092 const unsigned int buckets_no = 7;
2093
fb5d4327 2094 unsigned long long msr;
cbf97aba
HC
2095 int delta_cores, delta_ratio;
2096 int i, b_nr;
2097 unsigned int cores[buckets_no];
2098 unsigned int ratio[buckets_no];
fb5d4327 2099
ebf5926a 2100 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
fb5d4327 2101
b7d8c148 2102 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n",
bfae2052 2103 base_cpu, msr);
fb5d4327
DC
2104
2105 /**
2106 * Turbo encoding in KNL is as follows:
cbf97aba
HC
2107 * [0] -- Reserved
2108 * [7:1] -- Base value of number of active cores of bucket 1.
fb5d4327
DC
2109 * [15:8] -- Base value of freq ratio of bucket 1.
2110 * [20:16] -- +ve delta of number of active cores of bucket 2.
2111 * i.e. active cores of bucket 2 =
2112 * active cores of bucket 1 + delta
2113 * [23:21] -- Negative delta of freq ratio of bucket 2.
2114 * i.e. freq ratio of bucket 2 =
2115 * freq ratio of bucket 1 - delta
2116 * [28:24]-- +ve delta of number of active cores of bucket 3.
2117 * [31:29]-- -ve delta of freq ratio of bucket 3.
2118 * [36:32]-- +ve delta of number of active cores of bucket 4.
2119 * [39:37]-- -ve delta of freq ratio of bucket 4.
2120 * [44:40]-- +ve delta of number of active cores of bucket 5.
2121 * [47:45]-- -ve delta of freq ratio of bucket 5.
2122 * [52:48]-- +ve delta of number of active cores of bucket 6.
2123 * [55:53]-- -ve delta of freq ratio of bucket 6.
2124 * [60:56]-- +ve delta of number of active cores of bucket 7.
2125 * [63:61]-- -ve delta of freq ratio of bucket 7.
2126 */
cbf97aba
HC
2127
2128 b_nr = 0;
2129 cores[b_nr] = (msr & 0xFF) >> 1;
2130 ratio[b_nr] = (msr >> 8) & 0xFF;
2131
2132 for (i = 16; i < 64; i += 8) {
fb5d4327 2133 delta_cores = (msr >> i) & 0x1F;
cbf97aba
HC
2134 delta_ratio = (msr >> (i + 5)) & 0x7;
2135
2136 cores[b_nr + 1] = cores[b_nr] + delta_cores;
2137 ratio[b_nr + 1] = ratio[b_nr] - delta_ratio;
2138 b_nr++;
fb5d4327 2139 }
cbf97aba
HC
2140
2141 for (i = buckets_no - 1; i >= 0; i--)
2142 if (i > 0 ? ratio[i] != ratio[i - 1] : 1)
b7d8c148 2143 fprintf(outf,
710f273b 2144 "%d * %.1f = %.1f MHz max turbo %d active cores\n",
cbf97aba 2145 ratio[i], bclk, ratio[i] * bclk, cores[i]);
fb5d4327
DC
2146}
2147
fcd17211
LB
2148static void
2149dump_nhm_cst_cfg(void)
2150{
2151 unsigned long long msr;
2152
1df2e55a 2153 get_msr(base_cpu, MSR_PKG_CST_CONFIG_CONTROL, &msr);
fcd17211 2154
1df2e55a 2155 fprintf(outf, "cpu%d: MSR_PKG_CST_CONFIG_CONTROL: 0x%08llx", base_cpu, msr);
fcd17211 2156
3e8b62bf 2157 fprintf(outf, " (%s%s%s%s%slocked, pkg-cstate-limit=%d (%s)",
fcd17211
LB
2158 (msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "",
2159 (msr & SNB_C1_AUTO_UNDEMOTE) ? "UNdemote-C1, " : "",
2160 (msr & NHM_C3_AUTO_DEMOTE) ? "demote-C3, " : "",
2161 (msr & NHM_C1_AUTO_DEMOTE) ? "demote-C1, " : "",
2162 (msr & (1 << 15)) ? "" : "UN",
6c34f160 2163 (unsigned int)msr & 0xF,
fcd17211 2164 pkg_cstate_limit_strings[pkg_cstate_limit]);
ac980e13
AB
2165
2166#define AUTOMATIC_CSTATE_CONVERSION (1UL << 16)
2167 if (has_automatic_cstate_conversion) {
2168 fprintf(outf, ", automatic c-state conversion=%s",
2169 (msr & AUTOMATIC_CSTATE_CONVERSION) ? "on" : "off");
2170 }
2171
2172 fprintf(outf, ")\n");
2173
fcd17211 2174 return;
103a8fea
LB
2175}
2176
6fb3143b
LB
2177static void
2178dump_config_tdp(void)
2179{
2180 unsigned long long msr;
2181
2182 get_msr(base_cpu, MSR_CONFIG_TDP_NOMINAL, &msr);
b7d8c148 2183 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_NOMINAL: 0x%08llx", base_cpu, msr);
685b535b 2184 fprintf(outf, " (base_ratio=%d)\n", (unsigned int)msr & 0xFF);
6fb3143b
LB
2185
2186 get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_1, &msr);
b7d8c148 2187 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_1: 0x%08llx (", base_cpu, msr);
6fb3143b 2188 if (msr) {
685b535b
CY
2189 fprintf(outf, "PKG_MIN_PWR_LVL1=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
2190 fprintf(outf, "PKG_MAX_PWR_LVL1=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
2191 fprintf(outf, "LVL1_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
2192 fprintf(outf, "PKG_TDP_LVL1=%d", (unsigned int)(msr) & 0x7FFF);
6fb3143b 2193 }
b7d8c148 2194 fprintf(outf, ")\n");
6fb3143b
LB
2195
2196 get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_2, &msr);
b7d8c148 2197 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_2: 0x%08llx (", base_cpu, msr);
6fb3143b 2198 if (msr) {
685b535b
CY
2199 fprintf(outf, "PKG_MIN_PWR_LVL2=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
2200 fprintf(outf, "PKG_MAX_PWR_LVL2=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
2201 fprintf(outf, "LVL2_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
2202 fprintf(outf, "PKG_TDP_LVL2=%d", (unsigned int)(msr) & 0x7FFF);
6fb3143b 2203 }
b7d8c148 2204 fprintf(outf, ")\n");
6fb3143b
LB
2205
2206 get_msr(base_cpu, MSR_CONFIG_TDP_CONTROL, &msr);
b7d8c148 2207 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_CONTROL: 0x%08llx (", base_cpu, msr);
6fb3143b 2208 if ((msr) & 0x3)
b7d8c148
LB
2209 fprintf(outf, "TDP_LEVEL=%d ", (unsigned int)(msr) & 0x3);
2210 fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
2211 fprintf(outf, ")\n");
36229897 2212
6fb3143b 2213 get_msr(base_cpu, MSR_TURBO_ACTIVATION_RATIO, &msr);
b7d8c148 2214 fprintf(outf, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu, msr);
685b535b 2215 fprintf(outf, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0xFF);
b7d8c148
LB
2216 fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
2217 fprintf(outf, ")\n");
6fb3143b 2218}
5a63426e
LB
2219
2220unsigned int irtl_time_units[] = {1, 32, 1024, 32768, 1048576, 33554432, 0, 0 };
2221
2222void print_irtl(void)
2223{
2224 unsigned long long msr;
2225
2226 get_msr(base_cpu, MSR_PKGC3_IRTL, &msr);
2227 fprintf(outf, "cpu%d: MSR_PKGC3_IRTL: 0x%08llx (", base_cpu, msr);
2228 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
2229 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
2230
2231 get_msr(base_cpu, MSR_PKGC6_IRTL, &msr);
2232 fprintf(outf, "cpu%d: MSR_PKGC6_IRTL: 0x%08llx (", base_cpu, msr);
2233 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
2234 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
2235
2236 get_msr(base_cpu, MSR_PKGC7_IRTL, &msr);
2237 fprintf(outf, "cpu%d: MSR_PKGC7_IRTL: 0x%08llx (", base_cpu, msr);
2238 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
2239 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
2240
2241 if (!do_irtl_hsw)
2242 return;
2243
2244 get_msr(base_cpu, MSR_PKGC8_IRTL, &msr);
2245 fprintf(outf, "cpu%d: MSR_PKGC8_IRTL: 0x%08llx (", base_cpu, msr);
2246 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
2247 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
2248
2249 get_msr(base_cpu, MSR_PKGC9_IRTL, &msr);
2250 fprintf(outf, "cpu%d: MSR_PKGC9_IRTL: 0x%08llx (", base_cpu, msr);
2251 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
2252 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
2253
2254 get_msr(base_cpu, MSR_PKGC10_IRTL, &msr);
2255 fprintf(outf, "cpu%d: MSR_PKGC10_IRTL: 0x%08llx (", base_cpu, msr);
2256 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
2257 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
2258
2259}
36229897
LB
2260void free_fd_percpu(void)
2261{
2262 int i;
2263
01a67adf 2264 for (i = 0; i < topo.max_cpu_num + 1; ++i) {
36229897
LB
2265 if (fd_percpu[i] != 0)
2266 close(fd_percpu[i]);
2267 }
2268
2269 free(fd_percpu);
6fb3143b
LB
2270}
2271
c98d5d94 2272void free_all_buffers(void)
103a8fea 2273{
c98d5d94
LB
2274 CPU_FREE(cpu_present_set);
2275 cpu_present_set = NULL;
36229897 2276 cpu_present_setsize = 0;
103a8fea 2277
c98d5d94
LB
2278 CPU_FREE(cpu_affinity_set);
2279 cpu_affinity_set = NULL;
2280 cpu_affinity_setsize = 0;
103a8fea 2281
c98d5d94
LB
2282 free(thread_even);
2283 free(core_even);
2284 free(package_even);
103a8fea 2285
c98d5d94
LB
2286 thread_even = NULL;
2287 core_even = NULL;
2288 package_even = NULL;
103a8fea 2289
c98d5d94
LB
2290 free(thread_odd);
2291 free(core_odd);
2292 free(package_odd);
103a8fea 2293
c98d5d94
LB
2294 thread_odd = NULL;
2295 core_odd = NULL;
2296 package_odd = NULL;
103a8fea 2297
c98d5d94
LB
2298 free(output_buffer);
2299 output_buffer = NULL;
2300 outp = NULL;
36229897
LB
2301
2302 free_fd_percpu();
562a2d37
LB
2303
2304 free(irq_column_2_cpu);
2305 free(irqs_per_cpu);
103a8fea
LB
2306}
2307
57a42a34 2308
c98d5d94 2309/*
95aebc44 2310 * Parse a file containing a single int.
c98d5d94 2311 */
95aebc44 2312int parse_int_file(const char *fmt, ...)
103a8fea 2313{
95aebc44
JT
2314 va_list args;
2315 char path[PATH_MAX];
c98d5d94 2316 FILE *filep;
95aebc44 2317 int value;
103a8fea 2318
95aebc44
JT
2319 va_start(args, fmt);
2320 vsnprintf(path, sizeof(path), fmt, args);
2321 va_end(args);
57a42a34 2322 filep = fopen_or_die(path, "r");
b2c95d90
JT
2323 if (fscanf(filep, "%d", &value) != 1)
2324 err(1, "%s: failed to parse number from file", path);
c98d5d94 2325 fclose(filep);
95aebc44
JT
2326 return value;
2327}
2328
2329/*
e275b388
DC
2330 * get_cpu_position_in_core(cpu)
2331 * return the position of the CPU among its HT siblings in the core
2332 * return -1 if the sibling is not in list
95aebc44 2333 */
e275b388 2334int get_cpu_position_in_core(int cpu)
95aebc44 2335{
e275b388
DC
2336 char path[64];
2337 FILE *filep;
2338 int this_cpu;
2339 char character;
2340 int i;
2341
2342 sprintf(path,
2343 "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list",
2344 cpu);
2345 filep = fopen(path, "r");
2346 if (filep == NULL) {
2347 perror(path);
2348 exit(1);
2349 }
2350
2351 for (i = 0; i < topo.num_threads_per_core; i++) {
2352 fscanf(filep, "%d", &this_cpu);
2353 if (this_cpu == cpu) {
2354 fclose(filep);
2355 return i;
2356 }
2357
2358 /* Account for no separator after last thread*/
2359 if (i != (topo.num_threads_per_core - 1))
2360 fscanf(filep, "%c", &character);
2361 }
2362
2363 fclose(filep);
2364 return -1;
103a8fea
LB
2365}
2366
c98d5d94
LB
2367/*
2368 * cpu_is_first_core_in_package(cpu)
2369 * return 1 if given CPU is 1st core in package
2370 */
2371int cpu_is_first_core_in_package(int cpu)
103a8fea 2372{
95aebc44 2373 return cpu == parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_siblings_list", cpu);
103a8fea
LB
2374}
2375
2376int get_physical_package_id(int cpu)
2377{
95aebc44 2378 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu);
103a8fea
LB
2379}
2380
2381int get_core_id(int cpu)
2382{
95aebc44 2383 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", cpu);
103a8fea
LB
2384}
2385
c98d5d94
LB
2386int get_num_ht_siblings(int cpu)
2387{
2388 char path[80];
2389 FILE *filep;
e275b388
DC
2390 int sib1;
2391 int matches = 0;
c98d5d94 2392 char character;
e275b388
DC
2393 char str[100];
2394 char *ch;
c98d5d94
LB
2395
2396 sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", cpu);
57a42a34 2397 filep = fopen_or_die(path, "r");
e275b388 2398
c98d5d94
LB
2399 /*
2400 * file format:
e275b388
DC
2401 * A ',' separated or '-' separated set of numbers
2402 * (eg 1-2 or 1,3,4,5)
c98d5d94 2403 */
e275b388
DC
2404 fscanf(filep, "%d%c\n", &sib1, &character);
2405 fseek(filep, 0, SEEK_SET);
2406 fgets(str, 100, filep);
2407 ch = strchr(str, character);
2408 while (ch != NULL) {
2409 matches++;
2410 ch = strchr(ch+1, character);
2411 }
c98d5d94
LB
2412
2413 fclose(filep);
e275b388 2414 return matches+1;
c98d5d94
LB
2415}
2416
103a8fea 2417/*
c98d5d94
LB
2418 * run func(thread, core, package) in topology order
2419 * skip non-present cpus
103a8fea
LB
2420 */
2421
c98d5d94
LB
2422int for_all_cpus_2(int (func)(struct thread_data *, struct core_data *,
2423 struct pkg_data *, struct thread_data *, struct core_data *,
2424 struct pkg_data *), struct thread_data *thread_base,
2425 struct core_data *core_base, struct pkg_data *pkg_base,
2426 struct thread_data *thread_base2, struct core_data *core_base2,
2427 struct pkg_data *pkg_base2)
2428{
2429 int retval, pkg_no, core_no, thread_no;
2430
2431 for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) {
2432 for (core_no = 0; core_no < topo.num_cores_per_pkg; ++core_no) {
2433 for (thread_no = 0; thread_no <
2434 topo.num_threads_per_core; ++thread_no) {
2435 struct thread_data *t, *t2;
2436 struct core_data *c, *c2;
2437 struct pkg_data *p, *p2;
2438
2439 t = GET_THREAD(thread_base, thread_no, core_no, pkg_no);
2440
2441 if (cpu_is_not_present(t->cpu_id))
2442 continue;
2443
2444 t2 = GET_THREAD(thread_base2, thread_no, core_no, pkg_no);
2445
2446 c = GET_CORE(core_base, core_no, pkg_no);
2447 c2 = GET_CORE(core_base2, core_no, pkg_no);
2448
2449 p = GET_PKG(pkg_base, pkg_no);
2450 p2 = GET_PKG(pkg_base2, pkg_no);
2451
2452 retval = func(t, c, p, t2, c2, p2);
2453 if (retval)
2454 return retval;
2455 }
2456 }
2457 }
2458 return 0;
2459}
2460
2461/*
2462 * run func(cpu) on every cpu in /proc/stat
2463 * return max_cpu number
2464 */
2465int for_all_proc_cpus(int (func)(int))
103a8fea
LB
2466{
2467 FILE *fp;
c98d5d94 2468 int cpu_num;
103a8fea
LB
2469 int retval;
2470
57a42a34 2471 fp = fopen_or_die(proc_stat, "r");
103a8fea
LB
2472
2473 retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n");
b2c95d90
JT
2474 if (retval != 0)
2475 err(1, "%s: failed to parse format", proc_stat);
103a8fea 2476
c98d5d94
LB
2477 while (1) {
2478 retval = fscanf(fp, "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n", &cpu_num);
103a8fea
LB
2479 if (retval != 1)
2480 break;
2481
c98d5d94
LB
2482 retval = func(cpu_num);
2483 if (retval) {
2484 fclose(fp);
2485 return(retval);
2486 }
103a8fea
LB
2487 }
2488 fclose(fp);
c98d5d94 2489 return 0;
103a8fea
LB
2490}
2491
2492void re_initialize(void)
2493{
c98d5d94
LB
2494 free_all_buffers();
2495 setup_all_buffers();
2496 printf("turbostat: re-initialized with num_cpus %d\n", topo.num_cpus);
103a8fea
LB
2497}
2498
c98d5d94 2499
103a8fea 2500/*
c98d5d94
LB
2501 * count_cpus()
2502 * remember the last one seen, it will be the max
103a8fea 2503 */
c98d5d94 2504int count_cpus(int cpu)
103a8fea 2505{
c98d5d94
LB
2506 if (topo.max_cpu_num < cpu)
2507 topo.max_cpu_num = cpu;
103a8fea 2508
c98d5d94
LB
2509 topo.num_cpus += 1;
2510 return 0;
2511}
2512int mark_cpu_present(int cpu)
2513{
2514 CPU_SET_S(cpu, cpu_present_setsize, cpu_present_set);
15aaa346 2515 return 0;
103a8fea
LB
2516}
2517
562a2d37
LB
2518/*
2519 * snapshot_proc_interrupts()
2520 *
2521 * read and record summary of /proc/interrupts
2522 *
2523 * return 1 if config change requires a restart, else return 0
2524 */
2525int snapshot_proc_interrupts(void)
2526{
2527 static FILE *fp;
2528 int column, retval;
2529
2530 if (fp == NULL)
2531 fp = fopen_or_die("/proc/interrupts", "r");
2532 else
2533 rewind(fp);
2534
2535 /* read 1st line of /proc/interrupts to get cpu* name for each column */
2536 for (column = 0; column < topo.num_cpus; ++column) {
2537 int cpu_number;
2538
2539 retval = fscanf(fp, " CPU%d", &cpu_number);
2540 if (retval != 1)
2541 break;
2542
2543 if (cpu_number > topo.max_cpu_num) {
2544 warn("/proc/interrupts: cpu%d: > %d", cpu_number, topo.max_cpu_num);
2545 return 1;
2546 }
2547
2548 irq_column_2_cpu[column] = cpu_number;
2549 irqs_per_cpu[cpu_number] = 0;
2550 }
2551
2552 /* read /proc/interrupt count lines and sum up irqs per cpu */
2553 while (1) {
2554 int column;
2555 char buf[64];
2556
2557 retval = fscanf(fp, " %s:", buf); /* flush irq# "N:" */
2558 if (retval != 1)
2559 break;
2560
2561 /* read the count per cpu */
2562 for (column = 0; column < topo.num_cpus; ++column) {
2563
2564 int cpu_number, irq_count;
2565
2566 retval = fscanf(fp, " %d", &irq_count);
2567 if (retval != 1)
2568 break;
2569
2570 cpu_number = irq_column_2_cpu[column];
2571 irqs_per_cpu[cpu_number] += irq_count;
2572
2573 }
2574
2575 while (getc(fp) != '\n')
2576 ; /* flush interrupt description */
2577
2578 }
2579 return 0;
2580}
fdf676e5
LB
2581/*
2582 * snapshot_gfx_rc6_ms()
2583 *
2584 * record snapshot of
2585 * /sys/class/drm/card0/power/rc6_residency_ms
2586 *
2587 * return 1 if config change requires a restart, else return 0
2588 */
2589int snapshot_gfx_rc6_ms(void)
2590{
2591 FILE *fp;
2592 int retval;
2593
2594 fp = fopen_or_die("/sys/class/drm/card0/power/rc6_residency_ms", "r");
2595
2596 retval = fscanf(fp, "%lld", &gfx_cur_rc6_ms);
2597 if (retval != 1)
2598 err(1, "GFX rc6");
2599
2600 fclose(fp);
2601
2602 return 0;
2603}
27d47356
LB
2604/*
2605 * snapshot_gfx_mhz()
2606 *
2607 * record snapshot of
2608 * /sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz
2609 *
2610 * return 1 if config change requires a restart, else return 0
2611 */
2612int snapshot_gfx_mhz(void)
2613{
2614 static FILE *fp;
2615 int retval;
2616
2617 if (fp == NULL)
2618 fp = fopen_or_die("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", "r");
22048c54 2619 else {
27d47356 2620 rewind(fp);
22048c54
LB
2621 fflush(fp);
2622 }
27d47356
LB
2623
2624 retval = fscanf(fp, "%d", &gfx_cur_mhz);
2625 if (retval != 1)
2626 err(1, "GFX MHz");
2627
2628 return 0;
2629}
562a2d37 2630
be0e54c4
LB
2631/*
2632 * snapshot_cpu_lpi()
2633 *
2634 * record snapshot of
2635 * /sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us
2636 *
2637 * return 1 if config change requires a restart, else return 0
2638 */
2639int snapshot_cpu_lpi_us(void)
2640{
2641 FILE *fp;
2642 int retval;
2643
2644 fp = fopen_or_die("/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us", "r");
2645
2646 retval = fscanf(fp, "%lld", &cpuidle_cur_cpu_lpi_us);
2647 if (retval != 1)
2648 err(1, "CPU LPI");
2649
2650 fclose(fp);
2651
2652 return 0;
2653}
2654/*
2655 * snapshot_sys_lpi()
2656 *
2657 * record snapshot of
2658 * /sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us
2659 *
2660 * return 1 if config change requires a restart, else return 0
2661 */
2662int snapshot_sys_lpi_us(void)
2663{
2664 FILE *fp;
2665 int retval;
2666
2667 fp = fopen_or_die("/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us", "r");
2668
2669 retval = fscanf(fp, "%lld", &cpuidle_cur_sys_lpi_us);
2670 if (retval != 1)
2671 err(1, "SYS LPI");
2672
2673 fclose(fp);
2674
2675 return 0;
2676}
562a2d37
LB
2677/*
2678 * snapshot /proc and /sys files
2679 *
2680 * return 1 if configuration restart needed, else return 0
2681 */
2682int snapshot_proc_sysfs_files(void)
2683{
218f0e8d
LB
2684 if (DO_BIC(BIC_IRQ))
2685 if (snapshot_proc_interrupts())
2686 return 1;
562a2d37 2687
812db3f7 2688 if (DO_BIC(BIC_GFX_rc6))
fdf676e5
LB
2689 snapshot_gfx_rc6_ms();
2690
812db3f7 2691 if (DO_BIC(BIC_GFXMHz))
27d47356
LB
2692 snapshot_gfx_mhz();
2693
be0e54c4
LB
2694 if (DO_BIC(BIC_CPU_LPI))
2695 snapshot_cpu_lpi_us();
2696
2697 if (DO_BIC(BIC_SYS_LPI))
2698 snapshot_sys_lpi_us();
2699
562a2d37
LB
2700 return 0;
2701}
2702
8aa2ed0b
LB
2703int exit_requested;
2704
2705static void signal_handler (int signal)
2706{
2707 switch (signal) {
2708 case SIGINT:
2709 exit_requested = 1;
2710 if (debug)
2711 fprintf(stderr, " SIGINT\n");
2712 break;
07211960
LB
2713 case SIGUSR1:
2714 if (debug > 1)
2715 fprintf(stderr, "SIGUSR1\n");
2716 break;
8aa2ed0b 2717 }
b9ad8ee0
LB
2718 /* make sure this manually-invoked interval is at least 1ms long */
2719 nanosleep(&one_msec, NULL);
8aa2ed0b
LB
2720}
2721
2722void setup_signal_handler(void)
2723{
2724 struct sigaction sa;
2725
2726 memset(&sa, 0, sizeof(sa));
2727
2728 sa.sa_handler = &signal_handler;
2729
2730 if (sigaction(SIGINT, &sa, NULL) < 0)
2731 err(1, "sigaction SIGINT");
07211960
LB
2732 if (sigaction(SIGUSR1, &sa, NULL) < 0)
2733 err(1, "sigaction SIGUSR1");
8aa2ed0b 2734}
b9ad8ee0 2735
47936f94 2736void do_sleep(void)
b9ad8ee0
LB
2737{
2738 struct timeval select_timeout;
2739 fd_set readfds;
2740 int retval;
2741
2742 FD_ZERO(&readfds);
2743 FD_SET(0, &readfds);
2744
47936f94
AB
2745 if (!isatty(fileno(stdin))) {
2746 nanosleep(&interval_ts, NULL);
2747 return;
2748 }
b9ad8ee0 2749
47936f94 2750 select_timeout = interval_tv;
b9ad8ee0
LB
2751 retval = select(1, &readfds, NULL, NULL, &select_timeout);
2752
2753 if (retval == 1) {
b9ad8ee0
LB
2754 switch (getc(stdin)) {
2755 case 'q':
2756 exit_requested = 1;
2757 break;
2758 }
2759 /* make sure this manually-invoked interval is at least 1ms long */
2760 nanosleep(&one_msec, NULL);
2761 }
b9ad8ee0 2762}
47936f94 2763
103a8fea
LB
2764void turbostat_loop()
2765{
c98d5d94 2766 int retval;
e52966c0 2767 int restarted = 0;
023fe0ac 2768 int done_iters = 0;
c98d5d94 2769
8aa2ed0b
LB
2770 setup_signal_handler();
2771
103a8fea 2772restart:
e52966c0
LB
2773 restarted++;
2774
562a2d37 2775 snapshot_proc_sysfs_files();
c98d5d94 2776 retval = for_all_cpus(get_counters, EVEN_COUNTERS);
d91bb17c
LB
2777 if (retval < -1) {
2778 exit(retval);
2779 } else if (retval == -1) {
e52966c0
LB
2780 if (restarted > 1) {
2781 exit(retval);
2782 }
c98d5d94
LB
2783 re_initialize();
2784 goto restart;
2785 }
e52966c0 2786 restarted = 0;
023fe0ac 2787 done_iters = 0;
103a8fea
LB
2788 gettimeofday(&tv_even, (struct timezone *)NULL);
2789
2790 while (1) {
c98d5d94 2791 if (for_all_proc_cpus(cpu_is_not_present)) {
103a8fea
LB
2792 re_initialize();
2793 goto restart;
2794 }
b9ad8ee0 2795 do_sleep();
562a2d37
LB
2796 if (snapshot_proc_sysfs_files())
2797 goto restart;
c98d5d94 2798 retval = for_all_cpus(get_counters, ODD_COUNTERS);
d91bb17c
LB
2799 if (retval < -1) {
2800 exit(retval);
2801 } else if (retval == -1) {
15aaa346
LB
2802 re_initialize();
2803 goto restart;
2804 }
103a8fea 2805 gettimeofday(&tv_odd, (struct timezone *)NULL);
103a8fea 2806 timersub(&tv_odd, &tv_even, &tv_delta);
ba3dec99
LB
2807 if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS)) {
2808 re_initialize();
2809 goto restart;
2810 }
c98d5d94
LB
2811 compute_average(EVEN_COUNTERS);
2812 format_all_counters(EVEN_COUNTERS);
b7d8c148 2813 flush_output_stdout();
8aa2ed0b
LB
2814 if (exit_requested)
2815 break;
023fe0ac
CY
2816 if (num_iterations && ++done_iters >= num_iterations)
2817 break;
b9ad8ee0 2818 do_sleep();
562a2d37
LB
2819 if (snapshot_proc_sysfs_files())
2820 goto restart;
c98d5d94 2821 retval = for_all_cpus(get_counters, EVEN_COUNTERS);
d91bb17c
LB
2822 if (retval < -1) {
2823 exit(retval);
2824 } else if (retval == -1) {
103a8fea
LB
2825 re_initialize();
2826 goto restart;
2827 }
103a8fea 2828 gettimeofday(&tv_even, (struct timezone *)NULL);
103a8fea 2829 timersub(&tv_even, &tv_odd, &tv_delta);
ba3dec99
LB
2830 if (for_all_cpus_2(delta_cpu, EVEN_COUNTERS, ODD_COUNTERS)) {
2831 re_initialize();
2832 goto restart;
2833 }
c98d5d94
LB
2834 compute_average(ODD_COUNTERS);
2835 format_all_counters(ODD_COUNTERS);
b7d8c148 2836 flush_output_stdout();
8aa2ed0b
LB
2837 if (exit_requested)
2838 break;
023fe0ac
CY
2839 if (num_iterations && ++done_iters >= num_iterations)
2840 break;
103a8fea
LB
2841 }
2842}
2843
2844void check_dev_msr()
2845{
2846 struct stat sb;
7ce7d5de 2847 char pathname[32];
103a8fea 2848
7ce7d5de
PB
2849 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
2850 if (stat(pathname, &sb))
a21d38c8
LB
2851 if (system("/sbin/modprobe msr > /dev/null 2>&1"))
2852 err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" ");
103a8fea
LB
2853}
2854
98481e79 2855void check_permissions()
103a8fea 2856{
98481e79
LB
2857 struct __user_cap_header_struct cap_header_data;
2858 cap_user_header_t cap_header = &cap_header_data;
2859 struct __user_cap_data_struct cap_data_data;
2860 cap_user_data_t cap_data = &cap_data_data;
2861 extern int capget(cap_user_header_t hdrp, cap_user_data_t datap);
2862 int do_exit = 0;
7ce7d5de 2863 char pathname[32];
98481e79
LB
2864
2865 /* check for CAP_SYS_RAWIO */
2866 cap_header->pid = getpid();
2867 cap_header->version = _LINUX_CAPABILITY_VERSION;
2868 if (capget(cap_header, cap_data) < 0)
2869 err(-6, "capget(2) failed");
2870
2871 if ((cap_data->effective & (1 << CAP_SYS_RAWIO)) == 0) {
2872 do_exit++;
2873 warnx("capget(CAP_SYS_RAWIO) failed,"
2874 " try \"# setcap cap_sys_rawio=ep %s\"", progname);
2875 }
2876
2877 /* test file permissions */
7ce7d5de
PB
2878 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
2879 if (euidaccess(pathname, R_OK)) {
98481e79
LB
2880 do_exit++;
2881 warn("/dev/cpu/0/msr open failed, try chown or chmod +r /dev/cpu/*/msr");
2882 }
2883
2884 /* if all else fails, thell them to be root */
2885 if (do_exit)
2886 if (getuid() != 0)
d7899447 2887 warnx("... or simply run as root");
98481e79
LB
2888
2889 if (do_exit)
2890 exit(-6);
103a8fea
LB
2891}
2892
d7899447
LB
2893/*
2894 * NHM adds support for additional MSRs:
2895 *
2896 * MSR_SMI_COUNT 0x00000034
2897 *
ec0adc53 2898 * MSR_PLATFORM_INFO 0x000000ce
1df2e55a 2899 * MSR_PKG_CST_CONFIG_CONTROL 0x000000e2
d7899447 2900 *
cf4cbe53
LB
2901 * MSR_MISC_PWR_MGMT 0x000001aa
2902 *
d7899447
LB
2903 * MSR_PKG_C3_RESIDENCY 0x000003f8
2904 * MSR_PKG_C6_RESIDENCY 0x000003f9
2905 * MSR_CORE_C3_RESIDENCY 0x000003fc
2906 * MSR_CORE_C6_RESIDENCY 0x000003fd
2907 *
ee7e38e3 2908 * Side effect:
1df2e55a 2909 * sets global pkg_cstate_limit to decode MSR_PKG_CST_CONFIG_CONTROL
33148d67 2910 * sets has_misc_feature_control
d7899447 2911 */
ee7e38e3 2912int probe_nhm_msrs(unsigned int family, unsigned int model)
103a8fea 2913{
ee7e38e3 2914 unsigned long long msr;
21ed5574 2915 unsigned int base_ratio;
ee7e38e3
LB
2916 int *pkg_cstate_limits;
2917
103a8fea
LB
2918 if (!genuine_intel)
2919 return 0;
2920
2921 if (family != 6)
2922 return 0;
2923
21ed5574
LB
2924 bclk = discover_bclk(family, model);
2925
103a8fea 2926 switch (model) {
869ce69e
LB
2927 case INTEL_FAM6_NEHALEM_EP: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */
2928 case INTEL_FAM6_NEHALEM: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */
103a8fea 2929 case 0x1F: /* Core i7 and i5 Processor - Nehalem */
869ce69e
LB
2930 case INTEL_FAM6_WESTMERE: /* Westmere Client - Clarkdale, Arrandale */
2931 case INTEL_FAM6_WESTMERE_EP: /* Westmere EP - Gulftown */
2932 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */
2933 case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */
ee7e38e3
LB
2934 pkg_cstate_limits = nhm_pkg_cstate_limits;
2935 break;
869ce69e
LB
2936 case INTEL_FAM6_SANDYBRIDGE: /* SNB */
2937 case INTEL_FAM6_SANDYBRIDGE_X: /* SNB Xeon */
2938 case INTEL_FAM6_IVYBRIDGE: /* IVB */
2939 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
ee7e38e3 2940 pkg_cstate_limits = snb_pkg_cstate_limits;
33148d67 2941 has_misc_feature_control = 1;
ee7e38e3 2942 break;
869ce69e
LB
2943 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2944 case INTEL_FAM6_HASWELL_X: /* HSX */
2945 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2946 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
2947 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2948 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
2949 case INTEL_FAM6_BROADWELL_X: /* BDX */
2950 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2951 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2952 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2953 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2954 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
997e5395 2955 case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */
ee7e38e3 2956 pkg_cstate_limits = hsw_pkg_cstate_limits;
33148d67 2957 has_misc_feature_control = 1;
ee7e38e3 2958 break;
d8ebb442
LB
2959 case INTEL_FAM6_SKYLAKE_X: /* SKX */
2960 pkg_cstate_limits = skx_pkg_cstate_limits;
33148d67 2961 has_misc_feature_control = 1;
d8ebb442 2962 break;
869ce69e 2963 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
cf4cbe53 2964 no_MSR_MISC_PWR_MGMT = 1;
869ce69e 2965 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
ee7e38e3
LB
2966 pkg_cstate_limits = slv_pkg_cstate_limits;
2967 break;
869ce69e 2968 case INTEL_FAM6_ATOM_AIRMONT: /* AMT */
ee7e38e3 2969 pkg_cstate_limits = amt_pkg_cstate_limits;
cf4cbe53 2970 no_MSR_MISC_PWR_MGMT = 1;
ee7e38e3 2971 break;
869ce69e 2972 case INTEL_FAM6_XEON_PHI_KNL: /* PHI */
005c82d6 2973 case INTEL_FAM6_XEON_PHI_KNM:
ee7e38e3
LB
2974 pkg_cstate_limits = phi_pkg_cstate_limits;
2975 break;
869ce69e 2976 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
ac01ac13 2977 case INTEL_FAM6_ATOM_GEMINI_LAKE:
869ce69e 2978 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
e4085d54
LB
2979 pkg_cstate_limits = bxt_pkg_cstate_limits;
2980 break;
103a8fea
LB
2981 default:
2982 return 0;
2983 }
1df2e55a 2984 get_msr(base_cpu, MSR_PKG_CST_CONFIG_CONTROL, &msr);
e9257f5f 2985 pkg_cstate_limit = pkg_cstate_limits[msr & 0xF];
ee7e38e3 2986
ec0adc53 2987 get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
21ed5574
LB
2988 base_ratio = (msr >> 8) & 0xFF;
2989
2990 base_hz = base_ratio * bclk * 1000000;
2991 has_base_hz = 1;
ee7e38e3 2992 return 1;
103a8fea 2993}
0f7887c4 2994/*
495c7654 2995 * SLV client has support for unique MSRs:
0f7887c4
LB
2996 *
2997 * MSR_CC6_DEMOTION_POLICY_CONFIG
2998 * MSR_MC6_DEMOTION_POLICY_CONFIG
2999 */
3000
3001int has_slv_msrs(unsigned int family, unsigned int model)
3002{
3003 if (!genuine_intel)
3004 return 0;
3005
3006 switch (model) {
3007 case INTEL_FAM6_ATOM_SILVERMONT1:
3008 case INTEL_FAM6_ATOM_MERRIFIELD:
3009 case INTEL_FAM6_ATOM_MOOREFIELD:
3010 return 1;
3011 }
3012 return 0;
3013}
7170a374
LB
3014int is_dnv(unsigned int family, unsigned int model)
3015{
3016
3017 if (!genuine_intel)
3018 return 0;
3019
3020 switch (model) {
3021 case INTEL_FAM6_ATOM_DENVERTON:
3022 return 1;
3023 }
3024 return 0;
3025}
ade0ebac
LB
3026int is_bdx(unsigned int family, unsigned int model)
3027{
3028
3029 if (!genuine_intel)
3030 return 0;
3031
3032 switch (model) {
3033 case INTEL_FAM6_BROADWELL_X:
3034 case INTEL_FAM6_BROADWELL_XEON_D:
3035 return 1;
3036 }
3037 return 0;
3038}
34c76197
LB
3039int is_skx(unsigned int family, unsigned int model)
3040{
3041
3042 if (!genuine_intel)
3043 return 0;
3044
3045 switch (model) {
3046 case INTEL_FAM6_SKYLAKE_X:
3047 return 1;
3048 }
3049 return 0;
3050}
0f7887c4 3051
31e07522 3052int has_turbo_ratio_limit(unsigned int family, unsigned int model)
d7899447 3053{
0f7887c4
LB
3054 if (has_slv_msrs(family, model))
3055 return 0;
3056
d7899447
LB
3057 switch (model) {
3058 /* Nehalem compatible, but do not include turbo-ratio limit support */
869ce69e
LB
3059 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */
3060 case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */
3061 case INTEL_FAM6_XEON_PHI_KNL: /* PHI - Knights Landing (different MSR definition) */
005c82d6 3062 case INTEL_FAM6_XEON_PHI_KNM:
d7899447
LB
3063 return 0;
3064 default:
3065 return 1;
3066 }
3067}
0f7887c4
LB
3068int has_atom_turbo_ratio_limit(unsigned int family, unsigned int model)
3069{
3070 if (has_slv_msrs(family, model))
3071 return 1;
3072
3073 return 0;
3074}
6574a5d5
LB
3075int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model)
3076{
3077 if (!genuine_intel)
3078 return 0;
3079
3080 if (family != 6)
3081 return 0;
3082
3083 switch (model) {
869ce69e
LB
3084 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
3085 case INTEL_FAM6_HASWELL_X: /* HSW Xeon */
fcd17211
LB
3086 return 1;
3087 default:
3088 return 0;
3089 }
3090}
3091int has_hsw_turbo_ratio_limit(unsigned int family, unsigned int model)
3092{
3093 if (!genuine_intel)
3094 return 0;
3095
3096 if (family != 6)
3097 return 0;
3098
3099 switch (model) {
869ce69e 3100 case INTEL_FAM6_HASWELL_X: /* HSW Xeon */
6574a5d5
LB
3101 return 1;
3102 default:
3103 return 0;
3104 }
3105}
3106
fb5d4327
DC
3107int has_knl_turbo_ratio_limit(unsigned int family, unsigned int model)
3108{
3109 if (!genuine_intel)
3110 return 0;
3111
3112 if (family != 6)
3113 return 0;
3114
3115 switch (model) {
869ce69e 3116 case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */
005c82d6 3117 case INTEL_FAM6_XEON_PHI_KNM:
fb5d4327
DC
3118 return 1;
3119 default:
3120 return 0;
3121 }
3122}
31e07522
LB
3123int has_glm_turbo_ratio_limit(unsigned int family, unsigned int model)
3124{
3125 if (!genuine_intel)
3126 return 0;
3127
3128 if (family != 6)
3129 return 0;
3130
3131 switch (model) {
3132 case INTEL_FAM6_ATOM_GOLDMONT:
3133 case INTEL_FAM6_SKYLAKE_X:
3134 return 1;
3135 default:
3136 return 0;
3137 }
3138}
6fb3143b
LB
3139int has_config_tdp(unsigned int family, unsigned int model)
3140{
3141 if (!genuine_intel)
3142 return 0;
3143
3144 if (family != 6)
3145 return 0;
3146
3147 switch (model) {
869ce69e
LB
3148 case INTEL_FAM6_IVYBRIDGE: /* IVB */
3149 case INTEL_FAM6_HASWELL_CORE: /* HSW */
3150 case INTEL_FAM6_HASWELL_X: /* HSX */
3151 case INTEL_FAM6_HASWELL_ULT: /* HSW */
3152 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
3153 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
3154 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
3155 case INTEL_FAM6_BROADWELL_X: /* BDX */
3156 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
3157 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
3158 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
3159 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3160 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
997e5395 3161 case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */
869ce69e
LB
3162 case INTEL_FAM6_SKYLAKE_X: /* SKX */
3163
3164 case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */
005c82d6 3165 case INTEL_FAM6_XEON_PHI_KNM:
6fb3143b
LB
3166 return 1;
3167 default:
3168 return 0;
3169 }
3170}
3171
fcd17211 3172static void
1b69317d 3173dump_cstate_pstate_config_info(unsigned int family, unsigned int model)
fcd17211
LB
3174{
3175 if (!do_nhm_platform_info)
3176 return;
3177
3178 dump_nhm_platform_info();
3179
3180 if (has_hsw_turbo_ratio_limit(family, model))
3181 dump_hsw_turbo_ratio_limits();
3182
3183 if (has_ivt_turbo_ratio_limit(family, model))
3184 dump_ivt_turbo_ratio_limits();
3185
31e07522
LB
3186 if (has_turbo_ratio_limit(family, model))
3187 dump_turbo_ratio_limits(family, model);
fcd17211 3188
0f7887c4
LB
3189 if (has_atom_turbo_ratio_limit(family, model))
3190 dump_atom_turbo_ratio_limits();
3191
fb5d4327
DC
3192 if (has_knl_turbo_ratio_limit(family, model))
3193 dump_knl_turbo_ratio_limits();
3194
6fb3143b
LB
3195 if (has_config_tdp(family, model))
3196 dump_config_tdp();
3197
fcd17211
LB
3198 dump_nhm_cst_cfg();
3199}
3200
41618e63
LB
3201static void
3202dump_sysfs_cstate_config(void)
3203{
3204 char path[64];
3205 char name_buf[16];
3206 char desc[64];
3207 FILE *input;
3208 int state;
3209 char *sp;
3210
3211 if (!DO_BIC(BIC_sysfs))
3212 return;
3213
3214 for (state = 0; state < 10; ++state) {
3215
3216 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
3217 base_cpu, state);
3218 input = fopen(path, "r");
3219 if (input == NULL)
3220 continue;
3221 fgets(name_buf, sizeof(name_buf), input);
3222
3223 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
3224 sp = strchr(name_buf, '-');
3225 if (!sp)
3226 sp = strchrnul(name_buf, '\n');
3227 *sp = '\0';
3228
3229 fclose(input);
3230
3231 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/desc",
3232 base_cpu, state);
3233 input = fopen(path, "r");
3234 if (input == NULL)
3235 continue;
3236 fgets(desc, sizeof(desc), input);
3237
3238 fprintf(outf, "cpu%d: %s: %s", base_cpu, name_buf, desc);
3239 fclose(input);
3240 }
3241}
7293fccd
LB
3242static void
3243dump_sysfs_pstate_config(void)
3244{
3245 char path[64];
3246 char driver_buf[64];
3247 char governor_buf[64];
3248 FILE *input;
3249 int turbo;
3250
3251 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_driver",
3252 base_cpu);
3253 input = fopen(path, "r");
3254 if (input == NULL) {
3255 fprintf(stderr, "NSFOD %s\n", path);
3256 return;
3257 }
3258 fgets(driver_buf, sizeof(driver_buf), input);
3259 fclose(input);
3260
3261 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor",
3262 base_cpu);
3263 input = fopen(path, "r");
3264 if (input == NULL) {
3265 fprintf(stderr, "NSFOD %s\n", path);
3266 return;
3267 }
3268 fgets(governor_buf, sizeof(governor_buf), input);
3269 fclose(input);
3270
3271 fprintf(outf, "cpu%d: cpufreq driver: %s", base_cpu, driver_buf);
3272 fprintf(outf, "cpu%d: cpufreq governor: %s", base_cpu, governor_buf);
3273
3274 sprintf(path, "/sys/devices/system/cpu/cpufreq/boost");
3275 input = fopen(path, "r");
3276 if (input != NULL) {
3277 fscanf(input, "%d", &turbo);
3278 fprintf(outf, "cpufreq boost: %d\n", turbo);
3279 fclose(input);
3280 }
3281
3282 sprintf(path, "/sys/devices/system/cpu/intel_pstate/no_turbo");
3283 input = fopen(path, "r");
3284 if (input != NULL) {
3285 fscanf(input, "%d", &turbo);
3286 fprintf(outf, "cpufreq intel_pstate no_turbo: %d\n", turbo);
3287 fclose(input);
3288 }
3289}
41618e63 3290
fcd17211 3291
889facbe
LB
3292/*
3293 * print_epb()
3294 * Decode the ENERGY_PERF_BIAS MSR
3295 */
3296int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p)
3297{
3298 unsigned long long msr;
3299 char *epb_string;
3300 int cpu;
3301
3302 if (!has_epb)
3303 return 0;
3304
3305 cpu = t->cpu_id;
3306
3307 /* EPB is per-package */
3308 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
3309 return 0;
3310
3311 if (cpu_migrate(cpu)) {
b7d8c148 3312 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
889facbe
LB
3313 return -1;
3314 }
3315
3316 if (get_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &msr))
3317 return 0;
3318
e9be7dd6 3319 switch (msr & 0xF) {
889facbe
LB
3320 case ENERGY_PERF_BIAS_PERFORMANCE:
3321 epb_string = "performance";
3322 break;
3323 case ENERGY_PERF_BIAS_NORMAL:
3324 epb_string = "balanced";
3325 break;
3326 case ENERGY_PERF_BIAS_POWERSAVE:
3327 epb_string = "powersave";
3328 break;
3329 default:
3330 epb_string = "custom";
3331 break;
3332 }
b7d8c148 3333 fprintf(outf, "cpu%d: MSR_IA32_ENERGY_PERF_BIAS: 0x%08llx (%s)\n", cpu, msr, epb_string);
889facbe
LB
3334
3335 return 0;
3336}
7f5c258e
LB
3337/*
3338 * print_hwp()
3339 * Decode the MSR_HWP_CAPABILITIES
3340 */
3341int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p)
3342{
3343 unsigned long long msr;
3344 int cpu;
3345
3346 if (!has_hwp)
3347 return 0;
3348
3349 cpu = t->cpu_id;
3350
3351 /* MSR_HWP_CAPABILITIES is per-package */
3352 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
3353 return 0;
3354
3355 if (cpu_migrate(cpu)) {
b7d8c148 3356 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
7f5c258e
LB
3357 return -1;
3358 }
3359
3360 if (get_msr(cpu, MSR_PM_ENABLE, &msr))
3361 return 0;
3362
b7d8c148 3363 fprintf(outf, "cpu%d: MSR_PM_ENABLE: 0x%08llx (%sHWP)\n",
7f5c258e
LB
3364 cpu, msr, (msr & (1 << 0)) ? "" : "No-");
3365
3366 /* MSR_PM_ENABLE[1] == 1 if HWP is enabled and MSRs visible */
3367 if ((msr & (1 << 0)) == 0)
3368 return 0;
3369
3370 if (get_msr(cpu, MSR_HWP_CAPABILITIES, &msr))
3371 return 0;
3372
b7d8c148 3373 fprintf(outf, "cpu%d: MSR_HWP_CAPABILITIES: 0x%08llx "
6dbd25a2 3374 "(high %d guar %d eff %d low %d)\n",
7f5c258e
LB
3375 cpu, msr,
3376 (unsigned int)HWP_HIGHEST_PERF(msr),
3377 (unsigned int)HWP_GUARANTEED_PERF(msr),
3378 (unsigned int)HWP_MOSTEFFICIENT_PERF(msr),
3379 (unsigned int)HWP_LOWEST_PERF(msr));
3380
3381 if (get_msr(cpu, MSR_HWP_REQUEST, &msr))
3382 return 0;
3383
b7d8c148 3384 fprintf(outf, "cpu%d: MSR_HWP_REQUEST: 0x%08llx "
6dbd25a2 3385 "(min %d max %d des %d epp 0x%x window 0x%x pkg 0x%x)\n",
7f5c258e
LB
3386 cpu, msr,
3387 (unsigned int)(((msr) >> 0) & 0xff),
3388 (unsigned int)(((msr) >> 8) & 0xff),
3389 (unsigned int)(((msr) >> 16) & 0xff),
3390 (unsigned int)(((msr) >> 24) & 0xff),
3391 (unsigned int)(((msr) >> 32) & 0xff3),
3392 (unsigned int)(((msr) >> 42) & 0x1));
3393
3394 if (has_hwp_pkg) {
3395 if (get_msr(cpu, MSR_HWP_REQUEST_PKG, &msr))
3396 return 0;
3397
b7d8c148 3398 fprintf(outf, "cpu%d: MSR_HWP_REQUEST_PKG: 0x%08llx "
6dbd25a2 3399 "(min %d max %d des %d epp 0x%x window 0x%x)\n",
7f5c258e
LB
3400 cpu, msr,
3401 (unsigned int)(((msr) >> 0) & 0xff),
3402 (unsigned int)(((msr) >> 8) & 0xff),
3403 (unsigned int)(((msr) >> 16) & 0xff),
3404 (unsigned int)(((msr) >> 24) & 0xff),
3405 (unsigned int)(((msr) >> 32) & 0xff3));
3406 }
3407 if (has_hwp_notify) {
3408 if (get_msr(cpu, MSR_HWP_INTERRUPT, &msr))
3409 return 0;
3410
b7d8c148 3411 fprintf(outf, "cpu%d: MSR_HWP_INTERRUPT: 0x%08llx "
7f5c258e
LB
3412 "(%s_Guaranteed_Perf_Change, %s_Excursion_Min)\n",
3413 cpu, msr,
3414 ((msr) & 0x1) ? "EN" : "Dis",
3415 ((msr) & 0x2) ? "EN" : "Dis");
3416 }
3417 if (get_msr(cpu, MSR_HWP_STATUS, &msr))
3418 return 0;
3419
b7d8c148 3420 fprintf(outf, "cpu%d: MSR_HWP_STATUS: 0x%08llx "
7f5c258e
LB
3421 "(%sGuaranteed_Perf_Change, %sExcursion_Min)\n",
3422 cpu, msr,
3423 ((msr) & 0x1) ? "" : "No-",
3424 ((msr) & 0x2) ? "" : "No-");
889facbe
LB
3425
3426 return 0;
3427}
3428
3a9a941d
LB
3429/*
3430 * print_perf_limit()
3431 */
3432int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data *p)
3433{
3434 unsigned long long msr;
3435 int cpu;
3436
3437 cpu = t->cpu_id;
3438
3439 /* per-package */
3440 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
3441 return 0;
3442
3443 if (cpu_migrate(cpu)) {
b7d8c148 3444 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
3a9a941d
LB
3445 return -1;
3446 }
3447
3448 if (do_core_perf_limit_reasons) {
3449 get_msr(cpu, MSR_CORE_PERF_LIMIT_REASONS, &msr);
b7d8c148
LB
3450 fprintf(outf, "cpu%d: MSR_CORE_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
3451 fprintf(outf, " (Active: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)",
e33cbe85 3452 (msr & 1 << 15) ? "bit15, " : "",
3a9a941d 3453 (msr & 1 << 14) ? "bit14, " : "",
e33cbe85
LB
3454 (msr & 1 << 13) ? "Transitions, " : "",
3455 (msr & 1 << 12) ? "MultiCoreTurbo, " : "",
3456 (msr & 1 << 11) ? "PkgPwrL2, " : "",
3457 (msr & 1 << 10) ? "PkgPwrL1, " : "",
3458 (msr & 1 << 9) ? "CorePwr, " : "",
3459 (msr & 1 << 8) ? "Amps, " : "",
3460 (msr & 1 << 6) ? "VR-Therm, " : "",
3461 (msr & 1 << 5) ? "Auto-HWP, " : "",
3462 (msr & 1 << 4) ? "Graphics, " : "",
3463 (msr & 1 << 2) ? "bit2, " : "",
3464 (msr & 1 << 1) ? "ThermStatus, " : "",
3465 (msr & 1 << 0) ? "PROCHOT, " : "");
b7d8c148 3466 fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n",
e33cbe85 3467 (msr & 1 << 31) ? "bit31, " : "",
3a9a941d 3468 (msr & 1 << 30) ? "bit30, " : "",
e33cbe85
LB
3469 (msr & 1 << 29) ? "Transitions, " : "",
3470 (msr & 1 << 28) ? "MultiCoreTurbo, " : "",
3471 (msr & 1 << 27) ? "PkgPwrL2, " : "",
3472 (msr & 1 << 26) ? "PkgPwrL1, " : "",
3473 (msr & 1 << 25) ? "CorePwr, " : "",
3474 (msr & 1 << 24) ? "Amps, " : "",
3475 (msr & 1 << 22) ? "VR-Therm, " : "",
3476 (msr & 1 << 21) ? "Auto-HWP, " : "",
3477 (msr & 1 << 20) ? "Graphics, " : "",
3478 (msr & 1 << 18) ? "bit18, " : "",
3479 (msr & 1 << 17) ? "ThermStatus, " : "",
3480 (msr & 1 << 16) ? "PROCHOT, " : "");
3a9a941d
LB
3481
3482 }
3483 if (do_gfx_perf_limit_reasons) {
3484 get_msr(cpu, MSR_GFX_PERF_LIMIT_REASONS, &msr);
b7d8c148
LB
3485 fprintf(outf, "cpu%d: MSR_GFX_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
3486 fprintf(outf, " (Active: %s%s%s%s%s%s%s%s)",
3a9a941d
LB
3487 (msr & 1 << 0) ? "PROCHOT, " : "",
3488 (msr & 1 << 1) ? "ThermStatus, " : "",
3489 (msr & 1 << 4) ? "Graphics, " : "",
3490 (msr & 1 << 6) ? "VR-Therm, " : "",
3491 (msr & 1 << 8) ? "Amps, " : "",
3492 (msr & 1 << 9) ? "GFXPwr, " : "",
3493 (msr & 1 << 10) ? "PkgPwrL1, " : "",
3494 (msr & 1 << 11) ? "PkgPwrL2, " : "");
b7d8c148 3495 fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s)\n",
3a9a941d
LB
3496 (msr & 1 << 16) ? "PROCHOT, " : "",
3497 (msr & 1 << 17) ? "ThermStatus, " : "",
3498 (msr & 1 << 20) ? "Graphics, " : "",
3499 (msr & 1 << 22) ? "VR-Therm, " : "",
3500 (msr & 1 << 24) ? "Amps, " : "",
3501 (msr & 1 << 25) ? "GFXPwr, " : "",
3502 (msr & 1 << 26) ? "PkgPwrL1, " : "",
3503 (msr & 1 << 27) ? "PkgPwrL2, " : "");
3504 }
3505 if (do_ring_perf_limit_reasons) {
3506 get_msr(cpu, MSR_RING_PERF_LIMIT_REASONS, &msr);
b7d8c148
LB
3507 fprintf(outf, "cpu%d: MSR_RING_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
3508 fprintf(outf, " (Active: %s%s%s%s%s%s)",
3a9a941d
LB
3509 (msr & 1 << 0) ? "PROCHOT, " : "",
3510 (msr & 1 << 1) ? "ThermStatus, " : "",
3511 (msr & 1 << 6) ? "VR-Therm, " : "",
3512 (msr & 1 << 8) ? "Amps, " : "",
3513 (msr & 1 << 10) ? "PkgPwrL1, " : "",
3514 (msr & 1 << 11) ? "PkgPwrL2, " : "");
b7d8c148 3515 fprintf(outf, " (Logged: %s%s%s%s%s%s)\n",
3a9a941d
LB
3516 (msr & 1 << 16) ? "PROCHOT, " : "",
3517 (msr & 1 << 17) ? "ThermStatus, " : "",
3518 (msr & 1 << 22) ? "VR-Therm, " : "",
3519 (msr & 1 << 24) ? "Amps, " : "",
3520 (msr & 1 << 26) ? "PkgPwrL1, " : "",
3521 (msr & 1 << 27) ? "PkgPwrL2, " : "");
3522 }
3523 return 0;
3524}
3525
889facbe
LB
3526#define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */
3527#define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */
3528
1b69317d 3529double get_tdp(unsigned int model)
144b44b1
LB
3530{
3531 unsigned long long msr;
3532
3533 if (do_rapl & RAPL_PKG_POWER_INFO)
7ce7d5de 3534 if (!get_msr(base_cpu, MSR_PKG_POWER_INFO, &msr))
144b44b1
LB
3535 return ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units;
3536
3537 switch (model) {
869ce69e
LB
3538 case INTEL_FAM6_ATOM_SILVERMONT1:
3539 case INTEL_FAM6_ATOM_SILVERMONT2:
144b44b1
LB
3540 return 30.0;
3541 default:
3542 return 135.0;
3543 }
3544}
3545
40ee8e3b
AS
3546/*
3547 * rapl_dram_energy_units_probe()
3548 * Energy units are either hard-coded, or come from RAPL Energy Unit MSR.
3549 */
3550static double
3551rapl_dram_energy_units_probe(int model, double rapl_energy_units)
3552{
3553 /* only called for genuine_intel, family 6 */
3554
3555 switch (model) {
869ce69e
LB
3556 case INTEL_FAM6_HASWELL_X: /* HSX */
3557 case INTEL_FAM6_BROADWELL_X: /* BDX */
3558 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
3559 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
005c82d6 3560 case INTEL_FAM6_XEON_PHI_KNM:
40ee8e3b
AS
3561 return (rapl_dram_energy_units = 15.3 / 1000000);
3562 default:
3563 return (rapl_energy_units);
3564 }
3565}
3566
144b44b1 3567
889facbe
LB
3568/*
3569 * rapl_probe()
3570 *
144b44b1 3571 * sets do_rapl, rapl_power_units, rapl_energy_units, rapl_time_units
889facbe
LB
3572 */
3573void rapl_probe(unsigned int family, unsigned int model)
3574{
3575 unsigned long long msr;
144b44b1 3576 unsigned int time_unit;
889facbe
LB
3577 double tdp;
3578
3579 if (!genuine_intel)
3580 return;
3581
3582 if (family != 6)
3583 return;
3584
3585 switch (model) {
869ce69e
LB
3586 case INTEL_FAM6_SANDYBRIDGE:
3587 case INTEL_FAM6_IVYBRIDGE:
3588 case INTEL_FAM6_HASWELL_CORE: /* HSW */
3589 case INTEL_FAM6_HASWELL_ULT: /* HSW */
3590 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
3591 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
3592 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
144b44b1 3593 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO;
812db3f7
LB
3594 if (rapl_joules) {
3595 BIC_PRESENT(BIC_Pkg_J);
3596 BIC_PRESENT(BIC_Cor_J);
3597 BIC_PRESENT(BIC_GFX_J);
3598 } else {
3599 BIC_PRESENT(BIC_PkgWatt);
3600 BIC_PRESENT(BIC_CorWatt);
3601 BIC_PRESENT(BIC_GFXWatt);
3602 }
889facbe 3603 break;
869ce69e 3604 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
ac01ac13 3605 case INTEL_FAM6_ATOM_GEMINI_LAKE:
e4085d54 3606 do_rapl = RAPL_PKG | RAPL_PKG_POWER_INFO;
812db3f7
LB
3607 if (rapl_joules)
3608 BIC_PRESENT(BIC_Pkg_J);
3609 else
3610 BIC_PRESENT(BIC_PkgWatt);
e4085d54 3611 break;
869ce69e
LB
3612 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
3613 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
3614 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3615 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
997e5395 3616 case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */
81824921 3617 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_GFX | RAPL_PKG_POWER_INFO;
812db3f7
LB
3618 BIC_PRESENT(BIC_PKG__);
3619 BIC_PRESENT(BIC_RAM__);
3620 if (rapl_joules) {
3621 BIC_PRESENT(BIC_Pkg_J);
3622 BIC_PRESENT(BIC_Cor_J);
3623 BIC_PRESENT(BIC_RAM_J);
81824921 3624 BIC_PRESENT(BIC_GFX_J);
812db3f7
LB
3625 } else {
3626 BIC_PRESENT(BIC_PkgWatt);
3627 BIC_PRESENT(BIC_CorWatt);
3628 BIC_PRESENT(BIC_RAMWatt);
81824921 3629 BIC_PRESENT(BIC_GFXWatt);
812db3f7 3630 }
0b2bb692 3631 break;
869ce69e
LB
3632 case INTEL_FAM6_HASWELL_X: /* HSX */
3633 case INTEL_FAM6_BROADWELL_X: /* BDX */
3634 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
3635 case INTEL_FAM6_SKYLAKE_X: /* SKX */
3636 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
005c82d6 3637 case INTEL_FAM6_XEON_PHI_KNM:
0b2bb692 3638 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
812db3f7
LB
3639 BIC_PRESENT(BIC_PKG__);
3640 BIC_PRESENT(BIC_RAM__);
3641 if (rapl_joules) {
3642 BIC_PRESENT(BIC_Pkg_J);
3643 BIC_PRESENT(BIC_RAM_J);
3644 } else {
3645 BIC_PRESENT(BIC_PkgWatt);
3646 BIC_PRESENT(BIC_RAMWatt);
3647 }
e6f9bb3c 3648 break;
869ce69e
LB
3649 case INTEL_FAM6_SANDYBRIDGE_X:
3650 case INTEL_FAM6_IVYBRIDGE_X:
0b2bb692 3651 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;
812db3f7
LB
3652 BIC_PRESENT(BIC_PKG__);
3653 BIC_PRESENT(BIC_RAM__);
3654 if (rapl_joules) {
3655 BIC_PRESENT(BIC_Pkg_J);
3656 BIC_PRESENT(BIC_Cor_J);
3657 BIC_PRESENT(BIC_RAM_J);
3658 } else {
3659 BIC_PRESENT(BIC_PkgWatt);
3660 BIC_PRESENT(BIC_CorWatt);
3661 BIC_PRESENT(BIC_RAMWatt);
3662 }
144b44b1 3663 break;
869ce69e
LB
3664 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
3665 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
9148494c 3666 do_rapl = RAPL_PKG | RAPL_CORES;
812db3f7
LB
3667 if (rapl_joules) {
3668 BIC_PRESENT(BIC_Pkg_J);
3669 BIC_PRESENT(BIC_Cor_J);
3670 } else {
3671 BIC_PRESENT(BIC_PkgWatt);
3672 BIC_PRESENT(BIC_CorWatt);
3673 }
889facbe 3674 break;
869ce69e 3675 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
0f644909 3676 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;
812db3f7
LB
3677 BIC_PRESENT(BIC_PKG__);
3678 BIC_PRESENT(BIC_RAM__);
3679 if (rapl_joules) {
3680 BIC_PRESENT(BIC_Pkg_J);
3681 BIC_PRESENT(BIC_Cor_J);
3682 BIC_PRESENT(BIC_RAM_J);
3683 } else {
3684 BIC_PRESENT(BIC_PkgWatt);
3685 BIC_PRESENT(BIC_CorWatt);
3686 BIC_PRESENT(BIC_RAMWatt);
3687 }
0f644909 3688 break;
889facbe
LB
3689 default:
3690 return;
3691 }
3692
3693 /* units on package 0, verify later other packages match */
7ce7d5de 3694 if (get_msr(base_cpu, MSR_RAPL_POWER_UNIT, &msr))
889facbe
LB
3695 return;
3696
3697 rapl_power_units = 1.0 / (1 << (msr & 0xF));
869ce69e 3698 if (model == INTEL_FAM6_ATOM_SILVERMONT1)
144b44b1
LB
3699 rapl_energy_units = 1.0 * (1 << (msr >> 8 & 0x1F)) / 1000000;
3700 else
3701 rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F));
889facbe 3702
40ee8e3b
AS
3703 rapl_dram_energy_units = rapl_dram_energy_units_probe(model, rapl_energy_units);
3704
144b44b1
LB
3705 time_unit = msr >> 16 & 0xF;
3706 if (time_unit == 0)
3707 time_unit = 0xA;
889facbe 3708
144b44b1 3709 rapl_time_units = 1.0 / (1 << (time_unit));
889facbe 3710
144b44b1 3711 tdp = get_tdp(model);
889facbe 3712
144b44b1 3713 rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
96e47158 3714 if (!quiet)
b7d8c148 3715 fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
889facbe
LB
3716
3717 return;
3718}
3719
1b69317d 3720void perf_limit_reasons_probe(unsigned int family, unsigned int model)
3a9a941d
LB
3721{
3722 if (!genuine_intel)
3723 return;
3724
3725 if (family != 6)
3726 return;
3727
3728 switch (model) {
869ce69e
LB
3729 case INTEL_FAM6_HASWELL_CORE: /* HSW */
3730 case INTEL_FAM6_HASWELL_ULT: /* HSW */
3731 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
3a9a941d 3732 do_gfx_perf_limit_reasons = 1;
869ce69e 3733 case INTEL_FAM6_HASWELL_X: /* HSX */
3a9a941d
LB
3734 do_core_perf_limit_reasons = 1;
3735 do_ring_perf_limit_reasons = 1;
3736 default:
3737 return;
3738 }
3739}
3740
ac980e13
AB
3741void automatic_cstate_conversion_probe(unsigned int family, unsigned int model)
3742{
3743 if (is_skx(family, model) || is_bdx(family, model))
3744 has_automatic_cstate_conversion = 1;
3745}
3746
889facbe
LB
3747int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p)
3748{
3749 unsigned long long msr;
f4896fa5 3750 unsigned int dts, dts2;
889facbe
LB
3751 int cpu;
3752
3753 if (!(do_dts || do_ptm))
3754 return 0;
3755
3756 cpu = t->cpu_id;
3757
3758 /* DTS is per-core, no need to print for each thread */
388e9c81 3759 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
889facbe
LB
3760 return 0;
3761
3762 if (cpu_migrate(cpu)) {
b7d8c148 3763 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
889facbe
LB
3764 return -1;
3765 }
3766
3767 if (do_ptm && (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) {
3768 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
3769 return 0;
3770
3771 dts = (msr >> 16) & 0x7F;
b7d8c148 3772 fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_STATUS: 0x%08llx (%d C)\n",
889facbe
LB
3773 cpu, msr, tcc_activation_temp - dts);
3774
889facbe
LB
3775 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, &msr))
3776 return 0;
3777
3778 dts = (msr >> 16) & 0x7F;
3779 dts2 = (msr >> 8) & 0x7F;
b7d8c148 3780 fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
889facbe 3781 cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
889facbe
LB
3782 }
3783
3784
f4896fa5 3785 if (do_dts && debug) {
889facbe
LB
3786 unsigned int resolution;
3787
3788 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
3789 return 0;
3790
3791 dts = (msr >> 16) & 0x7F;
3792 resolution = (msr >> 27) & 0xF;
b7d8c148 3793 fprintf(outf, "cpu%d: MSR_IA32_THERM_STATUS: 0x%08llx (%d C +/- %d)\n",
889facbe
LB
3794 cpu, msr, tcc_activation_temp - dts, resolution);
3795
889facbe
LB
3796 if (get_msr(cpu, MSR_IA32_THERM_INTERRUPT, &msr))
3797 return 0;
3798
3799 dts = (msr >> 16) & 0x7F;
3800 dts2 = (msr >> 8) & 0x7F;
b7d8c148 3801 fprintf(outf, "cpu%d: MSR_IA32_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
889facbe 3802 cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
889facbe
LB
3803 }
3804
3805 return 0;
3806}
36229897 3807
889facbe
LB
3808void print_power_limit_msr(int cpu, unsigned long long msr, char *label)
3809{
b7d8c148 3810 fprintf(outf, "cpu%d: %s: %sabled (%f Watts, %f sec, clamp %sabled)\n",
889facbe
LB
3811 cpu, label,
3812 ((msr >> 15) & 1) ? "EN" : "DIS",
3813 ((msr >> 0) & 0x7FFF) * rapl_power_units,
3814 (1.0 + (((msr >> 22) & 0x3)/4.0)) * (1 << ((msr >> 17) & 0x1F)) * rapl_time_units,
3815 (((msr >> 16) & 1) ? "EN" : "DIS"));
3816
3817 return;
3818}
3819
3820int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
3821{
3822 unsigned long long msr;
3823 int cpu;
889facbe
LB
3824
3825 if (!do_rapl)
3826 return 0;
3827
3828 /* RAPL counters are per package, so print only for 1st thread/package */
3829 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
3830 return 0;
3831
3832 cpu = t->cpu_id;
3833 if (cpu_migrate(cpu)) {
b7d8c148 3834 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
889facbe
LB
3835 return -1;
3836 }
3837
3838 if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr))
3839 return -1;
3840
96e47158
LB
3841 fprintf(outf, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx (%f Watts, %f Joules, %f sec.)\n", cpu, msr,
3842 rapl_power_units, rapl_energy_units, rapl_time_units);
3843
144b44b1
LB
3844 if (do_rapl & RAPL_PKG_POWER_INFO) {
3845
889facbe
LB
3846 if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr))
3847 return -5;
3848
3849
b7d8c148 3850 fprintf(outf, "cpu%d: MSR_PKG_POWER_INFO: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
889facbe
LB
3851 cpu, msr,
3852 ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
3853 ((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
3854 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units,
3855 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
3856
144b44b1
LB
3857 }
3858 if (do_rapl & RAPL_PKG) {
3859
889facbe
LB
3860 if (get_msr(cpu, MSR_PKG_POWER_LIMIT, &msr))
3861 return -9;
3862
b7d8c148 3863 fprintf(outf, "cpu%d: MSR_PKG_POWER_LIMIT: 0x%08llx (%slocked)\n",
96e47158 3864 cpu, msr, (msr >> 63) & 1 ? "" : "UN");
889facbe
LB
3865
3866 print_power_limit_msr(cpu, msr, "PKG Limit #1");
b7d8c148 3867 fprintf(outf, "cpu%d: PKG Limit #2: %sabled (%f Watts, %f* sec, clamp %sabled)\n",
889facbe
LB
3868 cpu,
3869 ((msr >> 47) & 1) ? "EN" : "DIS",
3870 ((msr >> 32) & 0x7FFF) * rapl_power_units,
3871 (1.0 + (((msr >> 54) & 0x3)/4.0)) * (1 << ((msr >> 49) & 0x1F)) * rapl_time_units,
3872 ((msr >> 48) & 1) ? "EN" : "DIS");
3873 }
3874
0b2bb692 3875 if (do_rapl & RAPL_DRAM_POWER_INFO) {
889facbe
LB
3876 if (get_msr(cpu, MSR_DRAM_POWER_INFO, &msr))
3877 return -6;
3878
b7d8c148 3879 fprintf(outf, "cpu%d: MSR_DRAM_POWER_INFO,: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
889facbe
LB
3880 cpu, msr,
3881 ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
3882 ((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
3883 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units,
3884 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
0b2bb692
LB
3885 }
3886 if (do_rapl & RAPL_DRAM) {
889facbe
LB
3887 if (get_msr(cpu, MSR_DRAM_POWER_LIMIT, &msr))
3888 return -9;
b7d8c148 3889 fprintf(outf, "cpu%d: MSR_DRAM_POWER_LIMIT: 0x%08llx (%slocked)\n",
96e47158 3890 cpu, msr, (msr >> 31) & 1 ? "" : "UN");
889facbe
LB
3891
3892 print_power_limit_msr(cpu, msr, "DRAM Limit");
3893 }
144b44b1 3894 if (do_rapl & RAPL_CORE_POLICY) {
96e47158
LB
3895 if (get_msr(cpu, MSR_PP0_POLICY, &msr))
3896 return -7;
889facbe 3897
96e47158 3898 fprintf(outf, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF);
144b44b1 3899 }
9148494c 3900 if (do_rapl & RAPL_CORES_POWER_LIMIT) {
96e47158
LB
3901 if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr))
3902 return -9;
3903 fprintf(outf, "cpu%d: MSR_PP0_POWER_LIMIT: 0x%08llx (%slocked)\n",
3904 cpu, msr, (msr >> 31) & 1 ? "" : "UN");
3905 print_power_limit_msr(cpu, msr, "Cores Limit");
889facbe
LB
3906 }
3907 if (do_rapl & RAPL_GFX) {
96e47158
LB
3908 if (get_msr(cpu, MSR_PP1_POLICY, &msr))
3909 return -8;
889facbe 3910
96e47158 3911 fprintf(outf, "cpu%d: MSR_PP1_POLICY: %lld\n", cpu, msr & 0xF);
889facbe 3912
96e47158
LB
3913 if (get_msr(cpu, MSR_PP1_POWER_LIMIT, &msr))
3914 return -9;
3915 fprintf(outf, "cpu%d: MSR_PP1_POWER_LIMIT: 0x%08llx (%slocked)\n",
3916 cpu, msr, (msr >> 31) & 1 ? "" : "UN");
3917 print_power_limit_msr(cpu, msr, "GFX Limit");
889facbe
LB
3918 }
3919 return 0;
3920}
3921
d7899447
LB
3922/*
3923 * SNB adds support for additional MSRs:
3924 *
3925 * MSR_PKG_C7_RESIDENCY 0x000003fa
3926 * MSR_CORE_C7_RESIDENCY 0x000003fe
3927 * MSR_PKG_C2_RESIDENCY 0x0000060d
3928 */
103a8fea 3929
d7899447 3930int has_snb_msrs(unsigned int family, unsigned int model)
103a8fea
LB
3931{
3932 if (!genuine_intel)
3933 return 0;
3934
3935 switch (model) {
869ce69e
LB
3936 case INTEL_FAM6_SANDYBRIDGE:
3937 case INTEL_FAM6_SANDYBRIDGE_X:
3938 case INTEL_FAM6_IVYBRIDGE: /* IVB */
3939 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
3940 case INTEL_FAM6_HASWELL_CORE: /* HSW */
3941 case INTEL_FAM6_HASWELL_X: /* HSW */
3942 case INTEL_FAM6_HASWELL_ULT: /* HSW */
3943 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
3944 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
3945 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
3946 case INTEL_FAM6_BROADWELL_X: /* BDX */
3947 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
3948 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
3949 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
3950 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3951 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
997e5395 3952 case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */
869ce69e
LB
3953 case INTEL_FAM6_SKYLAKE_X: /* SKX */
3954 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
ac01ac13 3955 case INTEL_FAM6_ATOM_GEMINI_LAKE:
5bbac26e 3956 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
103a8fea
LB
3957 return 1;
3958 }
3959 return 0;
3960}
3961
d7899447
LB
3962/*
3963 * HSW adds support for additional MSRs:
3964 *
5a63426e
LB
3965 * MSR_PKG_C8_RESIDENCY 0x00000630
3966 * MSR_PKG_C9_RESIDENCY 0x00000631
3967 * MSR_PKG_C10_RESIDENCY 0x00000632
3968 *
3969 * MSR_PKGC8_IRTL 0x00000633
3970 * MSR_PKGC9_IRTL 0x00000634
3971 * MSR_PKGC10_IRTL 0x00000635
3972 *
d7899447
LB
3973 */
3974int has_hsw_msrs(unsigned int family, unsigned int model)
ca58710f
KCA
3975{
3976 if (!genuine_intel)
3977 return 0;
3978
3979 switch (model) {
869ce69e
LB
3980 case INTEL_FAM6_HASWELL_ULT: /* HSW */
3981 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
3982 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
3983 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
3984 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3985 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
997e5395 3986 case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */
869ce69e 3987 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
ac01ac13 3988 case INTEL_FAM6_ATOM_GEMINI_LAKE:
0b2bb692
LB
3989 return 1;
3990 }
3991 return 0;
3992}
3993
3994/*
3995 * SKL adds support for additional MSRS:
3996 *
3997 * MSR_PKG_WEIGHTED_CORE_C0_RES 0x00000658
3998 * MSR_PKG_ANY_CORE_C0_RES 0x00000659
3999 * MSR_PKG_ANY_GFXE_C0_RES 0x0000065A
4000 * MSR_PKG_BOTH_CORE_GFXE_C0_RES 0x0000065B
4001 */
4002int has_skl_msrs(unsigned int family, unsigned int model)
4003{
4004 if (!genuine_intel)
4005 return 0;
4006
4007 switch (model) {
869ce69e
LB
4008 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
4009 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
4010 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
4011 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
997e5395 4012 case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */
ca58710f
KCA
4013 return 1;
4014 }
4015 return 0;
4016}
4017
144b44b1
LB
4018int is_slm(unsigned int family, unsigned int model)
4019{
4020 if (!genuine_intel)
4021 return 0;
4022 switch (model) {
869ce69e
LB
4023 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
4024 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
144b44b1
LB
4025 return 1;
4026 }
4027 return 0;
4028}
4029
fb5d4327
DC
4030int is_knl(unsigned int family, unsigned int model)
4031{
4032 if (!genuine_intel)
4033 return 0;
4034 switch (model) {
869ce69e 4035 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
005c82d6 4036 case INTEL_FAM6_XEON_PHI_KNM:
fb5d4327
DC
4037 return 1;
4038 }
4039 return 0;
4040}
4041
997e5395
SP
4042int is_cnl(unsigned int family, unsigned int model)
4043{
4044 if (!genuine_intel)
4045 return 0;
4046
4047 switch (model) {
4048 case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */
4049 return 1;
4050 }
4051
4052 return 0;
4053}
4054
b2b34dfe
HC
4055unsigned int get_aperf_mperf_multiplier(unsigned int family, unsigned int model)
4056{
4057 if (is_knl(family, model))
4058 return 1024;
4059 return 1;
4060}
4061
144b44b1
LB
4062#define SLM_BCLK_FREQS 5
4063double slm_freq_table[SLM_BCLK_FREQS] = { 83.3, 100.0, 133.3, 116.7, 80.0};
4064
4065double slm_bclk(void)
4066{
4067 unsigned long long msr = 3;
4068 unsigned int i;
4069 double freq;
4070
7ce7d5de 4071 if (get_msr(base_cpu, MSR_FSB_FREQ, &msr))
b7d8c148 4072 fprintf(outf, "SLM BCLK: unknown\n");
144b44b1
LB
4073
4074 i = msr & 0xf;
4075 if (i >= SLM_BCLK_FREQS) {
b7d8c148 4076 fprintf(outf, "SLM BCLK[%d] invalid\n", i);
0a91e551 4077 i = 3;
144b44b1
LB
4078 }
4079 freq = slm_freq_table[i];
4080
96e47158 4081 if (!quiet)
8f6196c1 4082 fprintf(outf, "SLM BCLK: %.1f Mhz\n", freq);
144b44b1
LB
4083
4084 return freq;
4085}
4086
103a8fea
LB
4087double discover_bclk(unsigned int family, unsigned int model)
4088{
121b48bb 4089 if (has_snb_msrs(family, model) || is_knl(family, model))
103a8fea 4090 return 100.00;
144b44b1
LB
4091 else if (is_slm(family, model))
4092 return slm_bclk();
103a8fea
LB
4093 else
4094 return 133.33;
4095}
4096
889facbe
LB
4097/*
4098 * MSR_IA32_TEMPERATURE_TARGET indicates the temperature where
4099 * the Thermal Control Circuit (TCC) activates.
4100 * This is usually equal to tjMax.
4101 *
4102 * Older processors do not have this MSR, so there we guess,
4103 * but also allow cmdline over-ride with -T.
4104 *
4105 * Several MSR temperature values are in units of degrees-C
4106 * below this value, including the Digital Thermal Sensor (DTS),
4107 * Package Thermal Management Sensor (PTM), and thermal event thresholds.
4108 */
4109int set_temperature_target(struct thread_data *t, struct core_data *c, struct pkg_data *p)
4110{
4111 unsigned long long msr;
4112 unsigned int target_c_local;
4113 int cpu;
4114
4115 /* tcc_activation_temp is used only for dts or ptm */
4116 if (!(do_dts || do_ptm))
4117 return 0;
4118
4119 /* this is a per-package concept */
4120 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
4121 return 0;
4122
4123 cpu = t->cpu_id;
4124 if (cpu_migrate(cpu)) {
b7d8c148 4125 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
889facbe
LB
4126 return -1;
4127 }
4128
4129 if (tcc_activation_temp_override != 0) {
4130 tcc_activation_temp = tcc_activation_temp_override;
b7d8c148 4131 fprintf(outf, "cpu%d: Using cmdline TCC Target (%d C)\n",
889facbe
LB
4132 cpu, tcc_activation_temp);
4133 return 0;
4134 }
4135
4136 /* Temperature Target MSR is Nehalem and newer only */
d7899447 4137 if (!do_nhm_platform_info)
889facbe
LB
4138 goto guess;
4139
7ce7d5de 4140 if (get_msr(base_cpu, MSR_IA32_TEMPERATURE_TARGET, &msr))
889facbe
LB
4141 goto guess;
4142
3482124a 4143 target_c_local = (msr >> 16) & 0xFF;
889facbe 4144
96e47158 4145 if (!quiet)
b7d8c148 4146 fprintf(outf, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
889facbe
LB
4147 cpu, msr, target_c_local);
4148
3482124a 4149 if (!target_c_local)
889facbe
LB
4150 goto guess;
4151
4152 tcc_activation_temp = target_c_local;
4153
4154 return 0;
4155
4156guess:
4157 tcc_activation_temp = TJMAX_DEFAULT;
b7d8c148 4158 fprintf(outf, "cpu%d: Guessing tjMax %d C, Please use -T to specify\n",
889facbe
LB
4159 cpu, tcc_activation_temp);
4160
4161 return 0;
4162}
69807a63 4163
aa8d8cc7
LB
4164void decode_feature_control_msr(void)
4165{
4166 unsigned long long msr;
4167
4168 if (!get_msr(base_cpu, MSR_IA32_FEATURE_CONTROL, &msr))
4169 fprintf(outf, "cpu%d: MSR_IA32_FEATURE_CONTROL: 0x%08llx (%sLocked %s)\n",
4170 base_cpu, msr,
4171 msr & FEATURE_CONTROL_LOCKED ? "" : "UN-",
4172 msr & (1 << 18) ? "SGX" : "");
4173}
4174
69807a63
LB
4175void decode_misc_enable_msr(void)
4176{
4177 unsigned long long msr;
4178
f26b1519
LB
4179 if (!genuine_intel)
4180 return;
4181
69807a63 4182 if (!get_msr(base_cpu, MSR_IA32_MISC_ENABLE, &msr))
e6512624 4183 fprintf(outf, "cpu%d: MSR_IA32_MISC_ENABLE: 0x%08llx (%sTCC %sEIST %sMWAIT %sPREFETCH %sTURBO)\n",
69807a63 4184 base_cpu, msr,
e6512624
LB
4185 msr & MSR_IA32_MISC_ENABLE_TM1 ? "" : "No-",
4186 msr & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP ? "" : "No-",
fd3933ca 4187 msr & MSR_IA32_MISC_ENABLE_MWAIT ? "" : "No-",
e6512624
LB
4188 msr & MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE ? "No-" : "",
4189 msr & MSR_IA32_MISC_ENABLE_TURBO_DISABLE ? "No-" : "");
69807a63
LB
4190}
4191
33148d67
LB
4192void decode_misc_feature_control(void)
4193{
4194 unsigned long long msr;
4195
4196 if (!has_misc_feature_control)
4197 return;
4198
4199 if (!get_msr(base_cpu, MSR_MISC_FEATURE_CONTROL, &msr))
4200 fprintf(outf, "cpu%d: MSR_MISC_FEATURE_CONTROL: 0x%08llx (%sL2-Prefetch %sL2-Prefetch-pair %sL1-Prefetch %sL1-IP-Prefetch)\n",
4201 base_cpu, msr,
4202 msr & (0 << 0) ? "No-" : "",
4203 msr & (1 << 0) ? "No-" : "",
4204 msr & (2 << 0) ? "No-" : "",
4205 msr & (3 << 0) ? "No-" : "");
4206}
f0057310
LB
4207/*
4208 * Decode MSR_MISC_PWR_MGMT
4209 *
4210 * Decode the bits according to the Nehalem documentation
4211 * bit[0] seems to continue to have same meaning going forward
4212 * bit[1] less so...
4213 */
4214void decode_misc_pwr_mgmt_msr(void)
4215{
4216 unsigned long long msr;
4217
4218 if (!do_nhm_platform_info)
4219 return;
4220
cf4cbe53
LB
4221 if (no_MSR_MISC_PWR_MGMT)
4222 return;
4223
f0057310 4224 if (!get_msr(base_cpu, MSR_MISC_PWR_MGMT, &msr))
ddadb8ad 4225 fprintf(outf, "cpu%d: MSR_MISC_PWR_MGMT: 0x%08llx (%sable-EIST_Coordination %sable-EPB %sable-OOB)\n",
f0057310
LB
4226 base_cpu, msr,
4227 msr & (1 << 0) ? "DIS" : "EN",
ddadb8ad
SP
4228 msr & (1 << 1) ? "EN" : "DIS",
4229 msr & (1 << 8) ? "EN" : "DIS");
f0057310 4230}
71616c8e
LB
4231/*
4232 * Decode MSR_CC6_DEMOTION_POLICY_CONFIG, MSR_MC6_DEMOTION_POLICY_CONFIG
4233 *
4234 * This MSRs are present on Silvermont processors,
4235 * Intel Atom processor E3000 series (Baytrail), and friends.
4236 */
4237void decode_c6_demotion_policy_msr(void)
4238{
4239 unsigned long long msr;
4240
4241 if (!get_msr(base_cpu, MSR_CC6_DEMOTION_POLICY_CONFIG, &msr))
4242 fprintf(outf, "cpu%d: MSR_CC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-CC6-Demotion)\n",
4243 base_cpu, msr, msr & (1 << 0) ? "EN" : "DIS");
4244
4245 if (!get_msr(base_cpu, MSR_MC6_DEMOTION_POLICY_CONFIG, &msr))
4246 fprintf(outf, "cpu%d: MSR_MC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-MC6-Demotion)\n",
4247 base_cpu, msr, msr & (1 << 0) ? "EN" : "DIS");
4248}
7f5c258e 4249
fcd17211 4250void process_cpuid()
103a8fea 4251{
61a87ba7 4252 unsigned int eax, ebx, ecx, edx, max_level, max_extended_level;
103a8fea 4253 unsigned int fms, family, model, stepping;
b3a34e93 4254 unsigned int has_turbo;
103a8fea
LB
4255
4256 eax = ebx = ecx = edx = 0;
4257
5aea2f7f 4258 __cpuid(0, max_level, ebx, ecx, edx);
103a8fea
LB
4259
4260 if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)
4261 genuine_intel = 1;
4262
96e47158 4263 if (!quiet)
b7d8c148 4264 fprintf(outf, "CPUID(0): %.4s%.4s%.4s ",
103a8fea
LB
4265 (char *)&ebx, (char *)&edx, (char *)&ecx);
4266
5aea2f7f 4267 __cpuid(1, fms, ebx, ecx, edx);
103a8fea
LB
4268 family = (fms >> 8) & 0xf;
4269 model = (fms >> 4) & 0xf;
4270 stepping = fms & 0xf;
4271 if (family == 6 || family == 0xf)
4272 model += ((fms >> 16) & 0xf) << 4;
4273
96e47158 4274 if (!quiet) {
b7d8c148 4275 fprintf(outf, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
103a8fea 4276 max_level, family, model, stepping, family, model, stepping);
aa8d8cc7 4277 fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s\n",
69807a63
LB
4278 ecx & (1 << 0) ? "SSE3" : "-",
4279 ecx & (1 << 3) ? "MONITOR" : "-",
aa8d8cc7 4280 ecx & (1 << 6) ? "SMX" : "-",
69807a63
LB
4281 ecx & (1 << 7) ? "EIST" : "-",
4282 ecx & (1 << 8) ? "TM2" : "-",
4283 edx & (1 << 4) ? "TSC" : "-",
4284 edx & (1 << 5) ? "MSR" : "-",
4285 edx & (1 << 22) ? "ACPI-TM" : "-",
4286 edx & (1 << 29) ? "TM" : "-");
4287 }
103a8fea 4288
b2c95d90
JT
4289 if (!(edx & (1 << 5)))
4290 errx(1, "CPUID: no MSR");
103a8fea
LB
4291
4292 /*
4293 * check max extended function levels of CPUID.
4294 * This is needed to check for invariant TSC.
4295 * This check is valid for both Intel and AMD.
4296 */
4297 ebx = ecx = edx = 0;
5aea2f7f 4298 __cpuid(0x80000000, max_extended_level, ebx, ecx, edx);
103a8fea 4299
61a87ba7 4300 if (max_extended_level >= 0x80000007) {
103a8fea 4301
d7899447
LB
4302 /*
4303 * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8
4304 * this check is valid for both Intel and AMD
4305 */
5aea2f7f 4306 __cpuid(0x80000007, eax, ebx, ecx, edx);
d7899447
LB
4307 has_invariant_tsc = edx & (1 << 8);
4308 }
103a8fea
LB
4309
4310 /*
4311 * APERF/MPERF is advertised by CPUID.EAX=0x6: ECX.bit0
4312 * this check is valid for both Intel and AMD
4313 */
4314
5aea2f7f 4315 __cpuid(0x6, eax, ebx, ecx, edx);
8209e054 4316 has_aperf = ecx & (1 << 0);
812db3f7
LB
4317 if (has_aperf) {
4318 BIC_PRESENT(BIC_Avg_MHz);
4319 BIC_PRESENT(BIC_Busy);
4320 BIC_PRESENT(BIC_Bzy_MHz);
4321 }
889facbe 4322 do_dts = eax & (1 << 0);
812db3f7
LB
4323 if (do_dts)
4324 BIC_PRESENT(BIC_CoreTmp);
b3a34e93 4325 has_turbo = eax & (1 << 1);
889facbe 4326 do_ptm = eax & (1 << 6);
812db3f7
LB
4327 if (do_ptm)
4328 BIC_PRESENT(BIC_PkgTmp);
7f5c258e
LB
4329 has_hwp = eax & (1 << 7);
4330 has_hwp_notify = eax & (1 << 8);
4331 has_hwp_activity_window = eax & (1 << 9);
4332 has_hwp_epp = eax & (1 << 10);
4333 has_hwp_pkg = eax & (1 << 11);
889facbe
LB
4334 has_epb = ecx & (1 << 3);
4335
96e47158 4336 if (!quiet)
b3a34e93 4337 fprintf(outf, "CPUID(6): %sAPERF, %sTURBO, %sDTS, %sPTM, %sHWP, "
7f5c258e
LB
4338 "%sHWPnotify, %sHWPwindow, %sHWPepp, %sHWPpkg, %sEPB\n",
4339 has_aperf ? "" : "No-",
b3a34e93 4340 has_turbo ? "" : "No-",
7f5c258e
LB
4341 do_dts ? "" : "No-",
4342 do_ptm ? "" : "No-",
4343 has_hwp ? "" : "No-",
4344 has_hwp_notify ? "" : "No-",
4345 has_hwp_activity_window ? "" : "No-",
4346 has_hwp_epp ? "" : "No-",
4347 has_hwp_pkg ? "" : "No-",
4348 has_epb ? "" : "No-");
103a8fea 4349
96e47158 4350 if (!quiet)
69807a63
LB
4351 decode_misc_enable_msr();
4352
33148d67 4353
96e47158 4354 if (max_level >= 0x7 && !quiet) {
aa8d8cc7 4355 int has_sgx;
103a8fea 4356
aa8d8cc7
LB
4357 ecx = 0;
4358
4359 __cpuid_count(0x7, 0, eax, ebx, ecx, edx);
4360
4361 has_sgx = ebx & (1 << 2);
4362 fprintf(outf, "CPUID(7): %sSGX\n", has_sgx ? "" : "No-");
4363
4364 if (has_sgx)
4365 decode_feature_control_msr();
4366 }
4367
61a87ba7 4368 if (max_level >= 0x15) {
8a5bdf41
LB
4369 unsigned int eax_crystal;
4370 unsigned int ebx_tsc;
4371
4372 /*
4373 * CPUID 15H TSC/Crystal ratio, possibly Crystal Hz
4374 */
4375 eax_crystal = ebx_tsc = crystal_hz = edx = 0;
5aea2f7f 4376 __cpuid(0x15, eax_crystal, ebx_tsc, crystal_hz, edx);
8a5bdf41
LB
4377
4378 if (ebx_tsc != 0) {
4379
96e47158 4380 if (!quiet && (ebx != 0))
b7d8c148 4381 fprintf(outf, "CPUID(0x15): eax_crystal: %d ebx_tsc: %d ecx_crystal_hz: %d\n",
8a5bdf41
LB
4382 eax_crystal, ebx_tsc, crystal_hz);
4383
4384 if (crystal_hz == 0)
4385 switch(model) {
869ce69e
LB
4386 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
4387 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
4388 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
4389 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
e8efbc80
LB
4390 crystal_hz = 24000000; /* 24.0 MHz */
4391 break;
7268d407 4392 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
ec53e594
LB
4393 crystal_hz = 25000000; /* 25.0 MHz */
4394 break;
869ce69e 4395 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
ac01ac13 4396 case INTEL_FAM6_ATOM_GEMINI_LAKE:
e8efbc80 4397 crystal_hz = 19200000; /* 19.2 MHz */
8a5bdf41
LB
4398 break;
4399 default:
4400 crystal_hz = 0;
4401 }
4402
4403 if (crystal_hz) {
4404 tsc_hz = (unsigned long long) crystal_hz * ebx_tsc / eax_crystal;
96e47158 4405 if (!quiet)
b7d8c148 4406 fprintf(outf, "TSC: %lld MHz (%d Hz * %d / %d / 1000000)\n",
8a5bdf41
LB
4407 tsc_hz / 1000000, crystal_hz, ebx_tsc, eax_crystal);
4408 }
4409 }
4410 }
61a87ba7
LB
4411 if (max_level >= 0x16) {
4412 unsigned int base_mhz, max_mhz, bus_mhz, edx;
4413
4414 /*
4415 * CPUID 16H Base MHz, Max MHz, Bus MHz
4416 */
4417 base_mhz = max_mhz = bus_mhz = edx = 0;
4418
5aea2f7f 4419 __cpuid(0x16, base_mhz, max_mhz, bus_mhz, edx);
96e47158 4420 if (!quiet)
b7d8c148 4421 fprintf(outf, "CPUID(0x16): base_mhz: %d max_mhz: %d bus_mhz: %d\n",
61a87ba7
LB
4422 base_mhz, max_mhz, bus_mhz);
4423 }
8a5bdf41 4424
b2b34dfe
HC
4425 if (has_aperf)
4426 aperf_mperf_multiplier = get_aperf_mperf_multiplier(family, model);
4427
812db3f7
LB
4428 BIC_PRESENT(BIC_IRQ);
4429 BIC_PRESENT(BIC_TSC_MHz);
4430
4431 if (probe_nhm_msrs(family, model)) {
4432 do_nhm_platform_info = 1;
4433 BIC_PRESENT(BIC_CPU_c1);
4434 BIC_PRESENT(BIC_CPU_c3);
4435 BIC_PRESENT(BIC_CPU_c6);
4436 BIC_PRESENT(BIC_SMI);
4437 }
d7899447 4438 do_snb_cstates = has_snb_msrs(family, model);
812db3f7
LB
4439
4440 if (do_snb_cstates)
4441 BIC_PRESENT(BIC_CPU_c7);
4442
5a63426e 4443 do_irtl_snb = has_snb_msrs(family, model);
0f47c08d
LB
4444 if (do_snb_cstates && (pkg_cstate_limit >= PCL__2))
4445 BIC_PRESENT(BIC_Pkgpc2);
4446 if (pkg_cstate_limit >= PCL__3)
4447 BIC_PRESENT(BIC_Pkgpc3);
4448 if (pkg_cstate_limit >= PCL__6)
4449 BIC_PRESENT(BIC_Pkgpc6);
4450 if (do_snb_cstates && (pkg_cstate_limit >= PCL__7))
4451 BIC_PRESENT(BIC_Pkgpc7);
0539ba11 4452 if (has_slv_msrs(family, model)) {
0f47c08d
LB
4453 BIC_NOT_PRESENT(BIC_Pkgpc2);
4454 BIC_NOT_PRESENT(BIC_Pkgpc3);
4455 BIC_PRESENT(BIC_Pkgpc6);
4456 BIC_NOT_PRESENT(BIC_Pkgpc7);
0539ba11
LB
4457 BIC_PRESENT(BIC_Mod_c6);
4458 use_c1_residency_msr = 1;
4459 }
7170a374
LB
4460 if (is_dnv(family, model)) {
4461 BIC_PRESENT(BIC_CPU_c1);
4462 BIC_NOT_PRESENT(BIC_CPU_c3);
4463 BIC_NOT_PRESENT(BIC_Pkgpc3);
4464 BIC_NOT_PRESENT(BIC_CPU_c7);
4465 BIC_NOT_PRESENT(BIC_Pkgpc7);
4466 use_c1_residency_msr = 1;
4467 }
34c76197
LB
4468 if (is_skx(family, model)) {
4469 BIC_NOT_PRESENT(BIC_CPU_c3);
4470 BIC_NOT_PRESENT(BIC_Pkgpc3);
4471 BIC_NOT_PRESENT(BIC_CPU_c7);
4472 BIC_NOT_PRESENT(BIC_Pkgpc7);
4473 }
ade0ebac
LB
4474 if (is_bdx(family, model)) {
4475 BIC_NOT_PRESENT(BIC_CPU_c7);
4476 BIC_NOT_PRESENT(BIC_Pkgpc7);
4477 }
0f47c08d
LB
4478 if (has_hsw_msrs(family, model)) {
4479 BIC_PRESENT(BIC_Pkgpc8);
4480 BIC_PRESENT(BIC_Pkgpc9);
4481 BIC_PRESENT(BIC_Pkgpc10);
4482 }
5a63426e 4483 do_irtl_hsw = has_hsw_msrs(family, model);
a99d8730
LB
4484 if (has_skl_msrs(family, model)) {
4485 BIC_PRESENT(BIC_Totl_c0);
4486 BIC_PRESENT(BIC_Any_c0);
4487 BIC_PRESENT(BIC_GFX_c0);
4488 BIC_PRESENT(BIC_CPUGFX);
4489 }
144b44b1 4490 do_slm_cstates = is_slm(family, model);
fb5d4327 4491 do_knl_cstates = is_knl(family, model);
997e5395 4492 do_cnl_cstates = is_cnl(family, model);
103a8fea 4493
96e47158 4494 if (!quiet)
f0057310
LB
4495 decode_misc_pwr_mgmt_msr();
4496
96e47158 4497 if (!quiet && has_slv_msrs(family, model))
71616c8e
LB
4498 decode_c6_demotion_policy_msr();
4499
889facbe 4500 rapl_probe(family, model);
3a9a941d 4501 perf_limit_reasons_probe(family, model);
ac980e13 4502 automatic_cstate_conversion_probe(family, model);
889facbe 4503
96e47158 4504 if (!quiet)
1b69317d 4505 dump_cstate_pstate_config_info(family, model);
fcd17211 4506
41618e63
LB
4507 if (!quiet)
4508 dump_sysfs_cstate_config();
7293fccd
LB
4509 if (!quiet)
4510 dump_sysfs_pstate_config();
41618e63 4511
a2b7b749
LB
4512 if (has_skl_msrs(family, model))
4513 calculate_tsc_tweak();
4514
812db3f7
LB
4515 if (!access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK))
4516 BIC_PRESENT(BIC_GFX_rc6);
fdf676e5 4517
812db3f7
LB
4518 if (!access("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", R_OK))
4519 BIC_PRESENT(BIC_GFXMHz);
27d47356 4520
be0e54c4
LB
4521 if (!access("/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us", R_OK))
4522 BIC_PRESENT(BIC_CPU_LPI);
4523 else
4524 BIC_NOT_PRESENT(BIC_CPU_LPI);
4525
4526 if (!access("/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us", R_OK))
4527 BIC_PRESENT(BIC_SYS_LPI);
4528 else
4529 BIC_NOT_PRESENT(BIC_SYS_LPI);
4530
96e47158 4531 if (!quiet)
33148d67
LB
4532 decode_misc_feature_control();
4533
889facbe 4534 return;
103a8fea
LB
4535}
4536
103a8fea
LB
4537
4538/*
4539 * in /dev/cpu/ return success for names that are numbers
4540 * ie. filter out ".", "..", "microcode".
4541 */
4542int dir_filter(const struct dirent *dirp)
4543{
4544 if (isdigit(dirp->d_name[0]))
4545 return 1;
4546 else
4547 return 0;
4548}
4549
4550int open_dev_cpu_msr(int dummy1)
4551{
4552 return 0;
4553}
4554
c98d5d94
LB
4555void topology_probe()
4556{
4557 int i;
4558 int max_core_id = 0;
4559 int max_package_id = 0;
4560 int max_siblings = 0;
4561 struct cpu_topology {
4562 int core_id;
4563 int physical_package_id;
4564 } *cpus;
4565
4566 /* Initialize num_cpus, max_cpu_num */
4567 topo.num_cpus = 0;
4568 topo.max_cpu_num = 0;
4569 for_all_proc_cpus(count_cpus);
4570 if (!summary_only && topo.num_cpus > 1)
812db3f7 4571 BIC_PRESENT(BIC_CPU);
c98d5d94 4572
d8af6f5f 4573 if (debug > 1)
b7d8c148 4574 fprintf(outf, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num);
c98d5d94
LB
4575
4576 cpus = calloc(1, (topo.max_cpu_num + 1) * sizeof(struct cpu_topology));
b2c95d90
JT
4577 if (cpus == NULL)
4578 err(1, "calloc cpus");
c98d5d94
LB
4579
4580 /*
4581 * Allocate and initialize cpu_present_set
4582 */
4583 cpu_present_set = CPU_ALLOC((topo.max_cpu_num + 1));
b2c95d90
JT
4584 if (cpu_present_set == NULL)
4585 err(3, "CPU_ALLOC");
c98d5d94
LB
4586 cpu_present_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
4587 CPU_ZERO_S(cpu_present_setsize, cpu_present_set);
4588 for_all_proc_cpus(mark_cpu_present);
4589
1ef7d21a
LB
4590 /*
4591 * Validate that all cpus in cpu_subset are also in cpu_present_set
4592 */
4593 for (i = 0; i < CPU_SUBSET_MAXCPUS; ++i) {
4594 if (CPU_ISSET_S(i, cpu_subset_size, cpu_subset))
4595 if (!CPU_ISSET_S(i, cpu_present_setsize, cpu_present_set))
4596 err(1, "cpu%d not present", i);
4597 }
4598
c98d5d94
LB
4599 /*
4600 * Allocate and initialize cpu_affinity_set
4601 */
4602 cpu_affinity_set = CPU_ALLOC((topo.max_cpu_num + 1));
b2c95d90
JT
4603 if (cpu_affinity_set == NULL)
4604 err(3, "CPU_ALLOC");
c98d5d94
LB
4605 cpu_affinity_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
4606 CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
4607
4608
4609 /*
4610 * For online cpus
4611 * find max_core_id, max_package_id
4612 */
4613 for (i = 0; i <= topo.max_cpu_num; ++i) {
4614 int siblings;
4615
4616 if (cpu_is_not_present(i)) {
d8af6f5f 4617 if (debug > 1)
b7d8c148 4618 fprintf(outf, "cpu%d NOT PRESENT\n", i);
c98d5d94
LB
4619 continue;
4620 }
4621 cpus[i].core_id = get_core_id(i);
4622 if (cpus[i].core_id > max_core_id)
4623 max_core_id = cpus[i].core_id;
4624
4625 cpus[i].physical_package_id = get_physical_package_id(i);
4626 if (cpus[i].physical_package_id > max_package_id)
4627 max_package_id = cpus[i].physical_package_id;
4628
4629 siblings = get_num_ht_siblings(i);
4630 if (siblings > max_siblings)
4631 max_siblings = siblings;
d8af6f5f 4632 if (debug > 1)
b7d8c148 4633 fprintf(outf, "cpu %d pkg %d core %d\n",
c98d5d94
LB
4634 i, cpus[i].physical_package_id, cpus[i].core_id);
4635 }
4636 topo.num_cores_per_pkg = max_core_id + 1;
d8af6f5f 4637 if (debug > 1)
b7d8c148 4638 fprintf(outf, "max_core_id %d, sizing for %d cores per package\n",
c98d5d94 4639 max_core_id, topo.num_cores_per_pkg);
0f47c08d 4640 if (!summary_only && topo.num_cores_per_pkg > 1)
812db3f7 4641 BIC_PRESENT(BIC_Core);
c98d5d94
LB
4642
4643 topo.num_packages = max_package_id + 1;
d8af6f5f 4644 if (debug > 1)
b7d8c148 4645 fprintf(outf, "max_package_id %d, sizing for %d packages\n",
c98d5d94 4646 max_package_id, topo.num_packages);
7da6e3e2 4647 if (!summary_only && topo.num_packages > 1)
812db3f7 4648 BIC_PRESENT(BIC_Package);
c98d5d94
LB
4649
4650 topo.num_threads_per_core = max_siblings;
d8af6f5f 4651 if (debug > 1)
b7d8c148 4652 fprintf(outf, "max_siblings %d\n", max_siblings);
c98d5d94
LB
4653
4654 free(cpus);
4655}
4656
4657void
4658allocate_counters(struct thread_data **t, struct core_data **c, struct pkg_data **p)
4659{
4660 int i;
4661
4662 *t = calloc(topo.num_threads_per_core * topo.num_cores_per_pkg *
678a3bd1 4663 topo.num_packages, sizeof(struct thread_data));
c98d5d94
LB
4664 if (*t == NULL)
4665 goto error;
4666
4667 for (i = 0; i < topo.num_threads_per_core *
4668 topo.num_cores_per_pkg * topo.num_packages; i++)
4669 (*t)[i].cpu_id = -1;
4670
4671 *c = calloc(topo.num_cores_per_pkg * topo.num_packages,
678a3bd1 4672 sizeof(struct core_data));
c98d5d94
LB
4673 if (*c == NULL)
4674 goto error;
4675
4676 for (i = 0; i < topo.num_cores_per_pkg * topo.num_packages; i++)
4677 (*c)[i].core_id = -1;
4678
678a3bd1 4679 *p = calloc(topo.num_packages, sizeof(struct pkg_data));
c98d5d94
LB
4680 if (*p == NULL)
4681 goto error;
4682
4683 for (i = 0; i < topo.num_packages; i++)
4684 (*p)[i].package_id = i;
4685
4686 return;
4687error:
b2c95d90 4688 err(1, "calloc counters");
c98d5d94
LB
4689}
4690/*
4691 * init_counter()
4692 *
4693 * set cpu_id, core_num, pkg_num
4694 * set FIRST_THREAD_IN_CORE and FIRST_CORE_IN_PACKAGE
4695 *
4696 * increment topo.num_cores when 1st core in pkg seen
4697 */
4698void init_counter(struct thread_data *thread_base, struct core_data *core_base,
4699 struct pkg_data *pkg_base, int thread_num, int core_num,
4700 int pkg_num, int cpu_id)
4701{
4702 struct thread_data *t;
4703 struct core_data *c;
4704 struct pkg_data *p;
4705
4706 t = GET_THREAD(thread_base, thread_num, core_num, pkg_num);
4707 c = GET_CORE(core_base, core_num, pkg_num);
4708 p = GET_PKG(pkg_base, pkg_num);
4709
4710 t->cpu_id = cpu_id;
4711 if (thread_num == 0) {
4712 t->flags |= CPU_IS_FIRST_THREAD_IN_CORE;
4713 if (cpu_is_first_core_in_package(cpu_id))
4714 t->flags |= CPU_IS_FIRST_CORE_IN_PACKAGE;
4715 }
4716
4717 c->core_id = core_num;
4718 p->package_id = pkg_num;
4719}
4720
4721
4722int initialize_counters(int cpu_id)
4723{
4724 int my_thread_id, my_core_id, my_package_id;
4725
4726 my_package_id = get_physical_package_id(cpu_id);
4727 my_core_id = get_core_id(cpu_id);
e275b388
DC
4728 my_thread_id = get_cpu_position_in_core(cpu_id);
4729 if (!my_thread_id)
c98d5d94 4730 topo.num_cores++;
c98d5d94
LB
4731
4732 init_counter(EVEN_COUNTERS, my_thread_id, my_core_id, my_package_id, cpu_id);
4733 init_counter(ODD_COUNTERS, my_thread_id, my_core_id, my_package_id, cpu_id);
4734 return 0;
4735}
4736
4737void allocate_output_buffer()
4738{
3b4d5c7f 4739 output_buffer = calloc(1, (1 + topo.num_cpus) * 1024);
c98d5d94 4740 outp = output_buffer;
b2c95d90
JT
4741 if (outp == NULL)
4742 err(-1, "calloc output buffer");
c98d5d94 4743}
36229897
LB
4744void allocate_fd_percpu(void)
4745{
01a67adf 4746 fd_percpu = calloc(topo.max_cpu_num + 1, sizeof(int));
36229897
LB
4747 if (fd_percpu == NULL)
4748 err(-1, "calloc fd_percpu");
4749}
562a2d37
LB
4750void allocate_irq_buffers(void)
4751{
4752 irq_column_2_cpu = calloc(topo.num_cpus, sizeof(int));
4753 if (irq_column_2_cpu == NULL)
4754 err(-1, "calloc %d", topo.num_cpus);
c98d5d94 4755
01a67adf 4756 irqs_per_cpu = calloc(topo.max_cpu_num + 1, sizeof(int));
562a2d37 4757 if (irqs_per_cpu == NULL)
01a67adf 4758 err(-1, "calloc %d", topo.max_cpu_num + 1);
562a2d37 4759}
c98d5d94
LB
4760void setup_all_buffers(void)
4761{
4762 topology_probe();
562a2d37 4763 allocate_irq_buffers();
36229897 4764 allocate_fd_percpu();
c98d5d94
LB
4765 allocate_counters(&thread_even, &core_even, &package_even);
4766 allocate_counters(&thread_odd, &core_odd, &package_odd);
4767 allocate_output_buffer();
4768 for_all_proc_cpus(initialize_counters);
4769}
3b4d5c7f 4770
7ce7d5de
PB
4771void set_base_cpu(void)
4772{
4773 base_cpu = sched_getcpu();
4774 if (base_cpu < 0)
4775 err(-ENODEV, "No valid cpus found");
4776
4777 if (debug > 1)
b7d8c148 4778 fprintf(outf, "base_cpu = %d\n", base_cpu);
7ce7d5de
PB
4779}
4780
103a8fea
LB
4781void turbostat_init()
4782{
7ce7d5de
PB
4783 setup_all_buffers();
4784 set_base_cpu();
103a8fea 4785 check_dev_msr();
98481e79 4786 check_permissions();
fcd17211 4787 process_cpuid();
103a8fea 4788
103a8fea 4789
96e47158 4790 if (!quiet)
7f5c258e
LB
4791 for_all_cpus(print_hwp, ODD_COUNTERS);
4792
96e47158 4793 if (!quiet)
889facbe
LB
4794 for_all_cpus(print_epb, ODD_COUNTERS);
4795
96e47158 4796 if (!quiet)
3a9a941d
LB
4797 for_all_cpus(print_perf_limit, ODD_COUNTERS);
4798
96e47158 4799 if (!quiet)
889facbe
LB
4800 for_all_cpus(print_rapl, ODD_COUNTERS);
4801
4802 for_all_cpus(set_temperature_target, ODD_COUNTERS);
4803
96e47158 4804 if (!quiet)
889facbe 4805 for_all_cpus(print_thermal, ODD_COUNTERS);
5a63426e 4806
96e47158 4807 if (!quiet && do_irtl_snb)
5a63426e 4808 print_irtl();
103a8fea
LB
4809}
4810
4811int fork_it(char **argv)
4812{
103a8fea 4813 pid_t child_pid;
d91bb17c 4814 int status;
d15cf7c1 4815
218f0e8d 4816 snapshot_proc_sysfs_files();
d91bb17c
LB
4817 status = for_all_cpus(get_counters, EVEN_COUNTERS);
4818 if (status)
4819 exit(status);
c98d5d94
LB
4820 /* clear affinity side-effect of get_counters() */
4821 sched_setaffinity(0, cpu_present_setsize, cpu_present_set);
103a8fea
LB
4822 gettimeofday(&tv_even, (struct timezone *)NULL);
4823
4824 child_pid = fork();
4825 if (!child_pid) {
4826 /* child */
4827 execvp(argv[0], argv);
0815a3d0 4828 err(errno, "exec %s", argv[0]);
103a8fea 4829 } else {
103a8fea
LB
4830
4831 /* parent */
b2c95d90
JT
4832 if (child_pid == -1)
4833 err(1, "fork");
103a8fea
LB
4834
4835 signal(SIGINT, SIG_IGN);
4836 signal(SIGQUIT, SIG_IGN);
b2c95d90
JT
4837 if (waitpid(child_pid, &status, 0) == -1)
4838 err(status, "waitpid");
103a8fea 4839 }
c98d5d94
LB
4840 /*
4841 * n.b. fork_it() does not check for errors from for_all_cpus()
4842 * because re-starting is problematic when forking
4843 */
218f0e8d 4844 snapshot_proc_sysfs_files();
c98d5d94 4845 for_all_cpus(get_counters, ODD_COUNTERS);
103a8fea 4846 gettimeofday(&tv_odd, (struct timezone *)NULL);
103a8fea 4847 timersub(&tv_odd, &tv_even, &tv_delta);
ba3dec99
LB
4848 if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS))
4849 fprintf(outf, "%s: Counter reset detected\n", progname);
4850 else {
4851 compute_average(EVEN_COUNTERS);
4852 format_all_counters(EVEN_COUNTERS);
4853 }
103a8fea 4854
b7d8c148
LB
4855 fprintf(outf, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0);
4856
4857 flush_output_stderr();
103a8fea 4858
d91bb17c 4859 return status;
103a8fea
LB
4860}
4861
3b4d5c7f
AS
4862int get_and_dump_counters(void)
4863{
4864 int status;
4865
218f0e8d 4866 snapshot_proc_sysfs_files();
3b4d5c7f
AS
4867 status = for_all_cpus(get_counters, ODD_COUNTERS);
4868 if (status)
4869 return status;
4870
4871 status = for_all_cpus(dump_counters, ODD_COUNTERS);
4872 if (status)
4873 return status;
4874
b7d8c148 4875 flush_output_stdout();
3b4d5c7f
AS
4876
4877 return status;
4878}
4879
d8af6f5f 4880void print_version() {
f7d44a8f 4881 fprintf(outf, "turbostat version 17.06.23"
d8af6f5f
LB
4882 " - Len Brown <lenb@kernel.org>\n");
4883}
4884
495c7654
LB
4885int add_counter(unsigned int msr_num, char *path, char *name,
4886 unsigned int width, enum counter_scope scope,
41618e63 4887 enum counter_type type, enum counter_format format, int flags)
388e9c81
LB
4888{
4889 struct msr_counter *msrp;
4890
4891 msrp = calloc(1, sizeof(struct msr_counter));
4892 if (msrp == NULL) {
4893 perror("calloc");
4894 exit(1);
4895 }
4896
4897 msrp->msr_num = msr_num;
4898 strncpy(msrp->name, name, NAME_BYTES);
495c7654
LB
4899 if (path)
4900 strncpy(msrp->path, path, PATH_BYTES);
388e9c81
LB
4901 msrp->width = width;
4902 msrp->type = type;
4903 msrp->format = format;
41618e63 4904 msrp->flags = flags;
388e9c81
LB
4905
4906 switch (scope) {
4907
4908 case SCOPE_CPU:
388e9c81
LB
4909 msrp->next = sys.tp;
4910 sys.tp = msrp;
678a3bd1 4911 sys.added_thread_counters++;
0748eaf0 4912 if (sys.added_thread_counters > MAX_ADDED_THREAD_COUNTERS) {
678a3bd1
LB
4913 fprintf(stderr, "exceeded max %d added thread counters\n",
4914 MAX_ADDED_COUNTERS);
4915 exit(-1);
4916 }
388e9c81
LB
4917 break;
4918
4919 case SCOPE_CORE:
388e9c81
LB
4920 msrp->next = sys.cp;
4921 sys.cp = msrp;
678a3bd1
LB
4922 sys.added_core_counters++;
4923 if (sys.added_core_counters > MAX_ADDED_COUNTERS) {
4924 fprintf(stderr, "exceeded max %d added core counters\n",
4925 MAX_ADDED_COUNTERS);
4926 exit(-1);
4927 }
388e9c81
LB
4928 break;
4929
4930 case SCOPE_PACKAGE:
388e9c81
LB
4931 msrp->next = sys.pp;
4932 sys.pp = msrp;
678a3bd1
LB
4933 sys.added_package_counters++;
4934 if (sys.added_package_counters > MAX_ADDED_COUNTERS) {
4935 fprintf(stderr, "exceeded max %d added package counters\n",
4936 MAX_ADDED_COUNTERS);
4937 exit(-1);
4938 }
388e9c81
LB
4939 break;
4940 }
4941
4942 return 0;
4943}
4944
4945void parse_add_command(char *add_command)
4946{
4947 int msr_num = 0;
495c7654 4948 char *path = NULL;
0f47c08d 4949 char name_buffer[NAME_BYTES] = "";
388e9c81
LB
4950 int width = 64;
4951 int fail = 0;
4952 enum counter_scope scope = SCOPE_CPU;
4953 enum counter_type type = COUNTER_CYCLES;
4954 enum counter_format format = FORMAT_DELTA;
4955
4956 while (add_command) {
4957
4958 if (sscanf(add_command, "msr0x%x", &msr_num) == 1)
4959 goto next;
4960
4961 if (sscanf(add_command, "msr%d", &msr_num) == 1)
4962 goto next;
4963
495c7654
LB
4964 if (*add_command == '/') {
4965 path = add_command;
4966 goto next;
4967 }
4968
388e9c81
LB
4969 if (sscanf(add_command, "u%d", &width) == 1) {
4970 if ((width == 32) || (width == 64))
4971 goto next;
4972 width = 64;
4973 }
4974 if (!strncmp(add_command, "cpu", strlen("cpu"))) {
4975 scope = SCOPE_CPU;
4976 goto next;
4977 }
4978 if (!strncmp(add_command, "core", strlen("core"))) {
4979 scope = SCOPE_CORE;
4980 goto next;
4981 }
4982 if (!strncmp(add_command, "package", strlen("package"))) {
4983 scope = SCOPE_PACKAGE;
4984 goto next;
4985 }
4986 if (!strncmp(add_command, "cycles", strlen("cycles"))) {
4987 type = COUNTER_CYCLES;
4988 goto next;
4989 }
4990 if (!strncmp(add_command, "seconds", strlen("seconds"))) {
4991 type = COUNTER_SECONDS;
4992 goto next;
4993 }
41618e63
LB
4994 if (!strncmp(add_command, "usec", strlen("usec"))) {
4995 type = COUNTER_USEC;
4996 goto next;
4997 }
388e9c81
LB
4998 if (!strncmp(add_command, "raw", strlen("raw"))) {
4999 format = FORMAT_RAW;
5000 goto next;
5001 }
5002 if (!strncmp(add_command, "delta", strlen("delta"))) {
5003 format = FORMAT_DELTA;
5004 goto next;
5005 }
5006 if (!strncmp(add_command, "percent", strlen("percent"))) {
5007 format = FORMAT_PERCENT;
5008 goto next;
5009 }
5010
5011 if (sscanf(add_command, "%18s,%*s", name_buffer) == 1) { /* 18 < NAME_BYTES */
5012 char *eos;
5013
5014 eos = strchr(name_buffer, ',');
5015 if (eos)
5016 *eos = '\0';
5017 goto next;
5018 }
5019
5020next:
5021 add_command = strchr(add_command, ',');
495c7654
LB
5022 if (add_command) {
5023 *add_command = '\0';
388e9c81 5024 add_command++;
495c7654 5025 }
388e9c81
LB
5026
5027 }
495c7654
LB
5028 if ((msr_num == 0) && (path == NULL)) {
5029 fprintf(stderr, "--add: (msrDDD | msr0xXXX | /path_to_counter ) required\n");
388e9c81
LB
5030 fail++;
5031 }
5032
5033 /* generate default column header */
5034 if (*name_buffer == '\0') {
5f3aea57
LB
5035 if (width == 32)
5036 sprintf(name_buffer, "M0x%x%s", msr_num, format == FORMAT_PERCENT ? "%" : "");
5037 else
5038 sprintf(name_buffer, "M0X%x%s", msr_num, format == FORMAT_PERCENT ? "%" : "");
388e9c81
LB
5039 }
5040
41618e63 5041 if (add_counter(msr_num, path, name_buffer, width, scope, type, format, 0))
388e9c81
LB
5042 fail++;
5043
5044 if (fail) {
5045 help();
5046 exit(1);
5047 }
5048}
41618e63 5049
dd778a5e
LB
5050int is_deferred_skip(char *name)
5051{
5052 int i;
5053
5054 for (i = 0; i < deferred_skip_index; ++i)
5055 if (!strcmp(name, deferred_skip_names[i]))
5056 return 1;
5057 return 0;
5058}
5059
41618e63
LB
5060void probe_sysfs(void)
5061{
5062 char path[64];
5063 char name_buf[16];
5064 FILE *input;
5065 int state;
5066 char *sp;
5067
5068 if (!DO_BIC(BIC_sysfs))
5069 return;
5070
0748eaf0 5071 for (state = 10; state >= 0; --state) {
41618e63
LB
5072
5073 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
5074 base_cpu, state);
5075 input = fopen(path, "r");
5076 if (input == NULL)
5077 continue;
5078 fgets(name_buf, sizeof(name_buf), input);
5079
5080 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
5081 sp = strchr(name_buf, '-');
5082 if (!sp)
5083 sp = strchrnul(name_buf, '\n');
5084 *sp = '%';
5085 *(sp + 1) = '\0';
5086
5087 fclose(input);
5088
5089 sprintf(path, "cpuidle/state%d/time", state);
5090
dd778a5e
LB
5091 if (is_deferred_skip(name_buf))
5092 continue;
5093
41618e63
LB
5094 add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_USEC,
5095 FORMAT_PERCENT, SYSFS_PERCPU);
5096 }
5097
0748eaf0 5098 for (state = 10; state >= 0; --state) {
41618e63
LB
5099
5100 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
5101 base_cpu, state);
5102 input = fopen(path, "r");
5103 if (input == NULL)
5104 continue;
5105 fgets(name_buf, sizeof(name_buf), input);
5106 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
5107 sp = strchr(name_buf, '-');
5108 if (!sp)
5109 sp = strchrnul(name_buf, '\n');
5110 *sp = '\0';
5111 fclose(input);
5112
5113 sprintf(path, "cpuidle/state%d/usage", state);
5114
dd778a5e
LB
5115 if (is_deferred_skip(name_buf))
5116 continue;
5117
41618e63
LB
5118 add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS,
5119 FORMAT_DELTA, SYSFS_PERCPU);
5120 }
5121
5122}
5123
1ef7d21a
LB
5124
5125/*
5126 * parse cpuset with following syntax
5127 * 1,2,4..6,8-10 and set bits in cpu_subset
5128 */
5129void parse_cpu_command(char *optarg)
5130{
5131 unsigned int start, end;
5132 char *next;
5133
4e4e1e7c
LB
5134 if (!strcmp(optarg, "core")) {
5135 if (cpu_subset)
5136 goto error;
5137 show_core_only++;
5138 return;
5139 }
5140 if (!strcmp(optarg, "package")) {
5141 if (cpu_subset)
5142 goto error;
5143 show_pkg_only++;
5144 return;
5145 }
5146 if (show_core_only || show_pkg_only)
5147 goto error;
5148
1ef7d21a
LB
5149 cpu_subset = CPU_ALLOC(CPU_SUBSET_MAXCPUS);
5150 if (cpu_subset == NULL)
5151 err(3, "CPU_ALLOC");
5152 cpu_subset_size = CPU_ALLOC_SIZE(CPU_SUBSET_MAXCPUS);
5153
5154 CPU_ZERO_S(cpu_subset_size, cpu_subset);
5155
5156 next = optarg;
5157
5158 while (next && *next) {
5159
5160 if (*next == '-') /* no negative cpu numbers */
5161 goto error;
5162
5163 start = strtoul(next, &next, 10);
5164
5165 if (start >= CPU_SUBSET_MAXCPUS)
5166 goto error;
5167 CPU_SET_S(start, cpu_subset_size, cpu_subset);
5168
5169 if (*next == '\0')
5170 break;
5171
5172 if (*next == ',') {
5173 next += 1;
5174 continue;
5175 }
5176
5177 if (*next == '-') {
5178 next += 1; /* start range */
5179 } else if (*next == '.') {
5180 next += 1;
5181 if (*next == '.')
5182 next += 1; /* start range */
5183 else
5184 goto error;
5185 }
5186
5187 end = strtoul(next, &next, 10);
5188 if (end <= start)
5189 goto error;
5190
5191 while (++start <= end) {
5192 if (start >= CPU_SUBSET_MAXCPUS)
5193 goto error;
5194 CPU_SET_S(start, cpu_subset_size, cpu_subset);
5195 }
5196
5197 if (*next == ',')
5198 next += 1;
5199 else if (*next != '\0')
5200 goto error;
5201 }
5202
5203 return;
5204
5205error:
4e4e1e7c
LB
5206 fprintf(stderr, "\"--cpu %s\" malformed\n", optarg);
5207 help();
1ef7d21a
LB
5208 exit(-1);
5209}
5210
812db3f7 5211
103a8fea
LB
5212void cmdline(int argc, char **argv)
5213{
5214 int opt;
d8af6f5f
LB
5215 int option_index = 0;
5216 static struct option long_options[] = {
388e9c81 5217 {"add", required_argument, 0, 'a'},
1ef7d21a 5218 {"cpu", required_argument, 0, 'c'},
d8af6f5f 5219 {"Dump", no_argument, 0, 'D'},
96e47158 5220 {"debug", no_argument, 0, 'd'}, /* internal, not documented */
3f44a5c6 5221 {"enable", required_argument, 0, 'e'},
d8af6f5f 5222 {"interval", required_argument, 0, 'i'},
023fe0ac 5223 {"num_iterations", required_argument, 0, 'n'},
d8af6f5f 5224 {"help", no_argument, 0, 'h'},
812db3f7 5225 {"hide", required_argument, 0, 'H'}, // meh, -h taken by --help
d8af6f5f 5226 {"Joules", no_argument, 0, 'J'},
c8ade361 5227 {"list", no_argument, 0, 'l'},
b7d8c148 5228 {"out", required_argument, 0, 'o'},
96e47158 5229 {"quiet", no_argument, 0, 'q'},
812db3f7 5230 {"show", required_argument, 0, 's'},
d8af6f5f
LB
5231 {"Summary", no_argument, 0, 'S'},
5232 {"TCC", required_argument, 0, 'T'},
5233 {"version", no_argument, 0, 'v' },
5234 {0, 0, 0, 0 }
5235 };
103a8fea
LB
5236
5237 progname = argv[0];
5238
023fe0ac 5239 while ((opt = getopt_long_only(argc, argv, "+C:c:Dde:hi:Jn:o:qST:v",
d8af6f5f 5240 long_options, &option_index)) != -1) {
103a8fea 5241 switch (opt) {
388e9c81
LB
5242 case 'a':
5243 parse_add_command(optarg);
5244 break;
1ef7d21a
LB
5245 case 'c':
5246 parse_cpu_command(optarg);
5247 break;
d8af6f5f 5248 case 'D':
3b4d5c7f
AS
5249 dump_only++;
5250 break;
3f44a5c6
LB
5251 case 'e':
5252 /* --enable specified counter */
5253 bic_enabled |= bic_lookup(optarg, SHOW_LIST);
5254 break;
d8af6f5f
LB
5255 case 'd':
5256 debug++;
3f44a5c6 5257 ENABLE_BIC(BIC_DISABLED_BY_DEFAULT);
103a8fea 5258 break;
812db3f7 5259 case 'H':
3f44a5c6
LB
5260 /*
5261 * --hide: do not show those specified
5262 * multiple invocations simply clear more bits in enabled mask
5263 */
5264 bic_enabled &= ~bic_lookup(optarg, HIDE_LIST);
812db3f7 5265 break;
d8af6f5f
LB
5266 case 'h':
5267 default:
5268 help();
5269 exit(1);
103a8fea 5270 case 'i':
2a0609c0
LB
5271 {
5272 double interval = strtod(optarg, NULL);
5273
5274 if (interval < 0.001) {
b7d8c148 5275 fprintf(outf, "interval %f seconds is too small\n",
2a0609c0
LB
5276 interval);
5277 exit(2);
5278 }
5279
47936f94 5280 interval_tv.tv_sec = interval_ts.tv_sec = interval;
b9ad8ee0 5281 interval_tv.tv_usec = (interval - interval_tv.tv_sec) * 1000000;
47936f94 5282 interval_ts.tv_nsec = (interval - interval_ts.tv_sec) * 1000000000;
2a0609c0 5283 }
103a8fea 5284 break;
d8af6f5f
LB
5285 case 'J':
5286 rapl_joules++;
8e180f3c 5287 break;
c8ade361 5288 case 'l':
3f44a5c6 5289 ENABLE_BIC(BIC_DISABLED_BY_DEFAULT);
c8ade361
LB
5290 list_header_only++;
5291 quiet++;
5292 break;
b7d8c148
LB
5293 case 'o':
5294 outf = fopen_or_die(optarg, "w");
5295 break;
96e47158
LB
5296 case 'q':
5297 quiet = 1;
5298 break;
023fe0ac
CY
5299 case 'n':
5300 num_iterations = strtod(optarg, NULL);
5301
5302 if (num_iterations <= 0) {
5303 fprintf(outf, "iterations %d should be positive number\n",
5304 num_iterations);
5305 exit(2);
5306 }
5307 break;
812db3f7 5308 case 's':
3f44a5c6
LB
5309 /*
5310 * --show: show only those specified
5311 * The 1st invocation will clear and replace the enabled mask
5312 * subsequent invocations can add to it.
5313 */
5314 if (shown == 0)
5315 bic_enabled = bic_lookup(optarg, SHOW_LIST);
5316 else
5317 bic_enabled |= bic_lookup(optarg, SHOW_LIST);
5318 shown = 1;
812db3f7 5319 break;
d8af6f5f
LB
5320 case 'S':
5321 summary_only++;
889facbe
LB
5322 break;
5323 case 'T':
5324 tcc_activation_temp_override = atoi(optarg);
5325 break;
d8af6f5f
LB
5326 case 'v':
5327 print_version();
5328 exit(0);
5c56be9a 5329 break;
103a8fea
LB
5330 }
5331 }
5332}
5333
5334int main(int argc, char **argv)
5335{
b7d8c148
LB
5336 outf = stderr;
5337
103a8fea
LB
5338 cmdline(argc, argv);
5339
96e47158 5340 if (!quiet)
d8af6f5f 5341 print_version();
103a8fea 5342
41618e63
LB
5343 probe_sysfs();
5344
103a8fea
LB
5345 turbostat_init();
5346
3b4d5c7f
AS
5347 /* dump counters and exit */
5348 if (dump_only)
5349 return get_and_dump_counters();
5350
c8ade361
LB
5351 /* list header and exit */
5352 if (list_header_only) {
5353 print_header(",");
5354 flush_output_stdout();
5355 return 0;
5356 }
5357
103a8fea
LB
5358 /*
5359 * if any params left, it must be a command to fork
5360 */
5361 if (argc - optind)
5362 return fork_it(argv + optind);
5363 else
5364 turbostat_loop();
5365
5366 return 0;
5367}