tools/power/turbostat: Adjust cstate for has_c8910_msrs() models
[linux-block.git] / tools / power / x86 / turbostat / turbostat.c
CommitLineData
a61127c2 1// SPDX-License-Identifier: GPL-2.0-only
103a8fea
LB
2/*
3 * turbostat -- show CPU frequency and C-state residency
34041551 4 * on modern Intel and AMD processors.
103a8fea 5 *
de7839ee 6 * Copyright (c) 2023 Intel Corporation.
103a8fea 7 * Len Brown <len.brown@intel.com>
103a8fea
LB
8 */
9
88c3281f 10#define _GNU_SOURCE
b731f311 11#include MSRHEADER
869ce69e 12#include INTEL_FAMILY_HEADER
95aebc44 13#include <stdarg.h>
103a8fea 14#include <stdio.h>
b2c95d90 15#include <err.h>
103a8fea
LB
16#include <unistd.h>
17#include <sys/types.h>
18#include <sys/wait.h>
19#include <sys/stat.h>
b9ad8ee0 20#include <sys/select.h>
103a8fea
LB
21#include <sys/resource.h>
22#include <fcntl.h>
23#include <signal.h>
24#include <sys/time.h>
25#include <stdlib.h>
d8af6f5f 26#include <getopt.h>
103a8fea
LB
27#include <dirent.h>
28#include <string.h>
29#include <ctype.h>
88c3281f 30#include <sched.h>
2a0609c0 31#include <time.h>
2b92865e 32#include <cpuid.h>
fcaa681c 33#include <sys/capability.h>
98481e79 34#include <errno.h>
9392bd98 35#include <math.h>
2af4f9b8
LB
36#include <linux/perf_event.h>
37#include <asm/unistd.h>
7ab5ff49 38#include <stdbool.h>
103a8fea 39
9878bf7a
LB
40#define UNUSED(x) (void)(x)
41
164d7a96
LB
42/*
43 * This list matches the column headers, except
44 * 1. built-in only, the sysfs counters are not here -- we learn of those at run-time
45 * 2. Core and CPU are moved to the end, we can't have strings that contain them
46 * matching on them for --show and --hide.
47 */
48
49/*
50 * buffer size used by sscanf() for added column names
51 * Usually truncated to 7 characters, but also handles 18 columns for raw 64-bit counters
52 */
53#define NAME_BYTES 20
54#define PATH_BYTES 128
55
56enum counter_scope { SCOPE_CPU, SCOPE_CORE, SCOPE_PACKAGE };
57enum counter_type { COUNTER_ITEMS, COUNTER_CYCLES, COUNTER_SECONDS, COUNTER_USEC };
58enum counter_format { FORMAT_RAW, FORMAT_DELTA, FORMAT_PERCENT };
59
60struct msr_counter {
61 unsigned int msr_num;
62 char name[NAME_BYTES];
63 char path[PATH_BYTES];
64 unsigned int width;
65 enum counter_type type;
66 enum counter_format format;
67 struct msr_counter *next;
68 unsigned int flags;
69#define FLAGS_HIDE (1 << 0)
70#define FLAGS_SHOW (1 << 1)
71#define SYSFS_PERCPU (1 << 1)
72};
73
74struct msr_counter bic[] = {
9878bf7a
LB
75 { 0x0, "usec", "", 0, 0, 0, NULL, 0 },
76 { 0x0, "Time_Of_Day_Seconds", "", 0, 0, 0, NULL, 0 },
77 { 0x0, "Package", "", 0, 0, 0, NULL, 0 },
78 { 0x0, "Node", "", 0, 0, 0, NULL, 0 },
79 { 0x0, "Avg_MHz", "", 0, 0, 0, NULL, 0 },
80 { 0x0, "Busy%", "", 0, 0, 0, NULL, 0 },
81 { 0x0, "Bzy_MHz", "", 0, 0, 0, NULL, 0 },
82 { 0x0, "TSC_MHz", "", 0, 0, 0, NULL, 0 },
83 { 0x0, "IRQ", "", 0, 0, 0, NULL, 0 },
84 { 0x0, "SMI", "", 32, 0, FORMAT_DELTA, NULL, 0 },
85 { 0x0, "sysfs", "", 0, 0, 0, NULL, 0 },
86 { 0x0, "CPU%c1", "", 0, 0, 0, NULL, 0 },
87 { 0x0, "CPU%c3", "", 0, 0, 0, NULL, 0 },
88 { 0x0, "CPU%c6", "", 0, 0, 0, NULL, 0 },
89 { 0x0, "CPU%c7", "", 0, 0, 0, NULL, 0 },
90 { 0x0, "ThreadC", "", 0, 0, 0, NULL, 0 },
91 { 0x0, "CoreTmp", "", 0, 0, 0, NULL, 0 },
92 { 0x0, "CoreCnt", "", 0, 0, 0, NULL, 0 },
93 { 0x0, "PkgTmp", "", 0, 0, 0, NULL, 0 },
94 { 0x0, "GFX%rc6", "", 0, 0, 0, NULL, 0 },
95 { 0x0, "GFXMHz", "", 0, 0, 0, NULL, 0 },
96 { 0x0, "Pkg%pc2", "", 0, 0, 0, NULL, 0 },
97 { 0x0, "Pkg%pc3", "", 0, 0, 0, NULL, 0 },
98 { 0x0, "Pkg%pc6", "", 0, 0, 0, NULL, 0 },
99 { 0x0, "Pkg%pc7", "", 0, 0, 0, NULL, 0 },
100 { 0x0, "Pkg%pc8", "", 0, 0, 0, NULL, 0 },
101 { 0x0, "Pkg%pc9", "", 0, 0, 0, NULL, 0 },
102 { 0x0, "Pk%pc10", "", 0, 0, 0, NULL, 0 },
103 { 0x0, "CPU%LPI", "", 0, 0, 0, NULL, 0 },
104 { 0x0, "SYS%LPI", "", 0, 0, 0, NULL, 0 },
105 { 0x0, "PkgWatt", "", 0, 0, 0, NULL, 0 },
106 { 0x0, "CorWatt", "", 0, 0, 0, NULL, 0 },
107 { 0x0, "GFXWatt", "", 0, 0, 0, NULL, 0 },
108 { 0x0, "PkgCnt", "", 0, 0, 0, NULL, 0 },
109 { 0x0, "RAMWatt", "", 0, 0, 0, NULL, 0 },
110 { 0x0, "PKG_%", "", 0, 0, 0, NULL, 0 },
111 { 0x0, "RAM_%", "", 0, 0, 0, NULL, 0 },
112 { 0x0, "Pkg_J", "", 0, 0, 0, NULL, 0 },
113 { 0x0, "Cor_J", "", 0, 0, 0, NULL, 0 },
114 { 0x0, "GFX_J", "", 0, 0, 0, NULL, 0 },
115 { 0x0, "RAM_J", "", 0, 0, 0, NULL, 0 },
116 { 0x0, "Mod%c6", "", 0, 0, 0, NULL, 0 },
117 { 0x0, "Totl%C0", "", 0, 0, 0, NULL, 0 },
118 { 0x0, "Any%C0", "", 0, 0, 0, NULL, 0 },
119 { 0x0, "GFX%C0", "", 0, 0, 0, NULL, 0 },
120 { 0x0, "CPUGFX%", "", 0, 0, 0, NULL, 0 },
121 { 0x0, "Core", "", 0, 0, 0, NULL, 0 },
122 { 0x0, "CPU", "", 0, 0, 0, NULL, 0 },
123 { 0x0, "APIC", "", 0, 0, 0, NULL, 0 },
124 { 0x0, "X2APIC", "", 0, 0, 0, NULL, 0 },
125 { 0x0, "Die", "", 0, 0, 0, NULL, 0 },
126 { 0x0, "GFXAMHz", "", 0, 0, 0, NULL, 0 },
127 { 0x0, "IPC", "", 0, 0, 0, NULL, 0 },
128 { 0x0, "CoreThr", "", 0, 0, 0, NULL, 0 },
a5c6d65d 129 { 0x0, "UncMHz", "", 0, 0, 0, NULL, 0 },
164d7a96
LB
130};
131
132#define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter))
133#define BIC_USEC (1ULL << 0)
134#define BIC_TOD (1ULL << 1)
135#define BIC_Package (1ULL << 2)
136#define BIC_Node (1ULL << 3)
137#define BIC_Avg_MHz (1ULL << 4)
138#define BIC_Busy (1ULL << 5)
139#define BIC_Bzy_MHz (1ULL << 6)
140#define BIC_TSC_MHz (1ULL << 7)
141#define BIC_IRQ (1ULL << 8)
142#define BIC_SMI (1ULL << 9)
143#define BIC_sysfs (1ULL << 10)
144#define BIC_CPU_c1 (1ULL << 11)
145#define BIC_CPU_c3 (1ULL << 12)
146#define BIC_CPU_c6 (1ULL << 13)
147#define BIC_CPU_c7 (1ULL << 14)
148#define BIC_ThreadC (1ULL << 15)
149#define BIC_CoreTmp (1ULL << 16)
150#define BIC_CoreCnt (1ULL << 17)
151#define BIC_PkgTmp (1ULL << 18)
152#define BIC_GFX_rc6 (1ULL << 19)
153#define BIC_GFXMHz (1ULL << 20)
154#define BIC_Pkgpc2 (1ULL << 21)
155#define BIC_Pkgpc3 (1ULL << 22)
156#define BIC_Pkgpc6 (1ULL << 23)
157#define BIC_Pkgpc7 (1ULL << 24)
158#define BIC_Pkgpc8 (1ULL << 25)
159#define BIC_Pkgpc9 (1ULL << 26)
160#define BIC_Pkgpc10 (1ULL << 27)
161#define BIC_CPU_LPI (1ULL << 28)
162#define BIC_SYS_LPI (1ULL << 29)
163#define BIC_PkgWatt (1ULL << 30)
164#define BIC_CorWatt (1ULL << 31)
165#define BIC_GFXWatt (1ULL << 32)
166#define BIC_PkgCnt (1ULL << 33)
167#define BIC_RAMWatt (1ULL << 34)
168#define BIC_PKG__ (1ULL << 35)
169#define BIC_RAM__ (1ULL << 36)
170#define BIC_Pkg_J (1ULL << 37)
171#define BIC_Cor_J (1ULL << 38)
172#define BIC_GFX_J (1ULL << 39)
173#define BIC_RAM_J (1ULL << 40)
174#define BIC_Mod_c6 (1ULL << 41)
175#define BIC_Totl_c0 (1ULL << 42)
176#define BIC_Any_c0 (1ULL << 43)
177#define BIC_GFX_c0 (1ULL << 44)
178#define BIC_CPUGFX (1ULL << 45)
179#define BIC_Core (1ULL << 46)
180#define BIC_CPU (1ULL << 47)
181#define BIC_APIC (1ULL << 48)
182#define BIC_X2APIC (1ULL << 49)
183#define BIC_Die (1ULL << 50)
184#define BIC_GFXACTMHz (1ULL << 51)
185#define BIC_IPC (1ULL << 52)
186#define BIC_CORE_THROT_CNT (1ULL << 53)
a5c6d65d 187#define BIC_UNCORE_MHZ (1ULL << 54)
164d7a96
LB
188
189#define BIC_TOPOLOGY (BIC_Package | BIC_Node | BIC_CoreCnt | BIC_PkgCnt | BIC_Core | BIC_CPU | BIC_Die )
190#define BIC_THERMAL_PWR ( BIC_CoreTmp | BIC_PkgTmp | BIC_PkgWatt | BIC_CorWatt | BIC_GFXWatt | BIC_RAMWatt | BIC_PKG__ | BIC_RAM__)
a5c6d65d 191#define BIC_FREQUENCY ( BIC_Avg_MHz | BIC_Busy | BIC_Bzy_MHz | BIC_TSC_MHz | BIC_GFXMHz | BIC_GFXACTMHz | BIC_UNCORE_MHZ)
164d7a96
LB
192#define BIC_IDLE ( BIC_sysfs | BIC_CPU_c1 | BIC_CPU_c3 | BIC_CPU_c6 | BIC_CPU_c7 | BIC_GFX_rc6 | BIC_Pkgpc2 | BIC_Pkgpc3 | BIC_Pkgpc6 | BIC_Pkgpc7 | BIC_Pkgpc8 | BIC_Pkgpc9 | BIC_Pkgpc10 | BIC_CPU_LPI | BIC_SYS_LPI | BIC_Mod_c6 | BIC_Totl_c0 | BIC_Any_c0 | BIC_GFX_c0 | BIC_CPUGFX)
193#define BIC_OTHER ( BIC_IRQ | BIC_SMI | BIC_ThreadC | BIC_CoreTmp | BIC_IPC)
194
195#define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC)
196
197unsigned long long bic_enabled = (0xFFFFFFFFFFFFFFFFULL & ~BIC_DISABLED_BY_DEFAULT);
198unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs | BIC_APIC | BIC_X2APIC;
199
200#define DO_BIC(COUNTER_NAME) (bic_enabled & bic_present & COUNTER_NAME)
201#define DO_BIC_READ(COUNTER_NAME) (bic_present & COUNTER_NAME)
202#define ENABLE_BIC(COUNTER_NAME) (bic_enabled |= COUNTER_NAME)
203#define BIC_PRESENT(COUNTER_BIT) (bic_present |= COUNTER_BIT)
204#define BIC_NOT_PRESENT(COUNTER_BIT) (bic_present &= ~COUNTER_BIT)
205#define BIC_IS_ENABLED(COUNTER_BIT) (bic_enabled & COUNTER_BIT)
206
103a8fea 207char *proc_stat = "/proc/stat";
b7d8c148 208FILE *outf;
36229897 209int *fd_percpu;
2af4f9b8 210int *fd_instr_count_percpu;
1b439f01
LB
211struct timeval interval_tv = { 5, 0 };
212struct timespec interval_ts = { 5, 0 };
e9d3092f 213
023fe0ac 214unsigned int num_iterations;
c7e399f8 215unsigned int header_iterations;
d8af6f5f 216unsigned int debug;
96e47158 217unsigned int quiet;
3f44a5c6 218unsigned int shown;
0de6c0df 219unsigned int sums_need_wide_columns;
d8af6f5f
LB
220unsigned int rapl_joules;
221unsigned int summary_only;
c8ade361 222unsigned int list_header_only;
d8af6f5f 223unsigned int dump_only;
fb5d4327 224unsigned int do_knl_cstates;
144b44b1
LB
225unsigned int do_slm_cstates;
226unsigned int use_c1_residency_msr;
103a8fea 227unsigned int has_aperf;
889facbe 228unsigned int has_epb;
3ea8e52e 229unsigned int has_turbo;
774627c5 230unsigned int is_hybrid;
5a63426e
LB
231unsigned int do_irtl_snb;
232unsigned int do_irtl_hsw;
fc04cc67 233unsigned int units = 1000000; /* MHz etc */
103a8fea 234unsigned int genuine_intel;
34041551 235unsigned int authentic_amd;
c1c10cc7 236unsigned int hygon_genuine;
34041551 237unsigned int max_level, max_extended_level;
103a8fea 238unsigned int has_invariant_tsc;
b2b34dfe 239unsigned int aperf_mperf_multiplier = 1;
103a8fea 240double bclk;
a2b7b749 241double base_hz;
21ed5574 242unsigned int has_base_hz;
a2b7b749 243double tsc_tweak = 1.0;
c98d5d94
LB
244unsigned int show_pkg_only;
245unsigned int show_core_only;
246char *output_buffer, *outp;
889facbe
LB
247unsigned int do_dts;
248unsigned int do_ptm;
2af4f9b8 249unsigned int do_ipc;
1b439f01 250unsigned long long gfx_cur_rc6_ms;
be0e54c4
LB
251unsigned long long cpuidle_cur_cpu_lpi_us;
252unsigned long long cpuidle_cur_sys_lpi_us;
27d47356 253unsigned int gfx_cur_mhz;
b4b91569 254unsigned int gfx_act_mhz;
55279aef
ZR
255unsigned int tj_max;
256unsigned int tj_max_override;
40ee8e3b
AS
257double rapl_power_units, rapl_time_units;
258double rapl_dram_energy_units, rapl_energy_units;
889facbe 259double rapl_joule_counter_range;
aeb01e6d 260unsigned int dis_cstate_prewake;
8a5bdf41
LB
261unsigned int crystal_hz;
262unsigned long long tsc_hz;
7ce7d5de 263int base_cpu;
1b439f01 264unsigned int has_hwp; /* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */
7f5c258e 265 /* IA32_HWP_REQUEST, IA32_HWP_STATUS */
1b439f01 266unsigned int has_hwp_notify; /* IA32_HWP_INTERRUPT */
7f5c258e 267unsigned int has_hwp_activity_window; /* IA32_HWP_REQUEST[bits 41:32] */
1b439f01
LB
268unsigned int has_hwp_epp; /* IA32_HWP_REQUEST[bits 31:24] */
269unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */
4c2122d4 270unsigned int first_counter_read = 1;
c026c236 271int ignore_stdin;
889facbe 272
71e84129
ZR
273int get_msr(int cpu, off_t offset, unsigned long long *msr);
274
45232ab1
ZR
275/* Model specific support Start */
276
277/* List of features that may diverge among different platforms */
278struct platform_features {
778fc34a 279 bool has_msr_misc_feature_control; /* MSR_MISC_FEATURE_CONTROL */
3dd0e754 280 bool has_msr_misc_pwr_mgmt; /* MSR_MISC_PWR_MGMT */
fcfa1ce0 281 bool has_nhm_msrs; /* MSR_PLATFORM_INFO, MSR_IA32_TEMPERATURE_TARGET, MSR_SMI_COUNT, MSR_PKG_CST_CONFIG_CONTROL, TRL MSRs */
a61c9cb4 282 bool has_config_tdp; /* MSR_CONFIG_TDP_NOMINAL/LEVEL_1/LEVEL_2/CONTROL, MSR_TURBO_ACTIVATION_RATIO */
71e84129 283 int bclk_freq; /* CPU base clock */
a5d1ab93 284 int crystal_freq; /* Crystal clock to use when not available from CPUID.15 */
3c6a17b8 285 int supported_cstates; /* Core cstates and Package cstates supported */
3989fc89 286 int cst_limit; /* MSR_PKG_CST_CONFIG_CONTROL */
d90120bf 287 bool has_cst_auto_convension; /* AUTOMATIC_CSTATE_CONVERSION bit in MSR_PKG_CST_CONFIG_CONTROL */
10d85d85 288 int trl_msrs; /* MSR_TURBO_RATIO_LIMIT/LIMIT1/LIMIT2/SECONDARY, Atom TRL MSRs */
0c057cf7 289 int plr_msrs; /* MSR_CORE/GFX/RING_PERF_LIMIT_REASONS */
86ba263d 290 int rapl_msrs; /* RAPL PKG/DRAM/CORE/GFX MSRs, AMD RAPL MSRs */
e338831b 291 bool has_per_core_rapl; /* Indicates cores energy collection is per-core, not per-package. AMD specific for now */
6d35b8c4 292 bool has_rapl_divisor; /* Divisor for Energy unit raw value from MSR_RAPL_POWER_UNIT */
9e6f3515 293 bool has_fixed_rapl_unit; /* Fixed Energy Unit used for DRAM RAPL Domain */
7c604093 294 int rapl_quirk_tdp; /* Hardcoded TDP value when cannot be retrieved from hardware */
d8e1623b 295 int tcc_offset_bits; /* TCC Offset bits in MSR_IA32_TEMPERATURE_TARGET */
485a017c 296 bool enable_tsc_tweak; /* Use CPU Base freq instead of TSC freq for aperf/mperf counter */
45232ab1
ZR
297};
298
299struct platform_data {
300 unsigned int model;
301 const struct platform_features *features;
302};
303
71e84129
ZR
304/* For BCLK */
305enum bclk_freq {
306 BCLK_100MHZ = 1,
307 BCLK_133MHZ,
308 BCLK_SLV,
309};
310
311#define SLM_BCLK_FREQS 5
312double slm_freq_table[SLM_BCLK_FREQS] = { 83.3, 100.0, 133.3, 116.7, 80.0 };
313
314double slm_bclk(void)
315{
316 unsigned long long msr = 3;
317 unsigned int i;
318 double freq;
319
320 if (get_msr(base_cpu, MSR_FSB_FREQ, &msr))
321 fprintf(outf, "SLM BCLK: unknown\n");
322
323 i = msr & 0xf;
324 if (i >= SLM_BCLK_FREQS) {
325 fprintf(outf, "SLM BCLK[%d] invalid\n", i);
326 i = 3;
327 }
328 freq = slm_freq_table[i];
329
330 if (!quiet)
331 fprintf(outf, "SLM BCLK: %.1f Mhz\n", freq);
332
333 return freq;
334}
335
3989fc89
ZR
336/* For Package cstate limit */
337enum package_cstate_limit {
338 CST_LIMIT_NHM = 1,
339 CST_LIMIT_SNB,
340 CST_LIMIT_HSW,
341 CST_LIMIT_SKX,
342 CST_LIMIT_ICX,
343 CST_LIMIT_SLV,
344 CST_LIMIT_AMT,
345 CST_LIMIT_KNL,
346 CST_LIMIT_GMT,
347};
348
10d85d85
ZR
349/* For Turbo Ratio Limit MSRs */
350enum turbo_ratio_limit_msrs {
351 TRL_BASE = BIT(0),
352 TRL_LIMIT1 = BIT(1),
353 TRL_LIMIT2 = BIT(2),
354 TRL_ATOM = BIT(3),
355 TRL_KNL = BIT(4),
356 TRL_CORECOUNT = BIT(5),
357};
358
0c057cf7
ZR
359/* For Perf Limit Reason MSRs */
360enum perf_limit_reason_msrs {
361 PLR_CORE = BIT(0),
362 PLR_GFX = BIT(1),
363 PLR_RING = BIT(2),
364};
365
b9cd6683
ZR
366/* For RAPL MSRs */
367enum rapl_msrs {
368 RAPL_PKG_POWER_LIMIT = BIT(0), /* 0x610 MSR_PKG_POWER_LIMIT */
369 RAPL_PKG_ENERGY_STATUS = BIT(1), /* 0x611 MSR_PKG_ENERGY_STATUS */
370 RAPL_PKG_PERF_STATUS = BIT(2), /* 0x613 MSR_PKG_PERF_STATUS */
371 RAPL_PKG_POWER_INFO = BIT(3), /* 0x614 MSR_PKG_POWER_INFO */
372 RAPL_DRAM_POWER_LIMIT = BIT(4), /* 0x618 MSR_DRAM_POWER_LIMIT */
373 RAPL_DRAM_ENERGY_STATUS = BIT(5), /* 0x619 MSR_DRAM_ENERGY_STATUS */
374 RAPL_DRAM_PERF_STATUS = BIT(6), /* 0x61b MSR_DRAM_PERF_STATUS */
375 RAPL_DRAM_POWER_INFO = BIT(7), /* 0x61c MSR_DRAM_POWER_INFO */
376 RAPL_CORE_POWER_LIMIT = BIT(8), /* 0x638 MSR_PP0_POWER_LIMIT */
377 RAPL_CORE_ENERGY_STATUS = BIT(9), /* 0x639 MSR_PP0_ENERGY_STATUS */
378 RAPL_CORE_POLICY = BIT(10), /* 0x63a MSR_PP0_POLICY */
379 RAPL_GFX_POWER_LIMIT = BIT(11), /* 0x640 MSR_PP1_POWER_LIMIT */
380 RAPL_GFX_ENERGY_STATUS = BIT(12), /* 0x641 MSR_PP1_ENERGY_STATUS */
381 RAPL_GFX_POLICY = BIT(13), /* 0x642 MSR_PP1_POLICY */
382 RAPL_AMD_PWR_UNIT = BIT(14), /* 0xc0010299 MSR_AMD_RAPL_POWER_UNIT */
383 RAPL_AMD_CORE_ENERGY_STAT = BIT(15), /* 0xc001029a MSR_AMD_CORE_ENERGY_STATUS */
384 RAPL_AMD_PKG_ENERGY_STAT = BIT(16), /* 0xc001029b MSR_AMD_PKG_ENERGY_STATUS */
b9cd6683
ZR
385};
386
387#define RAPL_PKG (RAPL_PKG_ENERGY_STATUS | RAPL_PKG_POWER_LIMIT)
388#define RAPL_DRAM (RAPL_DRAM_ENERGY_STATUS | RAPL_DRAM_POWER_LIMIT)
389#define RAPL_CORE (RAPL_CORE_ENERGY_STATUS | RAPL_CORE_POWER_LIMIT)
390#define RAPL_GFX (RAPL_GFX_POWER_LIMIT | RAPL_GFX_ENERGY_STATUS)
391
392#define RAPL_PKG_ALL (RAPL_PKG | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO)
393#define RAPL_DRAM_ALL (RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_DRAM_POWER_INFO)
394#define RAPL_CORE_ALL (RAPL_CORE | RAPL_CORE_POLICY)
395#define RAPL_GFX_ALL (RAPL_GFX | RAPL_GFX_POLIGY)
396
397#define RAPL_AMD_F17H (RAPL_AMD_PWR_UNIT | RAPL_AMD_CORE_ENERGY_STAT | RAPL_AMD_PKG_ENERGY_STAT)
398
3c6a17b8
ZR
399/* For Cstates */
400enum cstates {
401 CC1 = BIT(0),
402 CC3 = BIT(1),
403 CC6 = BIT(2),
404 CC7 = BIT(3),
405 PC2 = BIT(4),
406 PC3 = BIT(5),
407 PC6 = BIT(6),
408 PC7 = BIT(7),
409 PC8 = BIT(8),
410 PC9 = BIT(9),
411 PC10 = BIT(10),
412};
413
45232ab1 414static const struct platform_features nhm_features = {
3dd0e754 415 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 416 .has_nhm_msrs = 1,
71e84129 417 .bclk_freq = BCLK_133MHZ,
6f1935c0 418 .supported_cstates = CC1 | CC3 | CC6 | PC3 | PC6,
3989fc89 419 .cst_limit = CST_LIMIT_NHM,
10d85d85 420 .trl_msrs = TRL_BASE,
45232ab1
ZR
421};
422
423static const struct platform_features nhx_features = {
3dd0e754 424 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 425 .has_nhm_msrs = 1,
71e84129 426 .bclk_freq = BCLK_133MHZ,
6f1935c0 427 .supported_cstates = CC1 | CC3 | CC6 | PC3 | PC6,
3989fc89 428 .cst_limit = CST_LIMIT_NHM,
45232ab1
ZR
429};
430
431static const struct platform_features snb_features = {
778fc34a 432 .has_msr_misc_feature_control = 1,
3dd0e754 433 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 434 .has_nhm_msrs = 1,
71e84129 435 .bclk_freq = BCLK_100MHZ,
192cbf04 436 .supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7,
3989fc89 437 .cst_limit = CST_LIMIT_SNB,
10d85d85 438 .trl_msrs = TRL_BASE,
86ba263d 439 .rapl_msrs = RAPL_PKG | RAPL_CORE_ALL | RAPL_GFX | RAPL_PKG_POWER_INFO,
45232ab1
ZR
440};
441
442static const struct platform_features snx_features = {
778fc34a 443 .has_msr_misc_feature_control = 1,
3dd0e754 444 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 445 .has_nhm_msrs = 1,
71e84129 446 .bclk_freq = BCLK_100MHZ,
192cbf04 447 .supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7,
3989fc89 448 .cst_limit = CST_LIMIT_SNB,
10d85d85 449 .trl_msrs = TRL_BASE,
86ba263d 450 .rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM_ALL,
45232ab1
ZR
451};
452
453static const struct platform_features ivb_features = {
778fc34a 454 .has_msr_misc_feature_control = 1,
3dd0e754 455 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 456 .has_nhm_msrs = 1,
a61c9cb4 457 .has_config_tdp = 1,
71e84129 458 .bclk_freq = BCLK_100MHZ,
192cbf04 459 .supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7,
3989fc89 460 .cst_limit = CST_LIMIT_SNB,
10d85d85 461 .trl_msrs = TRL_BASE,
86ba263d 462 .rapl_msrs = RAPL_PKG | RAPL_CORE_ALL | RAPL_GFX | RAPL_PKG_POWER_INFO,
45232ab1
ZR
463};
464
465static const struct platform_features ivx_features = {
778fc34a 466 .has_msr_misc_feature_control = 1,
3dd0e754 467 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 468 .has_nhm_msrs = 1,
71e84129 469 .bclk_freq = BCLK_100MHZ,
192cbf04 470 .supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7,
3989fc89 471 .cst_limit = CST_LIMIT_SNB,
10d85d85 472 .trl_msrs = TRL_BASE | TRL_LIMIT1,
86ba263d 473 .rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM_ALL,
45232ab1
ZR
474};
475
476static const struct platform_features hsw_features = {
778fc34a 477 .has_msr_misc_feature_control = 1,
3dd0e754 478 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 479 .has_nhm_msrs = 1,
a61c9cb4 480 .has_config_tdp = 1,
71e84129 481 .bclk_freq = BCLK_100MHZ,
192cbf04 482 .supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7,
3989fc89 483 .cst_limit = CST_LIMIT_HSW,
10d85d85 484 .trl_msrs = TRL_BASE,
0c057cf7 485 .plr_msrs = PLR_CORE | PLR_GFX | PLR_RING,
86ba263d 486 .rapl_msrs = RAPL_PKG | RAPL_CORE_ALL | RAPL_GFX | RAPL_PKG_POWER_INFO,
45232ab1
ZR
487};
488
489static const struct platform_features hsx_features = {
778fc34a 490 .has_msr_misc_feature_control = 1,
3dd0e754 491 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 492 .has_nhm_msrs = 1,
a61c9cb4 493 .has_config_tdp = 1,
71e84129 494 .bclk_freq = BCLK_100MHZ,
192cbf04 495 .supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7,
3989fc89 496 .cst_limit = CST_LIMIT_HSW,
10d85d85 497 .trl_msrs = TRL_BASE | TRL_LIMIT1 | TRL_LIMIT2,
0c057cf7 498 .plr_msrs = PLR_CORE | PLR_RING,
86ba263d 499 .rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL,
9e6f3515 500 .has_fixed_rapl_unit = 1,
45232ab1
ZR
501};
502
503static const struct platform_features hswl_features = {
778fc34a 504 .has_msr_misc_feature_control = 1,
3dd0e754 505 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 506 .has_nhm_msrs = 1,
a61c9cb4 507 .has_config_tdp = 1,
71e84129 508 .bclk_freq = BCLK_100MHZ,
4d2c95d4 509 .supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7 | PC8 | PC9 | PC10,
3989fc89 510 .cst_limit = CST_LIMIT_HSW,
10d85d85 511 .trl_msrs = TRL_BASE,
0c057cf7 512 .plr_msrs = PLR_CORE | PLR_GFX | PLR_RING,
86ba263d 513 .rapl_msrs = RAPL_PKG | RAPL_CORE_ALL | RAPL_GFX | RAPL_PKG_POWER_INFO,
45232ab1
ZR
514};
515
516static const struct platform_features hswg_features = {
778fc34a 517 .has_msr_misc_feature_control = 1,
3dd0e754 518 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 519 .has_nhm_msrs = 1,
a61c9cb4 520 .has_config_tdp = 1,
71e84129 521 .bclk_freq = BCLK_100MHZ,
192cbf04 522 .supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7,
3989fc89 523 .cst_limit = CST_LIMIT_HSW,
10d85d85 524 .trl_msrs = TRL_BASE,
0c057cf7 525 .plr_msrs = PLR_CORE | PLR_GFX | PLR_RING,
86ba263d 526 .rapl_msrs = RAPL_PKG | RAPL_CORE_ALL | RAPL_GFX | RAPL_PKG_POWER_INFO,
45232ab1
ZR
527};
528
529static const struct platform_features bdw_features = {
778fc34a 530 .has_msr_misc_feature_control = 1,
3dd0e754 531 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 532 .has_nhm_msrs = 1,
a61c9cb4 533 .has_config_tdp = 1,
71e84129 534 .bclk_freq = BCLK_100MHZ,
4d2c95d4 535 .supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7 | PC8 | PC9 | PC10,
3989fc89 536 .cst_limit = CST_LIMIT_HSW,
10d85d85 537 .trl_msrs = TRL_BASE,
86ba263d 538 .rapl_msrs = RAPL_PKG | RAPL_CORE_ALL | RAPL_GFX | RAPL_PKG_POWER_INFO,
45232ab1
ZR
539};
540
541static const struct platform_features bdwg_features = {
778fc34a 542 .has_msr_misc_feature_control = 1,
3dd0e754 543 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 544 .has_nhm_msrs = 1,
a61c9cb4 545 .has_config_tdp = 1,
71e84129 546 .bclk_freq = BCLK_100MHZ,
192cbf04 547 .supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7,
3989fc89 548 .cst_limit = CST_LIMIT_HSW,
10d85d85 549 .trl_msrs = TRL_BASE,
86ba263d 550 .rapl_msrs = RAPL_PKG | RAPL_CORE_ALL | RAPL_GFX | RAPL_PKG_POWER_INFO,
45232ab1
ZR
551};
552
553static const struct platform_features bdx_features = {
778fc34a 554 .has_msr_misc_feature_control = 1,
3dd0e754 555 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 556 .has_nhm_msrs = 1,
a61c9cb4 557 .has_config_tdp = 1,
71e84129 558 .bclk_freq = BCLK_100MHZ,
11096948 559 .supported_cstates = CC1 | CC3 | CC6 | PC2 | PC3 | PC6,
3989fc89 560 .cst_limit = CST_LIMIT_HSW,
d90120bf 561 .has_cst_auto_convension = 1,
10d85d85 562 .trl_msrs = TRL_BASE,
86ba263d 563 .rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL,
9e6f3515 564 .has_fixed_rapl_unit = 1,
45232ab1
ZR
565};
566
567static const struct platform_features skl_features = {
778fc34a 568 .has_msr_misc_feature_control = 1,
3dd0e754 569 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 570 .has_nhm_msrs = 1,
a61c9cb4 571 .has_config_tdp = 1,
71e84129 572 .bclk_freq = BCLK_100MHZ,
a5d1ab93 573 .crystal_freq = 24000000,
4d2c95d4 574 .supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7 | PC8 | PC9 | PC10,
3989fc89 575 .cst_limit = CST_LIMIT_HSW,
10d85d85 576 .trl_msrs = TRL_BASE,
d8e1623b 577 .tcc_offset_bits = 6,
86ba263d 578 .rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_GFX,
485a017c 579 .enable_tsc_tweak = 1,
45232ab1
ZR
580};
581
582static const struct platform_features cnl_features = {
778fc34a 583 .has_msr_misc_feature_control = 1,
3dd0e754 584 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 585 .has_nhm_msrs = 1,
a61c9cb4 586 .has_config_tdp = 1,
71e84129 587 .bclk_freq = BCLK_100MHZ,
4d2c95d4 588 .supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7 | PC8 | PC9 | PC10,
3989fc89 589 .cst_limit = CST_LIMIT_HSW,
10d85d85 590 .trl_msrs = TRL_BASE,
d8e1623b 591 .tcc_offset_bits = 6,
86ba263d 592 .rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_GFX,
485a017c 593 .enable_tsc_tweak = 1,
45232ab1
ZR
594};
595
596static const struct platform_features skx_features = {
778fc34a 597 .has_msr_misc_feature_control = 1,
3dd0e754 598 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 599 .has_nhm_msrs = 1,
a61c9cb4 600 .has_config_tdp = 1,
71e84129 601 .bclk_freq = BCLK_100MHZ,
24d16bec 602 .supported_cstates = CC1 | CC6 | PC2 | PC6,
3989fc89 603 .cst_limit = CST_LIMIT_SKX,
d90120bf 604 .has_cst_auto_convension = 1,
10d85d85 605 .trl_msrs = TRL_BASE | TRL_CORECOUNT,
86ba263d 606 .rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL,
9e6f3515 607 .has_fixed_rapl_unit = 1,
45232ab1
ZR
608};
609
610static const struct platform_features icx_features = {
778fc34a 611 .has_msr_misc_feature_control = 1,
3dd0e754 612 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 613 .has_nhm_msrs = 1,
a61c9cb4 614 .has_config_tdp = 1,
71e84129 615 .bclk_freq = BCLK_100MHZ,
24d16bec 616 .supported_cstates = CC1 | CC6 | PC2 | PC6,
3989fc89 617 .cst_limit = CST_LIMIT_ICX,
10d85d85 618 .trl_msrs = TRL_BASE | TRL_CORECOUNT,
86ba263d 619 .rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL,
9e6f3515 620 .has_fixed_rapl_unit = 1,
45232ab1
ZR
621};
622
623static const struct platform_features spr_features = {
778fc34a 624 .has_msr_misc_feature_control = 1,
3dd0e754 625 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 626 .has_nhm_msrs = 1,
a61c9cb4 627 .has_config_tdp = 1,
71e84129 628 .bclk_freq = BCLK_100MHZ,
24d16bec 629 .supported_cstates = CC1 | CC6 | PC2 | PC6,
3989fc89 630 .cst_limit = CST_LIMIT_SKX,
10d85d85 631 .trl_msrs = TRL_BASE | TRL_CORECOUNT,
86ba263d 632 .rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL,
45232ab1
ZR
633};
634
635static const struct platform_features slv_features = {
fcfa1ce0 636 .has_nhm_msrs = 1,
71e84129 637 .bclk_freq = BCLK_SLV,
ff206149 638 .supported_cstates = CC1 | CC3 | CC6 | PC6,
3989fc89 639 .cst_limit = CST_LIMIT_SLV,
10d85d85 640 .trl_msrs = TRL_ATOM,
86ba263d 641 .rapl_msrs = RAPL_PKG | RAPL_CORE,
6d35b8c4 642 .has_rapl_divisor = 1,
7c604093 643 .rapl_quirk_tdp = 30,
45232ab1
ZR
644};
645
646static const struct platform_features slvd_features = {
3dd0e754 647 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 648 .has_nhm_msrs = 1,
71e84129 649 .bclk_freq = BCLK_SLV,
6f1935c0 650 .supported_cstates = CC1 | CC3 | CC6 | PC3 | PC6,
3989fc89 651 .cst_limit = CST_LIMIT_SLV,
10d85d85 652 .trl_msrs = TRL_BASE,
86ba263d 653 .rapl_msrs = RAPL_PKG | RAPL_CORE,
7c604093 654 .rapl_quirk_tdp = 30,
45232ab1
ZR
655};
656
657static const struct platform_features amt_features = {
fcfa1ce0 658 .has_nhm_msrs = 1,
71e84129 659 .bclk_freq = BCLK_133MHZ,
6f1935c0 660 .supported_cstates = CC1 | CC3 | CC6 | PC3 | PC6,
3989fc89 661 .cst_limit = CST_LIMIT_AMT,
10d85d85 662 .trl_msrs = TRL_BASE,
45232ab1
ZR
663};
664
665static const struct platform_features gmt_features = {
3dd0e754 666 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 667 .has_nhm_msrs = 1,
71e84129 668 .bclk_freq = BCLK_100MHZ,
a5d1ab93 669 .crystal_freq = 19200000,
4d2c95d4 670 .supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7 | PC8 | PC9 | PC10,
3989fc89 671 .cst_limit = CST_LIMIT_GMT,
10d85d85 672 .trl_msrs = TRL_BASE | TRL_CORECOUNT,
86ba263d 673 .rapl_msrs = RAPL_PKG | RAPL_PKG_POWER_INFO,
45232ab1
ZR
674};
675
676static const struct platform_features gmtd_features = {
3dd0e754 677 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 678 .has_nhm_msrs = 1,
71e84129 679 .bclk_freq = BCLK_100MHZ,
a5d1ab93 680 .crystal_freq = 25000000,
8e20ced0 681 .supported_cstates = CC1 | CC6 | PC2 | PC6,
3989fc89 682 .cst_limit = CST_LIMIT_GMT,
10d85d85 683 .trl_msrs = TRL_BASE | TRL_CORECOUNT,
86ba263d 684 .rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL | RAPL_CORE_ENERGY_STATUS,
45232ab1
ZR
685};
686
687static const struct platform_features gmtp_features = {
3dd0e754 688 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 689 .has_nhm_msrs = 1,
71e84129 690 .bclk_freq = BCLK_100MHZ,
a5d1ab93 691 .crystal_freq = 19200000,
4d2c95d4 692 .supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7 | PC8 | PC9 | PC10,
3989fc89 693 .cst_limit = CST_LIMIT_GMT,
10d85d85 694 .trl_msrs = TRL_BASE,
86ba263d 695 .rapl_msrs = RAPL_PKG | RAPL_PKG_POWER_INFO,
45232ab1
ZR
696};
697
698static const struct platform_features tmt_features = {
3dd0e754 699 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 700 .has_nhm_msrs = 1,
71e84129 701 .bclk_freq = BCLK_100MHZ,
4d2c95d4 702 .supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7 | PC8 | PC9 | PC10,
3989fc89 703 .cst_limit = CST_LIMIT_GMT,
10d85d85 704 .trl_msrs = TRL_BASE,
86ba263d 705 .rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_GFX,
485a017c 706 .enable_tsc_tweak = 1,
45232ab1
ZR
707};
708
709static const struct platform_features tmtd_features = {
3dd0e754 710 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 711 .has_nhm_msrs = 1,
71e84129 712 .bclk_freq = BCLK_100MHZ,
3d982ac0 713 .supported_cstates = CC1 | CC6,
3989fc89 714 .cst_limit = CST_LIMIT_GMT,
10d85d85 715 .trl_msrs = TRL_BASE | TRL_CORECOUNT,
86ba263d 716 .rapl_msrs = RAPL_PKG_ALL,
45232ab1
ZR
717};
718
719static const struct platform_features knl_features = {
3dd0e754 720 .has_msr_misc_pwr_mgmt = 1,
fcfa1ce0 721 .has_nhm_msrs = 1,
a61c9cb4 722 .has_config_tdp = 1,
71e84129 723 .bclk_freq = BCLK_100MHZ,
6f1935c0 724 .supported_cstates = CC1 | CC3 | CC6 | PC3 | PC6,
3989fc89 725 .cst_limit = CST_LIMIT_KNL,
10d85d85 726 .trl_msrs = TRL_KNL,
86ba263d 727 .rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL,
9e6f3515 728 .has_fixed_rapl_unit = 1,
45232ab1
ZR
729};
730
731static const struct platform_features default_features = {
732};
733
734static const struct platform_features amd_features = {
735};
736
86ba263d
ZR
737static const struct platform_features amd_features_with_rapl = {
738 .rapl_msrs = RAPL_AMD_F17H,
e338831b 739 .has_per_core_rapl = 1,
7c604093 740 .rapl_quirk_tdp = 280, /* This is the max stock TDP of HEDT/Server Fam17h+ chips */
86ba263d
ZR
741};
742
45232ab1
ZR
743static const struct platform_data turbostat_pdata[] = {
744 { INTEL_FAM6_NEHALEM, &nhm_features },
745 { INTEL_FAM6_NEHALEM_G, &nhm_features },
746 { INTEL_FAM6_NEHALEM_EP, &nhm_features },
747 { INTEL_FAM6_NEHALEM_EX, &nhx_features },
748 { INTEL_FAM6_WESTMERE, &nhm_features },
749 { INTEL_FAM6_WESTMERE_EP, &nhm_features },
750 { INTEL_FAM6_WESTMERE_EX, &nhx_features },
751 { INTEL_FAM6_SANDYBRIDGE, &snb_features },
752 { INTEL_FAM6_SANDYBRIDGE_X, &snx_features },
753 { INTEL_FAM6_IVYBRIDGE, &ivb_features },
754 { INTEL_FAM6_IVYBRIDGE_X, &ivx_features },
755 { INTEL_FAM6_HASWELL, &hsw_features },
756 { INTEL_FAM6_HASWELL_X, &hsx_features },
757 { INTEL_FAM6_HASWELL_L, &hswl_features },
758 { INTEL_FAM6_HASWELL_G, &hswg_features },
759 { INTEL_FAM6_BROADWELL, &bdw_features },
760 { INTEL_FAM6_BROADWELL_G, &bdwg_features },
761 { INTEL_FAM6_BROADWELL_X, &bdx_features },
762 { INTEL_FAM6_BROADWELL_D, &bdx_features },
763 { INTEL_FAM6_SKYLAKE_L, &skl_features },
764 { INTEL_FAM6_SKYLAKE, &skl_features },
765 { INTEL_FAM6_SKYLAKE_X, &skx_features },
766 { INTEL_FAM6_KABYLAKE_L, &skl_features },
767 { INTEL_FAM6_KABYLAKE, &skl_features },
768 { INTEL_FAM6_COMETLAKE, &skl_features },
769 { INTEL_FAM6_COMETLAKE_L, &skl_features },
770 { INTEL_FAM6_CANNONLAKE_L, &cnl_features },
771 { INTEL_FAM6_ICELAKE_X, &icx_features },
772 { INTEL_FAM6_ICELAKE_D, &icx_features },
773 { INTEL_FAM6_ICELAKE_L, &cnl_features },
774 { INTEL_FAM6_ICELAKE_NNPI, &cnl_features },
775 { INTEL_FAM6_ROCKETLAKE, &cnl_features },
776 { INTEL_FAM6_TIGERLAKE_L, &cnl_features },
777 { INTEL_FAM6_TIGERLAKE, &cnl_features },
778 { INTEL_FAM6_SAPPHIRERAPIDS_X, &spr_features },
779 { INTEL_FAM6_EMERALDRAPIDS_X, &spr_features },
780 { INTEL_FAM6_LAKEFIELD, &cnl_features },
781 { INTEL_FAM6_ALDERLAKE, &cnl_features },
782 { INTEL_FAM6_ALDERLAKE_L, &cnl_features },
783 { INTEL_FAM6_RAPTORLAKE, &cnl_features },
784 { INTEL_FAM6_RAPTORLAKE_P, &cnl_features },
785 { INTEL_FAM6_RAPTORLAKE_S, &cnl_features },
786 { INTEL_FAM6_METEORLAKE, &cnl_features },
787 { INTEL_FAM6_METEORLAKE_L, &cnl_features },
788 { INTEL_FAM6_ATOM_SILVERMONT, &slv_features },
789 { INTEL_FAM6_ATOM_SILVERMONT_D, &slvd_features },
790 { INTEL_FAM6_ATOM_AIRMONT, &amt_features },
791 { INTEL_FAM6_ATOM_GOLDMONT, &gmt_features },
792 { INTEL_FAM6_ATOM_GOLDMONT_D, &gmtd_features },
793 { INTEL_FAM6_ATOM_GOLDMONT_PLUS, &gmtp_features },
794 { INTEL_FAM6_ATOM_TREMONT_D, &tmtd_features },
795 { INTEL_FAM6_ATOM_TREMONT, &tmt_features },
796 { INTEL_FAM6_ATOM_TREMONT_L, &tmt_features },
797 { INTEL_FAM6_ATOM_GRACEMONT, &cnl_features },
798 { INTEL_FAM6_XEON_PHI_KNL, &knl_features },
799 { INTEL_FAM6_XEON_PHI_KNM, &knl_features },
800 /*
801 * Missing support for
802 * INTEL_FAM6_ICELAKE
803 * INTEL_FAM6_ATOM_SILVERMONT_MID
804 * INTEL_FAM6_ATOM_AIRMONT_MID
805 * INTEL_FAM6_ATOM_AIRMONT_NP
806 */
807 { 0, NULL },
808};
809
810static const struct platform_features *platform;
811
812void probe_platform_features(unsigned int family, unsigned int model)
813{
814 int i;
815
816 if (authentic_amd || hygon_genuine) {
817 platform = &amd_features;
86ba263d
ZR
818
819 if (max_extended_level >= 0x80000007) {
820 unsigned int eax, ebx, ecx, edx;
821
822 __cpuid(0x80000007, eax, ebx, ecx, edx);
823 /* RAPL (Fam 17h+) */
e338831b 824 if ((edx & (1 << 14)) && family >= 0x17)
86ba263d 825 platform = &amd_features_with_rapl;
86ba263d 826 }
45232ab1
ZR
827 return;
828 }
829
830 platform = &default_features;
831
832 if (!genuine_intel || family != 6)
833 return;
834
835 for (i = 0; turbostat_pdata[i].features; i++) {
836 if (turbostat_pdata[i].model == model) {
837 platform = turbostat_pdata[i].features;
838 return;
839 }
840 }
841}
842
843/* Model specific support End */
844
889facbe
LB
845#define TJMAX_DEFAULT 100
846
9392bd98
CW
847/* MSRs that are not yet in the kernel-provided header. */
848#define MSR_RAPL_PWR_UNIT 0xc0010299
849#define MSR_CORE_ENERGY_STAT 0xc001029a
850#define MSR_PKG_ENERGY_STAT 0xc001029b
851
889facbe 852#define MAX(a, b) ((a) > (b) ? (a) : (b))
103a8fea 853
103a8fea
LB
854int backwards_count;
855char *progname;
103a8fea 856
1ef7d21a
LB
857#define CPU_SUBSET_MAXCPUS 1024 /* need to use before probe... */
858cpu_set_t *cpu_present_set, *cpu_affinity_set, *cpu_subset;
859size_t cpu_present_setsize, cpu_affinity_setsize, cpu_subset_size;
0748eaf0
LB
860#define MAX_ADDED_COUNTERS 8
861#define MAX_ADDED_THREAD_COUNTERS 24
0e2d8f05 862#define BITMASK_SIZE 32
c98d5d94
LB
863
864struct thread_data {
f4fdf2b4
LB
865 struct timeval tv_begin;
866 struct timeval tv_end;
d4794f25 867 struct timeval tv_delta;
c98d5d94
LB
868 unsigned long long tsc;
869 unsigned long long aperf;
870 unsigned long long mperf;
144b44b1 871 unsigned long long c1;
2af4f9b8 872 unsigned long long instr_count;
1b439f01 873 unsigned long long irq_count;
1ed51011 874 unsigned int smi_count;
c98d5d94 875 unsigned int cpu_id;
4c2122d4
LB
876 unsigned int apic_id;
877 unsigned int x2apic_id;
c98d5d94 878 unsigned int flags;
7ab5ff49 879 bool is_atom;
c98d5d94
LB
880#define CPU_IS_FIRST_THREAD_IN_CORE 0x2
881#define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4
0748eaf0 882 unsigned long long counter[MAX_ADDED_THREAD_COUNTERS];
c98d5d94
LB
883} *thread_even, *thread_odd;
884
885struct core_data {
886 unsigned long long c3;
887 unsigned long long c6;
888 unsigned long long c7;
0539ba11 889 unsigned long long mc6_us; /* duplicate as per-core for now, even though per module */
889facbe 890 unsigned int core_temp_c;
9392bd98 891 unsigned int core_energy; /* MSR_CORE_ENERGY_STAT */
c98d5d94 892 unsigned int core_id;
eae97e05 893 unsigned long long core_throt_cnt;
678a3bd1 894 unsigned long long counter[MAX_ADDED_COUNTERS];
c98d5d94
LB
895} *core_even, *core_odd;
896
897struct pkg_data {
898 unsigned long long pc2;
899 unsigned long long pc3;
900 unsigned long long pc6;
901 unsigned long long pc7;
ca58710f
KCA
902 unsigned long long pc8;
903 unsigned long long pc9;
904 unsigned long long pc10;
be0e54c4
LB
905 unsigned long long cpu_lpi;
906 unsigned long long sys_lpi;
0b2bb692
LB
907 unsigned long long pkg_wtd_core_c0;
908 unsigned long long pkg_any_core_c0;
909 unsigned long long pkg_any_gfxe_c0;
910 unsigned long long pkg_both_core_gfxe_c0;
9185e988 911 long long gfx_rc6_ms;
27d47356 912 unsigned int gfx_mhz;
b4b91569 913 unsigned int gfx_act_mhz;
c98d5d94 914 unsigned int package_id;
7c2ccc50
CY
915 unsigned long long energy_pkg; /* MSR_PKG_ENERGY_STATUS */
916 unsigned long long energy_dram; /* MSR_DRAM_ENERGY_STATUS */
917 unsigned long long energy_cores; /* MSR_PP0_ENERGY_STATUS */
918 unsigned long long energy_gfx; /* MSR_PP1_ENERGY_STATUS */
919 unsigned long long rapl_pkg_perf_status; /* MSR_PKG_PERF_STATUS */
920 unsigned long long rapl_dram_perf_status; /* MSR_DRAM_PERF_STATUS */
889facbe 921 unsigned int pkg_temp_c;
a5c6d65d 922 unsigned int uncore_mhz;
678a3bd1 923 unsigned long long counter[MAX_ADDED_COUNTERS];
c98d5d94
LB
924} *package_even, *package_odd;
925
926#define ODD_COUNTERS thread_odd, core_odd, package_odd
927#define EVEN_COUNTERS thread_even, core_even, package_even
928
40f5cfe7
PB
929#define GET_THREAD(thread_base, thread_no, core_no, node_no, pkg_no) \
930 ((thread_base) + \
931 ((pkg_no) * \
932 topo.nodes_per_pkg * topo.cores_per_node * topo.threads_per_core) + \
933 ((node_no) * topo.cores_per_node * topo.threads_per_core) + \
934 ((core_no) * topo.threads_per_core) + \
935 (thread_no))
936
937#define GET_CORE(core_base, core_no, node_no, pkg_no) \
938 ((core_base) + \
939 ((pkg_no) * topo.nodes_per_pkg * topo.cores_per_node) + \
940 ((node_no) * topo.cores_per_node) + \
941 (core_no))
942
c98d5d94
LB
943#define GET_PKG(pkg_base, pkg_no) (pkg_base + pkg_no)
944
87e15da9
CY
945/*
946 * The accumulated sum of MSR is defined as a monotonic
947 * increasing MSR, it will be accumulated periodically,
948 * despite its register's bit width.
949 */
950enum {
951 IDX_PKG_ENERGY,
952 IDX_DRAM_ENERGY,
953 IDX_PP0_ENERGY,
954 IDX_PP1_ENERGY,
955 IDX_PKG_PERF,
956 IDX_DRAM_PERF,
957 IDX_COUNT,
958};
959
960int get_msr_sum(int cpu, off_t offset, unsigned long long *msr);
961
962struct msr_sum_array {
963 /* get_msr_sum() = sum + (get_msr() - last) */
964 struct {
1b439f01 965 /*The accumulated MSR value is updated by the timer */
87e15da9 966 unsigned long long sum;
1b439f01 967 /*The MSR footprint recorded in last timer */
87e15da9
CY
968 unsigned long long last;
969 } entries[IDX_COUNT];
970};
971
972/* The percpu MSR sum array.*/
973struct msr_sum_array *per_cpu_msr_sum;
974
13a779de 975off_t idx_to_offset(int idx)
87e15da9 976{
13a779de 977 off_t offset;
87e15da9
CY
978
979 switch (idx) {
980 case IDX_PKG_ENERGY:
86ba263d 981 if (platform->rapl_msrs & RAPL_AMD_F17H)
301b1d3a
BN
982 offset = MSR_PKG_ENERGY_STAT;
983 else
984 offset = MSR_PKG_ENERGY_STATUS;
87e15da9
CY
985 break;
986 case IDX_DRAM_ENERGY:
987 offset = MSR_DRAM_ENERGY_STATUS;
988 break;
989 case IDX_PP0_ENERGY:
990 offset = MSR_PP0_ENERGY_STATUS;
991 break;
992 case IDX_PP1_ENERGY:
993 offset = MSR_PP1_ENERGY_STATUS;
994 break;
995 case IDX_PKG_PERF:
996 offset = MSR_PKG_PERF_STATUS;
997 break;
998 case IDX_DRAM_PERF:
999 offset = MSR_DRAM_PERF_STATUS;
1000 break;
1001 default:
1002 offset = -1;
1003 }
1004 return offset;
1005}
1006
13a779de 1007int offset_to_idx(off_t offset)
87e15da9
CY
1008{
1009 int idx;
1010
1011 switch (offset) {
1012 case MSR_PKG_ENERGY_STATUS:
301b1d3a 1013 case MSR_PKG_ENERGY_STAT:
87e15da9
CY
1014 idx = IDX_PKG_ENERGY;
1015 break;
1016 case MSR_DRAM_ENERGY_STATUS:
1017 idx = IDX_DRAM_ENERGY;
1018 break;
1019 case MSR_PP0_ENERGY_STATUS:
1020 idx = IDX_PP0_ENERGY;
1021 break;
1022 case MSR_PP1_ENERGY_STATUS:
1023 idx = IDX_PP1_ENERGY;
1024 break;
1025 case MSR_PKG_PERF_STATUS:
1026 idx = IDX_PKG_PERF;
1027 break;
1028 case MSR_DRAM_PERF_STATUS:
1029 idx = IDX_DRAM_PERF;
1030 break;
1031 default:
1032 idx = -1;
1033 }
1034 return idx;
1035}
1036
1037int idx_valid(int idx)
1038{
1039 switch (idx) {
1040 case IDX_PKG_ENERGY:
86ba263d 1041 return platform->rapl_msrs & (RAPL_PKG | RAPL_AMD_F17H);
87e15da9 1042 case IDX_DRAM_ENERGY:
86ba263d 1043 return platform->rapl_msrs & RAPL_DRAM;
87e15da9 1044 case IDX_PP0_ENERGY:
86ba263d 1045 return platform->rapl_msrs & RAPL_CORE_ENERGY_STATUS;
87e15da9 1046 case IDX_PP1_ENERGY:
86ba263d 1047 return platform->rapl_msrs & RAPL_GFX;
87e15da9 1048 case IDX_PKG_PERF:
86ba263d 1049 return platform->rapl_msrs & RAPL_PKG_PERF_STATUS;
87e15da9 1050 case IDX_DRAM_PERF:
86ba263d 1051 return platform->rapl_msrs & RAPL_DRAM_PERF_STATUS;
87e15da9
CY
1052 default:
1053 return 0;
1054 }
1055}
1b439f01 1056
388e9c81 1057struct sys_counters {
678a3bd1
LB
1058 unsigned int added_thread_counters;
1059 unsigned int added_core_counters;
1060 unsigned int added_package_counters;
388e9c81
LB
1061 struct msr_counter *tp;
1062 struct msr_counter *cp;
1063 struct msr_counter *pp;
1064} sys;
1065
c98d5d94
LB
1066struct system_summary {
1067 struct thread_data threads;
1068 struct core_data cores;
1069 struct pkg_data packages;
388e9c81 1070} average;
c98d5d94 1071
0e2d8f05
LB
1072struct cpu_topology {
1073 int physical_package_id;
6de68fe1 1074 int die_id;
0e2d8f05 1075 int logical_cpu_id;
ef605741
PB
1076 int physical_node_id;
1077 int logical_node_id; /* 0-based count within the package */
0e2d8f05 1078 int physical_core_id;
8cb48b32 1079 int thread_id;
1b439f01 1080 cpu_set_t *put_ids; /* Processing Unit/Thread IDs */
0e2d8f05 1081} *cpus;
c98d5d94
LB
1082
1083struct topo_params {
1084 int num_packages;
6de68fe1 1085 int num_die;
c98d5d94
LB
1086 int num_cpus;
1087 int num_cores;
1088 int max_cpu_num;
ef605741 1089 int max_node_num;
70a9c6e8
PB
1090 int nodes_per_pkg;
1091 int cores_per_node;
1092 int threads_per_core;
c98d5d94
LB
1093} topo;
1094
1095struct timeval tv_even, tv_odd, tv_delta;
1096
1b439f01 1097int *irq_column_2_cpu; /* /proc/interrupts column numbers */
562a2d37
LB
1098int *irqs_per_cpu; /* indexed by cpu_num */
1099
c98d5d94
LB
1100void setup_all_buffers(void);
1101
1f81c5ef
LB
1102char *sys_lpi_file;
1103char *sys_lpi_file_sysfs = "/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us";
1104char *sys_lpi_file_debugfs = "/sys/kernel/debug/pmc_core/slp_s0_residency_usec";
1105
c98d5d94 1106int cpu_is_not_present(int cpu)
d15cf7c1 1107{
c98d5d94 1108 return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set);
d15cf7c1 1109}
1b439f01 1110
88c3281f 1111/*
c98d5d94
LB
1112 * run func(thread, core, package) in topology order
1113 * skip non-present cpus
88c3281f 1114 */
c98d5d94 1115
1b439f01
LB
1116int for_all_cpus(int (func) (struct thread_data *, struct core_data *, struct pkg_data *),
1117 struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base)
88c3281f 1118{
40f5cfe7 1119 int retval, pkg_no, core_no, thread_no, node_no;
d15cf7c1 1120
c98d5d94 1121 for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) {
df2f677d
LB
1122 for (node_no = 0; node_no < topo.nodes_per_pkg; node_no++) {
1123 for (core_no = 0; core_no < topo.cores_per_node; ++core_no) {
1b439f01 1124 for (thread_no = 0; thread_no < topo.threads_per_core; ++thread_no) {
40f5cfe7
PB
1125 struct thread_data *t;
1126 struct core_data *c;
1127 struct pkg_data *p;
1128
1b439f01 1129 t = GET_THREAD(thread_base, thread_no, core_no, node_no, pkg_no);
40f5cfe7
PB
1130
1131 if (cpu_is_not_present(t->cpu_id))
1132 continue;
1133
1b439f01 1134 c = GET_CORE(core_base, core_no, node_no, pkg_no);
40f5cfe7
PB
1135 p = GET_PKG(pkg_base, pkg_no);
1136
1137 retval = func(t, c, p);
1138 if (retval)
1139 return retval;
1140 }
c98d5d94
LB
1141 }
1142 }
1143 }
1144 return 0;
88c3281f
LB
1145}
1146
1147int cpu_migrate(int cpu)
1148{
c98d5d94
LB
1149 CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
1150 CPU_SET_S(cpu, cpu_affinity_setsize, cpu_affinity_set);
1151 if (sched_setaffinity(0, cpu_affinity_setsize, cpu_affinity_set) == -1)
88c3281f
LB
1152 return -1;
1153 else
1154 return 0;
1155}
1b439f01 1156
36229897 1157int get_msr_fd(int cpu)
103a8fea 1158{
103a8fea
LB
1159 char pathname[32];
1160 int fd;
1161
36229897
LB
1162 fd = fd_percpu[cpu];
1163
1164 if (fd)
1165 return fd;
1166
103a8fea
LB
1167 sprintf(pathname, "/dev/cpu/%d/msr", cpu);
1168 fd = open(pathname, O_RDONLY);
15aaa346 1169 if (fd < 0)
98481e79 1170 err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, or run as root", pathname);
103a8fea 1171
36229897
LB
1172 fd_percpu[cpu] = fd;
1173
1174 return fd;
1175}
1176
2af4f9b8
LB
1177static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, int group_fd, unsigned long flags)
1178{
1179 return syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
1180}
1181
1182static int perf_instr_count_open(int cpu_num)
1183{
1184 struct perf_event_attr pea;
1185 int fd;
1186
1187 memset(&pea, 0, sizeof(struct perf_event_attr));
1188 pea.type = PERF_TYPE_HARDWARE;
1189 pea.size = sizeof(struct perf_event_attr);
1190 pea.config = PERF_COUNT_HW_INSTRUCTIONS;
1191
1192 /* counter for cpu_num, including user + kernel and all processes */
1193 fd = perf_event_open(&pea, -1, cpu_num, -1, 0);
164d7a96 1194 if (fd == -1) {
de7839ee 1195 warnx("capget(CAP_PERFMON) failed, try \"# setcap cap_sys_admin=ep %s\"", progname);
164d7a96
LB
1196 BIC_NOT_PRESENT(BIC_IPC);
1197 }
2af4f9b8
LB
1198
1199 return fd;
1200}
1201
1202int get_instr_count_fd(int cpu)
1203{
1204 if (fd_instr_count_percpu[cpu])
1205 return fd_instr_count_percpu[cpu];
1206
1207 fd_instr_count_percpu[cpu] = perf_instr_count_open(cpu);
1208
1209 return fd_instr_count_percpu[cpu];
1210}
1211
36229897
LB
1212int get_msr(int cpu, off_t offset, unsigned long long *msr)
1213{
1214 ssize_t retval;
1215
1216 retval = pread(get_msr_fd(cpu), msr, sizeof(*msr), offset);
15aaa346 1217
98481e79 1218 if (retval != sizeof *msr)
cf4cbe53 1219 err(-1, "cpu%d: msr offset 0x%llx read failed", cpu, (unsigned long long)offset);
15aaa346
LB
1220
1221 return 0;
103a8fea
LB
1222}
1223
dd778a5e 1224#define MAX_DEFERRED 16
0fc521bc 1225char *deferred_add_names[MAX_DEFERRED];
dd778a5e 1226char *deferred_skip_names[MAX_DEFERRED];
0fc521bc 1227int deferred_add_index;
dd778a5e
LB
1228int deferred_skip_index;
1229
1230/*
1231 * HIDE_LIST - hide this list of counters, show the rest [default]
1232 * SHOW_LIST - show this list of counters, hide the rest
1233 */
1234enum show_hide_mode { SHOW_LIST, HIDE_LIST } global_show_hide_mode = HIDE_LIST;
1235
1236void help(void)
1237{
1238 fprintf(outf,
1b439f01
LB
1239 "Usage: turbostat [OPTIONS][(--interval seconds) | COMMAND ...]\n"
1240 "\n"
1241 "Turbostat forks the specified COMMAND and prints statistics\n"
1242 "when COMMAND completes.\n"
1243 "If no COMMAND is specified, turbostat wakes every 5-seconds\n"
1244 "to print statistics, until interrupted.\n"
1245 " -a, --add add a counter\n"
1246 " eg. --add msr0x10,u64,cpu,delta,MY_TSC\n"
1247 " -c, --cpu cpu-set limit output to summary plus cpu-set:\n"
1248 " {core | package | j,k,l..m,n-p }\n"
1249 " -d, --debug displays usec, Time_Of_Day_Seconds and more debugging\n"
1250 " -D, --Dump displays the raw counter values\n"
1251 " -e, --enable [all | column]\n"
1252 " shows all or the specified disabled column\n"
1253 " -H, --hide [column|column,column,...]\n"
1254 " hide the specified column(s)\n"
1255 " -i, --interval sec.subsec\n"
1256 " Override default 5-second measurement interval\n"
1257 " -J, --Joules displays energy in Joules instead of Watts\n"
1258 " -l, --list list column headers only\n"
1259 " -n, --num_iterations num\n"
1260 " number of the measurement iterations\n"
c7e399f8
ZLCH
1261 " -N, --header_iterations num\n"
1262 " print header every num iterations\n"
1b439f01
LB
1263 " -o, --out file\n"
1264 " create or truncate \"file\" for all output\n"
1265 " -q, --quiet skip decoding system configuration header\n"
1266 " -s, --show [column|column,column,...]\n"
1267 " show only the specified column(s)\n"
1268 " -S, --Summary\n"
1269 " limits output to 1-line system summary per interval\n"
1270 " -T, --TCC temperature\n"
1271 " sets the Thermal Control Circuit temperature in\n"
1272 " degrees Celsius\n"
1273 " -h, --help print this help message\n"
1274 " -v, --version print version information\n" "\n" "For more help, run \"man turbostat\"\n");
dd778a5e
LB
1275}
1276
812db3f7
LB
1277/*
1278 * bic_lookup
1279 * for all the strings in comma separate name_list,
1280 * set the approprate bit in return value.
1281 */
dd778a5e 1282unsigned long long bic_lookup(char *name_list, enum show_hide_mode mode)
812db3f7 1283{
9878bf7a 1284 unsigned int i;
812db3f7
LB
1285 unsigned long long retval = 0;
1286
1287 while (name_list) {
1288 char *comma;
1289
1290 comma = strchr(name_list, ',');
1291
1292 if (comma)
1293 *comma = '\0';
1294
1295 for (i = 0; i < MAX_BIC; ++i) {
1296 if (!strcmp(name_list, bic[i].name)) {
1297 retval |= (1ULL << i);
1298 break;
1299 }
5dc241f2
LB
1300 if (!strcmp(name_list, "all")) {
1301 retval |= ~0;
1302 break;
1303 } else if (!strcmp(name_list, "topology")) {
1304 retval |= BIC_TOPOLOGY;
1305 break;
1306 } else if (!strcmp(name_list, "power")) {
1307 retval |= BIC_THERMAL_PWR;
1308 break;
1309 } else if (!strcmp(name_list, "idle")) {
1310 retval |= BIC_IDLE;
1311 break;
1312 } else if (!strcmp(name_list, "frequency")) {
1313 retval |= BIC_FREQUENCY;
1314 break;
1315 } else if (!strcmp(name_list, "other")) {
1316 retval |= BIC_OTHER;
1317 break;
1318 }
1319
812db3f7
LB
1320 }
1321 if (i == MAX_BIC) {
dd778a5e 1322 if (mode == SHOW_LIST) {
0fc521bc
ZLCH
1323 deferred_add_names[deferred_add_index++] = name_list;
1324 if (deferred_add_index >= MAX_DEFERRED) {
1325 fprintf(stderr, "More than max %d un-recognized --add options '%s'\n",
164d7a96 1326 MAX_DEFERRED, name_list);
0fc521bc
ZLCH
1327 help();
1328 exit(1);
1329 }
1330 } else {
1331 deferred_skip_names[deferred_skip_index++] = name_list;
1332 if (debug)
1333 fprintf(stderr, "deferred \"%s\"\n", name_list);
1334 if (deferred_skip_index >= MAX_DEFERRED) {
1335 fprintf(stderr, "More than max %d un-recognized --skip options '%s'\n",
164d7a96 1336 MAX_DEFERRED, name_list);
0fc521bc
ZLCH
1337 help();
1338 exit(1);
1339 }
dd778a5e 1340 }
812db3f7
LB
1341 }
1342
1343 name_list = comma;
1344 if (name_list)
1345 name_list++;
1346
1347 }
1348 return retval;
1349}
fc04cc67 1350
c8ade361 1351void print_header(char *delim)
103a8fea 1352{
388e9c81 1353 struct msr_counter *mp;
6168c2e0 1354 int printed = 0;
388e9c81 1355
3f44a5c6
LB
1356 if (DO_BIC(BIC_USEC))
1357 outp += sprintf(outp, "%susec", (printed++ ? delim : ""));
1358 if (DO_BIC(BIC_TOD))
1359 outp += sprintf(outp, "%sTime_Of_Day_Seconds", (printed++ ? delim : ""));
812db3f7 1360 if (DO_BIC(BIC_Package))
6168c2e0 1361 outp += sprintf(outp, "%sPackage", (printed++ ? delim : ""));
6de68fe1
LB
1362 if (DO_BIC(BIC_Die))
1363 outp += sprintf(outp, "%sDie", (printed++ ? delim : ""));
01235041
PB
1364 if (DO_BIC(BIC_Node))
1365 outp += sprintf(outp, "%sNode", (printed++ ? delim : ""));
812db3f7 1366 if (DO_BIC(BIC_Core))
6168c2e0 1367 outp += sprintf(outp, "%sCore", (printed++ ? delim : ""));
812db3f7 1368 if (DO_BIC(BIC_CPU))
6168c2e0 1369 outp += sprintf(outp, "%sCPU", (printed++ ? delim : ""));
4c2122d4
LB
1370 if (DO_BIC(BIC_APIC))
1371 outp += sprintf(outp, "%sAPIC", (printed++ ? delim : ""));
1372 if (DO_BIC(BIC_X2APIC))
1373 outp += sprintf(outp, "%sX2APIC", (printed++ ? delim : ""));
812db3f7 1374 if (DO_BIC(BIC_Avg_MHz))
6168c2e0 1375 outp += sprintf(outp, "%sAvg_MHz", (printed++ ? delim : ""));
812db3f7 1376 if (DO_BIC(BIC_Busy))
6168c2e0 1377 outp += sprintf(outp, "%sBusy%%", (printed++ ? delim : ""));
812db3f7 1378 if (DO_BIC(BIC_Bzy_MHz))
6168c2e0 1379 outp += sprintf(outp, "%sBzy_MHz", (printed++ ? delim : ""));
812db3f7 1380 if (DO_BIC(BIC_TSC_MHz))
6168c2e0 1381 outp += sprintf(outp, "%sTSC_MHz", (printed++ ? delim : ""));
1cc21f7b 1382
2af4f9b8
LB
1383 if (DO_BIC(BIC_IPC))
1384 outp += sprintf(outp, "%sIPC", (printed++ ? delim : ""));
1385
0de6c0df
LB
1386 if (DO_BIC(BIC_IRQ)) {
1387 if (sums_need_wide_columns)
6168c2e0 1388 outp += sprintf(outp, "%s IRQ", (printed++ ? delim : ""));
0de6c0df 1389 else
6168c2e0 1390 outp += sprintf(outp, "%sIRQ", (printed++ ? delim : ""));
0de6c0df
LB
1391 }
1392
812db3f7 1393 if (DO_BIC(BIC_SMI))
6168c2e0 1394 outp += sprintf(outp, "%sSMI", (printed++ ? delim : ""));
1cc21f7b 1395
388e9c81 1396 for (mp = sys.tp; mp; mp = mp->next) {
dd778a5e 1397
388e9c81
LB
1398 if (mp->format == FORMAT_RAW) {
1399 if (mp->width == 64)
dd778a5e 1400 outp += sprintf(outp, "%s%18.18s", (printed++ ? delim : ""), mp->name);
388e9c81 1401 else
dd778a5e 1402 outp += sprintf(outp, "%s%10.10s", (printed++ ? delim : ""), mp->name);
388e9c81 1403 } else {
0de6c0df 1404 if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
dd778a5e 1405 outp += sprintf(outp, "%s%8s", (printed++ ? delim : ""), mp->name);
0de6c0df 1406 else
dd778a5e 1407 outp += sprintf(outp, "%s%s", (printed++ ? delim : ""), mp->name);
388e9c81
LB
1408 }
1409 }
1410
41618e63 1411 if (DO_BIC(BIC_CPU_c1))
6168c2e0 1412 outp += sprintf(outp, "%sCPU%%c1", (printed++ ? delim : ""));
562855ee 1413 if (DO_BIC(BIC_CPU_c3))
6168c2e0 1414 outp += sprintf(outp, "%sCPU%%c3", (printed++ ? delim : ""));
812db3f7 1415 if (DO_BIC(BIC_CPU_c6))
6168c2e0 1416 outp += sprintf(outp, "%sCPU%%c6", (printed++ ? delim : ""));
812db3f7 1417 if (DO_BIC(BIC_CPU_c7))
6168c2e0 1418 outp += sprintf(outp, "%sCPU%%c7", (printed++ ? delim : ""));
678a3bd1 1419
0539ba11 1420 if (DO_BIC(BIC_Mod_c6))
6168c2e0 1421 outp += sprintf(outp, "%sMod%%c6", (printed++ ? delim : ""));
678a3bd1 1422
812db3f7 1423 if (DO_BIC(BIC_CoreTmp))
6168c2e0 1424 outp += sprintf(outp, "%sCoreTmp", (printed++ ? delim : ""));
388e9c81 1425
eae97e05
CY
1426 if (DO_BIC(BIC_CORE_THROT_CNT))
1427 outp += sprintf(outp, "%sCoreThr", (printed++ ? delim : ""));
1428
86ba263d 1429 if (platform->rapl_msrs && !rapl_joules) {
e338831b 1430 if (DO_BIC(BIC_CorWatt) && platform->has_per_core_rapl)
9392bd98 1431 outp += sprintf(outp, "%sCorWatt", (printed++ ? delim : ""));
86ba263d 1432 } else if (platform->rapl_msrs && rapl_joules) {
e338831b 1433 if (DO_BIC(BIC_Cor_J) && platform->has_per_core_rapl)
9392bd98
CW
1434 outp += sprintf(outp, "%sCor_J", (printed++ ? delim : ""));
1435 }
1436
388e9c81
LB
1437 for (mp = sys.cp; mp; mp = mp->next) {
1438 if (mp->format == FORMAT_RAW) {
1439 if (mp->width == 64)
c8ade361 1440 outp += sprintf(outp, "%s%18.18s", delim, mp->name);
388e9c81 1441 else
c8ade361 1442 outp += sprintf(outp, "%s%10.10s", delim, mp->name);
388e9c81 1443 } else {
0de6c0df
LB
1444 if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
1445 outp += sprintf(outp, "%s%8s", delim, mp->name);
1446 else
1447 outp += sprintf(outp, "%s%s", delim, mp->name);
388e9c81
LB
1448 }
1449 }
1450
812db3f7 1451 if (DO_BIC(BIC_PkgTmp))
6168c2e0 1452 outp += sprintf(outp, "%sPkgTmp", (printed++ ? delim : ""));
889facbe 1453
812db3f7 1454 if (DO_BIC(BIC_GFX_rc6))
6168c2e0 1455 outp += sprintf(outp, "%sGFX%%rc6", (printed++ ? delim : ""));
fdf676e5 1456
812db3f7 1457 if (DO_BIC(BIC_GFXMHz))
6168c2e0 1458 outp += sprintf(outp, "%sGFXMHz", (printed++ ? delim : ""));
27d47356 1459
b4b91569
RA
1460 if (DO_BIC(BIC_GFXACTMHz))
1461 outp += sprintf(outp, "%sGFXAMHz", (printed++ ? delim : ""));
1462
a99d8730 1463 if (DO_BIC(BIC_Totl_c0))
6168c2e0 1464 outp += sprintf(outp, "%sTotl%%C0", (printed++ ? delim : ""));
a99d8730 1465 if (DO_BIC(BIC_Any_c0))
6168c2e0 1466 outp += sprintf(outp, "%sAny%%C0", (printed++ ? delim : ""));
a99d8730 1467 if (DO_BIC(BIC_GFX_c0))
6168c2e0 1468 outp += sprintf(outp, "%sGFX%%C0", (printed++ ? delim : ""));
a99d8730 1469 if (DO_BIC(BIC_CPUGFX))
6168c2e0 1470 outp += sprintf(outp, "%sCPUGFX%%", (printed++ ? delim : ""));
0b2bb692 1471
0f47c08d 1472 if (DO_BIC(BIC_Pkgpc2))
6168c2e0 1473 outp += sprintf(outp, "%sPkg%%pc2", (printed++ ? delim : ""));
0f47c08d 1474 if (DO_BIC(BIC_Pkgpc3))
6168c2e0 1475 outp += sprintf(outp, "%sPkg%%pc3", (printed++ ? delim : ""));
0f47c08d 1476 if (DO_BIC(BIC_Pkgpc6))
6168c2e0 1477 outp += sprintf(outp, "%sPkg%%pc6", (printed++ ? delim : ""));
0f47c08d 1478 if (DO_BIC(BIC_Pkgpc7))
6168c2e0 1479 outp += sprintf(outp, "%sPkg%%pc7", (printed++ ? delim : ""));
0f47c08d 1480 if (DO_BIC(BIC_Pkgpc8))
6168c2e0 1481 outp += sprintf(outp, "%sPkg%%pc8", (printed++ ? delim : ""));
0f47c08d 1482 if (DO_BIC(BIC_Pkgpc9))
6168c2e0 1483 outp += sprintf(outp, "%sPkg%%pc9", (printed++ ? delim : ""));
0f47c08d 1484 if (DO_BIC(BIC_Pkgpc10))
6168c2e0 1485 outp += sprintf(outp, "%sPk%%pc10", (printed++ ? delim : ""));
be0e54c4
LB
1486 if (DO_BIC(BIC_CPU_LPI))
1487 outp += sprintf(outp, "%sCPU%%LPI", (printed++ ? delim : ""));
1488 if (DO_BIC(BIC_SYS_LPI))
1489 outp += sprintf(outp, "%sSYS%%LPI", (printed++ ? delim : ""));
103a8fea 1490
86ba263d 1491 if (platform->rapl_msrs && !rapl_joules) {
812db3f7 1492 if (DO_BIC(BIC_PkgWatt))
6168c2e0 1493 outp += sprintf(outp, "%sPkgWatt", (printed++ ? delim : ""));
e338831b 1494 if (DO_BIC(BIC_CorWatt) && !platform->has_per_core_rapl)
6168c2e0 1495 outp += sprintf(outp, "%sCorWatt", (printed++ ? delim : ""));
812db3f7 1496 if (DO_BIC(BIC_GFXWatt))
6168c2e0 1497 outp += sprintf(outp, "%sGFXWatt", (printed++ ? delim : ""));
812db3f7 1498 if (DO_BIC(BIC_RAMWatt))
6168c2e0 1499 outp += sprintf(outp, "%sRAMWatt", (printed++ ? delim : ""));
812db3f7 1500 if (DO_BIC(BIC_PKG__))
6168c2e0 1501 outp += sprintf(outp, "%sPKG_%%", (printed++ ? delim : ""));
812db3f7 1502 if (DO_BIC(BIC_RAM__))
6168c2e0 1503 outp += sprintf(outp, "%sRAM_%%", (printed++ ? delim : ""));
86ba263d 1504 } else if (platform->rapl_msrs && rapl_joules) {
812db3f7 1505 if (DO_BIC(BIC_Pkg_J))
6168c2e0 1506 outp += sprintf(outp, "%sPkg_J", (printed++ ? delim : ""));
e338831b 1507 if (DO_BIC(BIC_Cor_J) && !platform->has_per_core_rapl)
6168c2e0 1508 outp += sprintf(outp, "%sCor_J", (printed++ ? delim : ""));
812db3f7 1509 if (DO_BIC(BIC_GFX_J))
6168c2e0 1510 outp += sprintf(outp, "%sGFX_J", (printed++ ? delim : ""));
812db3f7 1511 if (DO_BIC(BIC_RAM_J))
6168c2e0 1512 outp += sprintf(outp, "%sRAM_J", (printed++ ? delim : ""));
812db3f7 1513 if (DO_BIC(BIC_PKG__))
6168c2e0 1514 outp += sprintf(outp, "%sPKG_%%", (printed++ ? delim : ""));
812db3f7 1515 if (DO_BIC(BIC_RAM__))
6168c2e0 1516 outp += sprintf(outp, "%sRAM_%%", (printed++ ? delim : ""));
5c56be9a 1517 }
a5c6d65d
LB
1518 if (DO_BIC(BIC_UNCORE_MHZ))
1519 outp += sprintf(outp, "%sUncMHz", (printed++ ? delim : ""));
1520
388e9c81
LB
1521 for (mp = sys.pp; mp; mp = mp->next) {
1522 if (mp->format == FORMAT_RAW) {
1523 if (mp->width == 64)
c8ade361 1524 outp += sprintf(outp, "%s%18.18s", delim, mp->name);
388e9c81 1525 else
c8ade361 1526 outp += sprintf(outp, "%s%10.10s", delim, mp->name);
388e9c81 1527 } else {
0de6c0df
LB
1528 if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
1529 outp += sprintf(outp, "%s%8s", delim, mp->name);
1530 else
1531 outp += sprintf(outp, "%s%s", delim, mp->name);
388e9c81
LB
1532 }
1533 }
1534
c98d5d94 1535 outp += sprintf(outp, "\n");
103a8fea
LB
1536}
1537
1b439f01 1538int dump_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
103a8fea 1539{
388e9c81
LB
1540 int i;
1541 struct msr_counter *mp;
1542
3b4d5c7f 1543 outp += sprintf(outp, "t %p, c %p, p %p\n", t, c, p);
c98d5d94
LB
1544
1545 if (t) {
1b439f01 1546 outp += sprintf(outp, "CPU: %d flags 0x%x\n", t->cpu_id, t->flags);
3b4d5c7f
AS
1547 outp += sprintf(outp, "TSC: %016llX\n", t->tsc);
1548 outp += sprintf(outp, "aperf: %016llX\n", t->aperf);
1549 outp += sprintf(outp, "mperf: %016llX\n", t->mperf);
1550 outp += sprintf(outp, "c1: %016llX\n", t->c1);
6886fee4 1551
2af4f9b8
LB
1552 if (DO_BIC(BIC_IPC))
1553 outp += sprintf(outp, "IPC: %lld\n", t->instr_count);
1554
812db3f7 1555 if (DO_BIC(BIC_IRQ))
0de6c0df 1556 outp += sprintf(outp, "IRQ: %lld\n", t->irq_count);
812db3f7 1557 if (DO_BIC(BIC_SMI))
218f0e8d 1558 outp += sprintf(outp, "SMI: %d\n", t->smi_count);
388e9c81
LB
1559
1560 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
1b439f01 1561 outp += sprintf(outp, "tADDED [%d] msr0x%x: %08llX\n", i, mp->msr_num, t->counter[i]);
388e9c81 1562 }
c98d5d94 1563 }
103a8fea 1564
c98d5d94 1565 if (c) {
3b4d5c7f
AS
1566 outp += sprintf(outp, "core: %d\n", c->core_id);
1567 outp += sprintf(outp, "c3: %016llX\n", c->c3);
1568 outp += sprintf(outp, "c6: %016llX\n", c->c6);
1569 outp += sprintf(outp, "c7: %016llX\n", c->c7);
1570 outp += sprintf(outp, "DTS: %dC\n", c->core_temp_c);
eae97e05 1571 outp += sprintf(outp, "cpu_throt_count: %016llX\n", c->core_throt_cnt);
9392bd98 1572 outp += sprintf(outp, "Joules: %0X\n", c->core_energy);
388e9c81
LB
1573
1574 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
1b439f01 1575 outp += sprintf(outp, "cADDED [%d] msr0x%x: %08llX\n", i, mp->msr_num, c->counter[i]);
388e9c81 1576 }
0539ba11 1577 outp += sprintf(outp, "mc6_us: %016llX\n", c->mc6_us);
c98d5d94 1578 }
103a8fea 1579
c98d5d94 1580 if (p) {
3b4d5c7f 1581 outp += sprintf(outp, "package: %d\n", p->package_id);
0b2bb692
LB
1582
1583 outp += sprintf(outp, "Weighted cores: %016llX\n", p->pkg_wtd_core_c0);
1584 outp += sprintf(outp, "Any cores: %016llX\n", p->pkg_any_core_c0);
1585 outp += sprintf(outp, "Any GFX: %016llX\n", p->pkg_any_gfxe_c0);
1586 outp += sprintf(outp, "CPU + GFX: %016llX\n", p->pkg_both_core_gfxe_c0);
1587
3b4d5c7f 1588 outp += sprintf(outp, "pc2: %016llX\n", p->pc2);
0f47c08d 1589 if (DO_BIC(BIC_Pkgpc3))
ee7e38e3 1590 outp += sprintf(outp, "pc3: %016llX\n", p->pc3);
0f47c08d 1591 if (DO_BIC(BIC_Pkgpc6))
ee7e38e3 1592 outp += sprintf(outp, "pc6: %016llX\n", p->pc6);
0f47c08d 1593 if (DO_BIC(BIC_Pkgpc7))
ee7e38e3 1594 outp += sprintf(outp, "pc7: %016llX\n", p->pc7);
3b4d5c7f
AS
1595 outp += sprintf(outp, "pc8: %016llX\n", p->pc8);
1596 outp += sprintf(outp, "pc9: %016llX\n", p->pc9);
1597 outp += sprintf(outp, "pc10: %016llX\n", p->pc10);
be0e54c4
LB
1598 outp += sprintf(outp, "cpu_lpi: %016llX\n", p->cpu_lpi);
1599 outp += sprintf(outp, "sys_lpi: %016llX\n", p->sys_lpi);
7c2ccc50
CY
1600 outp += sprintf(outp, "Joules PKG: %0llX\n", p->energy_pkg);
1601 outp += sprintf(outp, "Joules COR: %0llX\n", p->energy_cores);
1602 outp += sprintf(outp, "Joules GFX: %0llX\n", p->energy_gfx);
1603 outp += sprintf(outp, "Joules RAM: %0llX\n", p->energy_dram);
1b439f01
LB
1604 outp += sprintf(outp, "Throttle PKG: %0llX\n", p->rapl_pkg_perf_status);
1605 outp += sprintf(outp, "Throttle RAM: %0llX\n", p->rapl_dram_perf_status);
3b4d5c7f 1606 outp += sprintf(outp, "PTM: %dC\n", p->pkg_temp_c);
388e9c81
LB
1607
1608 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
1b439f01 1609 outp += sprintf(outp, "pADDED [%d] msr0x%x: %08llX\n", i, mp->msr_num, p->counter[i]);
388e9c81 1610 }
c98d5d94 1611 }
3b4d5c7f
AS
1612
1613 outp += sprintf(outp, "\n");
1614
c98d5d94 1615 return 0;
103a8fea
LB
1616}
1617
e23da037
LB
1618/*
1619 * column formatting convention & formats
e23da037 1620 */
1b439f01 1621int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
103a8fea 1622{
008d396e 1623 double interval_float, tsc;
fc04cc67 1624 char *fmt8;
388e9c81
LB
1625 int i;
1626 struct msr_counter *mp;
6168c2e0
LB
1627 char *delim = "\t";
1628 int printed = 0;
103a8fea 1629
1b439f01 1630 /* if showing only 1st thread in core and this isn't one, bail out */
c98d5d94
LB
1631 if (show_core_only && !(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
1632 return 0;
1633
1b439f01 1634 /* if showing only 1st thread in pkg and this isn't one, bail out */
c98d5d94
LB
1635 if (show_pkg_only && !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
1636 return 0;
1637
1ef7d21a 1638 /*if not summary line and --cpu is used */
1b439f01 1639 if ((t != &average.threads) && (cpu_subset && !CPU_ISSET_S(t->cpu_id, cpu_subset_size, cpu_subset)))
1ef7d21a
LB
1640 return 0;
1641
3f44a5c6 1642 if (DO_BIC(BIC_USEC)) {
f4fdf2b4
LB
1643 /* on each row, print how many usec each timestamp took to gather */
1644 struct timeval tv;
1645
1646 timersub(&t->tv_end, &t->tv_begin, &tv);
1647 outp += sprintf(outp, "%5ld\t", tv.tv_sec * 1000000 + tv.tv_usec);
1648 }
1649
3f44a5c6
LB
1650 /* Time_Of_Day_Seconds: on each row, print sec.usec last timestamp taken */
1651 if (DO_BIC(BIC_TOD))
1652 outp += sprintf(outp, "%10ld.%06ld\t", t->tv_end.tv_sec, t->tv_end.tv_usec);
1653
1b439f01 1654 interval_float = t->tv_delta.tv_sec + t->tv_delta.tv_usec / 1000000.0;
103a8fea 1655
008d396e
LB
1656 tsc = t->tsc * tsc_tweak;
1657
c98d5d94
LB
1658 /* topo columns, print blanks on 1st (average) line */
1659 if (t == &average.threads) {
812db3f7 1660 if (DO_BIC(BIC_Package))
6168c2e0 1661 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
6de68fe1
LB
1662 if (DO_BIC(BIC_Die))
1663 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
01235041
PB
1664 if (DO_BIC(BIC_Node))
1665 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
812db3f7 1666 if (DO_BIC(BIC_Core))
6168c2e0 1667 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
812db3f7 1668 if (DO_BIC(BIC_CPU))
6168c2e0 1669 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
4c2122d4
LB
1670 if (DO_BIC(BIC_APIC))
1671 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
1672 if (DO_BIC(BIC_X2APIC))
1673 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
103a8fea 1674 } else {
812db3f7 1675 if (DO_BIC(BIC_Package)) {
c98d5d94 1676 if (p)
6168c2e0 1677 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->package_id);
c98d5d94 1678 else
6168c2e0 1679 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
c98d5d94 1680 }
6de68fe1
LB
1681 if (DO_BIC(BIC_Die)) {
1682 if (c)
1683 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), cpus[t->cpu_id].die_id);
1684 else
1685 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
1686 }
01235041
PB
1687 if (DO_BIC(BIC_Node)) {
1688 if (t)
1689 outp += sprintf(outp, "%s%d",
1b439f01 1690 (printed++ ? delim : ""), cpus[t->cpu_id].physical_node_id);
01235041 1691 else
1b439f01 1692 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
01235041 1693 }
812db3f7 1694 if (DO_BIC(BIC_Core)) {
c98d5d94 1695 if (c)
6168c2e0 1696 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), c->core_id);
c98d5d94 1697 else
6168c2e0 1698 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
c98d5d94 1699 }
812db3f7 1700 if (DO_BIC(BIC_CPU))
6168c2e0 1701 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->cpu_id);
4c2122d4
LB
1702 if (DO_BIC(BIC_APIC))
1703 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->apic_id);
1704 if (DO_BIC(BIC_X2APIC))
1705 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->x2apic_id);
103a8fea 1706 }
fc04cc67 1707
812db3f7 1708 if (DO_BIC(BIC_Avg_MHz))
1b439f01 1709 outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), 1.0 / units * t->aperf / interval_float);
fc04cc67 1710
812db3f7 1711 if (DO_BIC(BIC_Busy))
1b439f01 1712 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * t->mperf / tsc);
103a8fea 1713
812db3f7 1714 if (DO_BIC(BIC_Bzy_MHz)) {
21ed5574 1715 if (has_base_hz)
1b439f01
LB
1716 outp +=
1717 sprintf(outp, "%s%.0f", (printed++ ? delim : ""), base_hz / units * t->aperf / t->mperf);
21ed5574 1718 else
6168c2e0 1719 outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""),
1b439f01 1720 tsc / units * t->aperf / t->mperf / interval_float);
21ed5574 1721 }
103a8fea 1722
812db3f7 1723 if (DO_BIC(BIC_TSC_MHz))
1b439f01 1724 outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), 1.0 * t->tsc / units / interval_float);
103a8fea 1725
2af4f9b8
LB
1726 if (DO_BIC(BIC_IPC))
1727 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 1.0 * t->instr_count / t->aperf);
1728
562a2d37 1729 /* IRQ */
0de6c0df
LB
1730 if (DO_BIC(BIC_IRQ)) {
1731 if (sums_need_wide_columns)
6168c2e0 1732 outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), t->irq_count);
0de6c0df 1733 else
6168c2e0 1734 outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), t->irq_count);
0de6c0df 1735 }
562a2d37 1736
1cc21f7b 1737 /* SMI */
812db3f7 1738 if (DO_BIC(BIC_SMI))
6168c2e0 1739 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->smi_count);
1cc21f7b 1740
678a3bd1 1741 /* Added counters */
388e9c81
LB
1742 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
1743 if (mp->format == FORMAT_RAW) {
1744 if (mp->width == 32)
1b439f01
LB
1745 outp +=
1746 sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int)t->counter[i]);
388e9c81 1747 else
6168c2e0 1748 outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), t->counter[i]);
388e9c81 1749 } else if (mp->format == FORMAT_DELTA) {
0de6c0df 1750 if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
6168c2e0 1751 outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), t->counter[i]);
0de6c0df 1752 else
6168c2e0 1753 outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), t->counter[i]);
388e9c81 1754 } else if (mp->format == FORMAT_PERCENT) {
41618e63 1755 if (mp->type == COUNTER_USEC)
1b439f01
LB
1756 outp +=
1757 sprintf(outp, "%s%.2f", (printed++ ? delim : ""),
1758 t->counter[i] / interval_float / 10000);
41618e63 1759 else
1b439f01 1760 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * t->counter[i] / tsc);
388e9c81
LB
1761 }
1762 }
1763
41618e63
LB
1764 /* C1 */
1765 if (DO_BIC(BIC_CPU_c1))
1b439f01 1766 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * t->c1 / tsc);
41618e63 1767
678a3bd1
LB
1768 /* print per-core data only for 1st thread in core */
1769 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
1770 goto done;
1771
562855ee 1772 if (DO_BIC(BIC_CPU_c3))
1b439f01 1773 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c3 / tsc);
812db3f7 1774 if (DO_BIC(BIC_CPU_c6))
1b439f01 1775 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c6 / tsc);
812db3f7 1776 if (DO_BIC(BIC_CPU_c7))
1b439f01 1777 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c7 / tsc);
678a3bd1 1778
0539ba11
LB
1779 /* Mod%c6 */
1780 if (DO_BIC(BIC_Mod_c6))
6168c2e0 1781 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->mc6_us / tsc);
0539ba11 1782
812db3f7 1783 if (DO_BIC(BIC_CoreTmp))
6168c2e0 1784 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), c->core_temp_c);
889facbe 1785
eae97e05
CY
1786 /* Core throttle count */
1787 if (DO_BIC(BIC_CORE_THROT_CNT))
1788 outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), c->core_throt_cnt);
1789
388e9c81
LB
1790 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
1791 if (mp->format == FORMAT_RAW) {
1792 if (mp->width == 32)
1b439f01
LB
1793 outp +=
1794 sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int)c->counter[i]);
388e9c81 1795 else
6168c2e0 1796 outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), c->counter[i]);
388e9c81 1797 } else if (mp->format == FORMAT_DELTA) {
0de6c0df 1798 if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
6168c2e0 1799 outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), c->counter[i]);
0de6c0df 1800 else
6168c2e0 1801 outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), c->counter[i]);
388e9c81 1802 } else if (mp->format == FORMAT_PERCENT) {
1b439f01 1803 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->counter[i] / tsc);
388e9c81
LB
1804 }
1805 }
1806
9972d5d8 1807 fmt8 = "%s%.2f";
9392bd98 1808
e338831b 1809 if (DO_BIC(BIC_CorWatt) && platform->has_per_core_rapl)
1b439f01
LB
1810 outp +=
1811 sprintf(outp, fmt8, (printed++ ? delim : ""), c->core_energy * rapl_energy_units / interval_float);
e338831b 1812 if (DO_BIC(BIC_Cor_J) && platform->has_per_core_rapl)
9392bd98
CW
1813 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), c->core_energy * rapl_energy_units);
1814
c98d5d94
LB
1815 /* print per-package data only for 1st core in package */
1816 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
1817 goto done;
1818
0b2bb692 1819 /* PkgTmp */
812db3f7 1820 if (DO_BIC(BIC_PkgTmp))
6168c2e0 1821 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->pkg_temp_c);
889facbe 1822
fdf676e5 1823 /* GFXrc6 */
812db3f7 1824 if (DO_BIC(BIC_GFX_rc6)) {
ba3dec99 1825 if (p->gfx_rc6_ms == -1) { /* detect GFX counter reset */
6168c2e0 1826 outp += sprintf(outp, "%s**.**", (printed++ ? delim : ""));
9185e988 1827 } else {
6168c2e0 1828 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""),
1b439f01 1829 p->gfx_rc6_ms / 10.0 / interval_float);
9185e988
LB
1830 }
1831 }
fdf676e5 1832
27d47356 1833 /* GFXMHz */
812db3f7 1834 if (DO_BIC(BIC_GFXMHz))
6168c2e0 1835 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->gfx_mhz);
27d47356 1836
b4b91569
RA
1837 /* GFXACTMHz */
1838 if (DO_BIC(BIC_GFXACTMHz))
1839 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->gfx_act_mhz);
1840
0b2bb692 1841 /* Totl%C0, Any%C0 GFX%C0 CPUGFX% */
a99d8730 1842 if (DO_BIC(BIC_Totl_c0))
1b439f01 1843 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_wtd_core_c0 / tsc);
a99d8730 1844 if (DO_BIC(BIC_Any_c0))
1b439f01 1845 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_any_core_c0 / tsc);
a99d8730 1846 if (DO_BIC(BIC_GFX_c0))
1b439f01 1847 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_any_gfxe_c0 / tsc);
a99d8730 1848 if (DO_BIC(BIC_CPUGFX))
1b439f01 1849 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_both_core_gfxe_c0 / tsc);
0b2bb692 1850
0f47c08d 1851 if (DO_BIC(BIC_Pkgpc2))
1b439f01 1852 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc2 / tsc);
0f47c08d 1853 if (DO_BIC(BIC_Pkgpc3))
1b439f01 1854 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc3 / tsc);
0f47c08d 1855 if (DO_BIC(BIC_Pkgpc6))
1b439f01 1856 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc6 / tsc);
0f47c08d 1857 if (DO_BIC(BIC_Pkgpc7))
1b439f01 1858 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc7 / tsc);
0f47c08d 1859 if (DO_BIC(BIC_Pkgpc8))
1b439f01 1860 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc8 / tsc);
0f47c08d 1861 if (DO_BIC(BIC_Pkgpc9))
1b439f01 1862 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc9 / tsc);
0f47c08d 1863 if (DO_BIC(BIC_Pkgpc10))
1b439f01 1864 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc10 / tsc);
889facbe 1865
be0e54c4 1866 if (DO_BIC(BIC_CPU_LPI))
1b439f01
LB
1867 outp +=
1868 sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->cpu_lpi / 1000000.0 / interval_float);
be0e54c4 1869 if (DO_BIC(BIC_SYS_LPI))
1b439f01
LB
1870 outp +=
1871 sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->sys_lpi / 1000000.0 / interval_float);
be0e54c4 1872
812db3f7 1873 if (DO_BIC(BIC_PkgWatt))
1b439f01
LB
1874 outp +=
1875 sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units / interval_float);
eae97e05 1876
e338831b 1877 if (DO_BIC(BIC_CorWatt) && !platform->has_per_core_rapl)
1b439f01
LB
1878 outp +=
1879 sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units / interval_float);
812db3f7 1880 if (DO_BIC(BIC_GFXWatt))
1b439f01
LB
1881 outp +=
1882 sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units / interval_float);
812db3f7 1883 if (DO_BIC(BIC_RAMWatt))
1b439f01
LB
1884 outp +=
1885 sprintf(outp, fmt8, (printed++ ? delim : ""),
1886 p->energy_dram * rapl_dram_energy_units / interval_float);
812db3f7 1887 if (DO_BIC(BIC_Pkg_J))
6168c2e0 1888 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units);
e338831b 1889 if (DO_BIC(BIC_Cor_J) && !platform->has_per_core_rapl)
6168c2e0 1890 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units);
812db3f7 1891 if (DO_BIC(BIC_GFX_J))
6168c2e0 1892 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units);
812db3f7 1893 if (DO_BIC(BIC_RAM_J))
6168c2e0 1894 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_dram * rapl_dram_energy_units);
812db3f7 1895 if (DO_BIC(BIC_PKG__))
1b439f01
LB
1896 outp +=
1897 sprintf(outp, fmt8, (printed++ ? delim : ""),
1898 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
812db3f7 1899 if (DO_BIC(BIC_RAM__))
1b439f01
LB
1900 outp +=
1901 sprintf(outp, fmt8, (printed++ ? delim : ""),
1902 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
a5c6d65d
LB
1903 /* UncMHz */
1904 if (DO_BIC(BIC_UNCORE_MHZ))
1905 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->uncore_mhz);
812db3f7 1906
388e9c81
LB
1907 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
1908 if (mp->format == FORMAT_RAW) {
1909 if (mp->width == 32)
1b439f01
LB
1910 outp +=
1911 sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int)p->counter[i]);
388e9c81 1912 else
6168c2e0 1913 outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), p->counter[i]);
388e9c81 1914 } else if (mp->format == FORMAT_DELTA) {
0de6c0df 1915 if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
6168c2e0 1916 outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), p->counter[i]);
0de6c0df 1917 else
6168c2e0 1918 outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), p->counter[i]);
388e9c81 1919 } else if (mp->format == FORMAT_PERCENT) {
1b439f01 1920 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->counter[i] / tsc);
388e9c81
LB
1921 }
1922 }
1923
c98d5d94 1924done:
94d6ab4b
LB
1925 if (*(outp - 1) != '\n')
1926 outp += sprintf(outp, "\n");
c98d5d94
LB
1927
1928 return 0;
103a8fea
LB
1929}
1930
b7d8c148 1931void flush_output_stdout(void)
c98d5d94 1932{
b7d8c148
LB
1933 FILE *filep;
1934
1935 if (outf == stderr)
1936 filep = stdout;
1937 else
1938 filep = outf;
1939
1940 fputs(output_buffer, filep);
1941 fflush(filep);
1942
c98d5d94
LB
1943 outp = output_buffer;
1944}
1b439f01 1945
b7d8c148 1946void flush_output_stderr(void)
c98d5d94 1947{
b7d8c148
LB
1948 fputs(output_buffer, outf);
1949 fflush(outf);
c98d5d94
LB
1950 outp = output_buffer;
1951}
1b439f01 1952
c98d5d94 1953void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
103a8fea 1954{
c7e399f8 1955 static int count;
103a8fea 1956
c7e399f8 1957 if ((!count || (header_iterations && !(count % header_iterations))) || !summary_only)
c8ade361 1958 print_header("\t");
103a8fea 1959
9d83601a 1960 format_counters(&average.threads, &average.cores, &average.packages);
103a8fea 1961
c7e399f8 1962 count++;
e23da037
LB
1963
1964 if (summary_only)
1965 return;
1966
c98d5d94 1967 for_all_cpus(format_counters, t, c, p);
103a8fea
LB
1968}
1969
889facbe 1970#define DELTA_WRAP32(new, old) \
7c2ccc50 1971 old = ((((unsigned long long)new << 32) - ((unsigned long long)old << 32)) >> 32);
889facbe 1972
1b439f01 1973int delta_package(struct pkg_data *new, struct pkg_data *old)
c98d5d94 1974{
388e9c81
LB
1975 int i;
1976 struct msr_counter *mp;
0b2bb692 1977
a99d8730 1978 if (DO_BIC(BIC_Totl_c0))
0b2bb692 1979 old->pkg_wtd_core_c0 = new->pkg_wtd_core_c0 - old->pkg_wtd_core_c0;
a99d8730 1980 if (DO_BIC(BIC_Any_c0))
0b2bb692 1981 old->pkg_any_core_c0 = new->pkg_any_core_c0 - old->pkg_any_core_c0;
a99d8730 1982 if (DO_BIC(BIC_GFX_c0))
0b2bb692 1983 old->pkg_any_gfxe_c0 = new->pkg_any_gfxe_c0 - old->pkg_any_gfxe_c0;
a99d8730 1984 if (DO_BIC(BIC_CPUGFX))
0b2bb692 1985 old->pkg_both_core_gfxe_c0 = new->pkg_both_core_gfxe_c0 - old->pkg_both_core_gfxe_c0;
a99d8730 1986
c98d5d94 1987 old->pc2 = new->pc2 - old->pc2;
0f47c08d 1988 if (DO_BIC(BIC_Pkgpc3))
ee7e38e3 1989 old->pc3 = new->pc3 - old->pc3;
0f47c08d 1990 if (DO_BIC(BIC_Pkgpc6))
ee7e38e3 1991 old->pc6 = new->pc6 - old->pc6;
0f47c08d 1992 if (DO_BIC(BIC_Pkgpc7))
ee7e38e3 1993 old->pc7 = new->pc7 - old->pc7;
ca58710f
KCA
1994 old->pc8 = new->pc8 - old->pc8;
1995 old->pc9 = new->pc9 - old->pc9;
1996 old->pc10 = new->pc10 - old->pc10;
be0e54c4
LB
1997 old->cpu_lpi = new->cpu_lpi - old->cpu_lpi;
1998 old->sys_lpi = new->sys_lpi - old->sys_lpi;
889facbe
LB
1999 old->pkg_temp_c = new->pkg_temp_c;
2000
9185e988 2001 /* flag an error when rc6 counter resets/wraps */
1b439f01 2002 if (old->gfx_rc6_ms > new->gfx_rc6_ms)
9185e988
LB
2003 old->gfx_rc6_ms = -1;
2004 else
2005 old->gfx_rc6_ms = new->gfx_rc6_ms - old->gfx_rc6_ms;
2006
a5c6d65d 2007 old->uncore_mhz = new->uncore_mhz;
27d47356 2008 old->gfx_mhz = new->gfx_mhz;
b4b91569 2009 old->gfx_act_mhz = new->gfx_act_mhz;
27d47356 2010
87e15da9
CY
2011 old->energy_pkg = new->energy_pkg - old->energy_pkg;
2012 old->energy_cores = new->energy_cores - old->energy_cores;
2013 old->energy_gfx = new->energy_gfx - old->energy_gfx;
2014 old->energy_dram = new->energy_dram - old->energy_dram;
2015 old->rapl_pkg_perf_status = new->rapl_pkg_perf_status - old->rapl_pkg_perf_status;
2016 old->rapl_dram_perf_status = new->rapl_dram_perf_status - old->rapl_dram_perf_status;
ba3dec99 2017
388e9c81
LB
2018 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
2019 if (mp->format == FORMAT_RAW)
2020 old->counter[i] = new->counter[i];
2021 else
2022 old->counter[i] = new->counter[i] - old->counter[i];
2023 }
2024
ba3dec99 2025 return 0;
c98d5d94 2026}
103a8fea 2027
1b439f01 2028void delta_core(struct core_data *new, struct core_data *old)
103a8fea 2029{
388e9c81
LB
2030 int i;
2031 struct msr_counter *mp;
2032
c98d5d94
LB
2033 old->c3 = new->c3 - old->c3;
2034 old->c6 = new->c6 - old->c6;
2035 old->c7 = new->c7 - old->c7;
889facbe 2036 old->core_temp_c = new->core_temp_c;
eae97e05 2037 old->core_throt_cnt = new->core_throt_cnt;
0539ba11 2038 old->mc6_us = new->mc6_us - old->mc6_us;
388e9c81 2039
9392bd98
CW
2040 DELTA_WRAP32(new->core_energy, old->core_energy);
2041
388e9c81
LB
2042 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
2043 if (mp->format == FORMAT_RAW)
2044 old->counter[i] = new->counter[i];
2045 else
2046 old->counter[i] = new->counter[i] - old->counter[i];
2047 }
c98d5d94 2048}
103a8fea 2049
1e9042b9
SP
2050int soft_c1_residency_display(int bic)
2051{
2052 if (!DO_BIC(BIC_CPU_c1) || use_c1_residency_msr)
2053 return 0;
2054
2055 return DO_BIC_READ(bic);
2056}
2057
c3ae331d
LB
2058/*
2059 * old = new - old
2060 */
1b439f01 2061int delta_thread(struct thread_data *new, struct thread_data *old, struct core_data *core_delta)
c98d5d94 2062{
388e9c81
LB
2063 int i;
2064 struct msr_counter *mp;
2065
4c2122d4
LB
2066 /* we run cpuid just the 1st time, copy the results */
2067 if (DO_BIC(BIC_APIC))
2068 new->apic_id = old->apic_id;
2069 if (DO_BIC(BIC_X2APIC))
2070 new->x2apic_id = old->x2apic_id;
2071
3f44a5c6
LB
2072 /*
2073 * the timestamps from start of measurement interval are in "old"
2074 * the timestamp from end of measurement interval are in "new"
2075 * over-write old w/ new so we can print end of interval values
2076 */
2077
d4794f25 2078 timersub(&new->tv_begin, &old->tv_begin, &old->tv_delta);
3f44a5c6
LB
2079 old->tv_begin = new->tv_begin;
2080 old->tv_end = new->tv_end;
2081
c98d5d94
LB
2082 old->tsc = new->tsc - old->tsc;
2083
2084 /* check for TSC < 1 Mcycles over interval */
b2c95d90
JT
2085 if (old->tsc < (1000 * 1000))
2086 errx(-3, "Insanely slow TSC rate, TSC stops in idle?\n"
2087 "You can disable all c-states by booting with \"idle=poll\"\n"
2088 "or just the deep ones with \"processor.max_cstate=1\"");
103a8fea 2089
c98d5d94 2090 old->c1 = new->c1 - old->c1;
103a8fea 2091
1b439f01 2092 if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz) || soft_c1_residency_display(BIC_Avg_MHz)) {
a729617c
LB
2093 if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) {
2094 old->aperf = new->aperf - old->aperf;
2095 old->mperf = new->mperf - old->mperf;
2096 } else {
ba3dec99 2097 return -1;
103a8fea 2098 }
c98d5d94 2099 }
103a8fea 2100
144b44b1
LB
2101 if (use_c1_residency_msr) {
2102 /*
2103 * Some models have a dedicated C1 residency MSR,
2104 * which should be more accurate than the derivation below.
2105 */
2106 } else {
2107 /*
2108 * As counter collection is not atomic,
2109 * it is possible for mperf's non-halted cycles + idle states
2110 * to exceed TSC's all cycles: show c1 = 0% in that case.
2111 */
95149369 2112 if ((old->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > (old->tsc * tsc_tweak))
144b44b1
LB
2113 old->c1 = 0;
2114 else {
2115 /* normal case, derive c1 */
008d396e 2116 old->c1 = (old->tsc * tsc_tweak) - old->mperf - core_delta->c3
1b439f01 2117 - core_delta->c6 - core_delta->c7;
144b44b1 2118 }
c98d5d94 2119 }
c3ae331d 2120
c98d5d94 2121 if (old->mperf == 0) {
b7d8c148
LB
2122 if (debug > 1)
2123 fprintf(outf, "cpu%d MPERF 0!\n", old->cpu_id);
c98d5d94 2124 old->mperf = 1; /* divide by 0 protection */
103a8fea 2125 }
c98d5d94 2126
2af4f9b8
LB
2127 if (DO_BIC(BIC_IPC))
2128 old->instr_count = new->instr_count - old->instr_count;
2129
812db3f7 2130 if (DO_BIC(BIC_IRQ))
562a2d37
LB
2131 old->irq_count = new->irq_count - old->irq_count;
2132
812db3f7 2133 if (DO_BIC(BIC_SMI))
1ed51011 2134 old->smi_count = new->smi_count - old->smi_count;
ba3dec99 2135
388e9c81
LB
2136 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
2137 if (mp->format == FORMAT_RAW)
2138 old->counter[i] = new->counter[i];
2139 else
2140 old->counter[i] = new->counter[i] - old->counter[i];
2141 }
ba3dec99 2142 return 0;
c98d5d94
LB
2143}
2144
2145int delta_cpu(struct thread_data *t, struct core_data *c,
1b439f01 2146 struct pkg_data *p, struct thread_data *t2, struct core_data *c2, struct pkg_data *p2)
c98d5d94 2147{
ba3dec99
LB
2148 int retval = 0;
2149
c98d5d94
LB
2150 /* calculate core delta only for 1st thread in core */
2151 if (t->flags & CPU_IS_FIRST_THREAD_IN_CORE)
2152 delta_core(c, c2);
2153
2154 /* always calculate thread delta */
ba3dec99
LB
2155 retval = delta_thread(t, t2, c2); /* c2 is core delta */
2156 if (retval)
2157 return retval;
c98d5d94
LB
2158
2159 /* calculate package delta only for 1st core in package */
2160 if (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)
ba3dec99 2161 retval = delta_package(p, p2);
c98d5d94 2162
ba3dec99 2163 return retval;
103a8fea
LB
2164}
2165
c98d5d94
LB
2166void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2167{
388e9c81 2168 int i;
1b439f01 2169 struct msr_counter *mp;
388e9c81 2170
3f44a5c6
LB
2171 t->tv_begin.tv_sec = 0;
2172 t->tv_begin.tv_usec = 0;
2173 t->tv_end.tv_sec = 0;
2174 t->tv_end.tv_usec = 0;
d4794f25
YG
2175 t->tv_delta.tv_sec = 0;
2176 t->tv_delta.tv_usec = 0;
3f44a5c6 2177
c98d5d94
LB
2178 t->tsc = 0;
2179 t->aperf = 0;
2180 t->mperf = 0;
2181 t->c1 = 0;
2182
2af4f9b8
LB
2183 t->instr_count = 0;
2184
562a2d37
LB
2185 t->irq_count = 0;
2186 t->smi_count = 0;
2187
c98d5d94
LB
2188 /* tells format_counters to dump all fields from this set */
2189 t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE;
2190
2191 c->c3 = 0;
2192 c->c6 = 0;
2193 c->c7 = 0;
0539ba11 2194 c->mc6_us = 0;
889facbe 2195 c->core_temp_c = 0;
9392bd98 2196 c->core_energy = 0;
eae97e05 2197 c->core_throt_cnt = 0;
c98d5d94 2198
0b2bb692
LB
2199 p->pkg_wtd_core_c0 = 0;
2200 p->pkg_any_core_c0 = 0;
2201 p->pkg_any_gfxe_c0 = 0;
2202 p->pkg_both_core_gfxe_c0 = 0;
2203
c98d5d94 2204 p->pc2 = 0;
0f47c08d 2205 if (DO_BIC(BIC_Pkgpc3))
ee7e38e3 2206 p->pc3 = 0;
0f47c08d 2207 if (DO_BIC(BIC_Pkgpc6))
ee7e38e3 2208 p->pc6 = 0;
0f47c08d 2209 if (DO_BIC(BIC_Pkgpc7))
ee7e38e3 2210 p->pc7 = 0;
ca58710f
KCA
2211 p->pc8 = 0;
2212 p->pc9 = 0;
2213 p->pc10 = 0;
be0e54c4
LB
2214 p->cpu_lpi = 0;
2215 p->sys_lpi = 0;
889facbe
LB
2216
2217 p->energy_pkg = 0;
2218 p->energy_dram = 0;
2219 p->energy_cores = 0;
2220 p->energy_gfx = 0;
2221 p->rapl_pkg_perf_status = 0;
2222 p->rapl_dram_perf_status = 0;
2223 p->pkg_temp_c = 0;
27d47356 2224
fdf676e5 2225 p->gfx_rc6_ms = 0;
a5c6d65d 2226 p->uncore_mhz = 0;
27d47356 2227 p->gfx_mhz = 0;
b4b91569 2228 p->gfx_act_mhz = 0;
388e9c81
LB
2229 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next)
2230 t->counter[i] = 0;
2231
2232 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next)
2233 c->counter[i] = 0;
2234
2235 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next)
2236 p->counter[i] = 0;
c98d5d94 2237}
1b439f01
LB
2238
2239int sum_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
103a8fea 2240{
388e9c81
LB
2241 int i;
2242 struct msr_counter *mp;
2243
4c2122d4
LB
2244 /* copy un-changing apic_id's */
2245 if (DO_BIC(BIC_APIC))
2246 average.threads.apic_id = t->apic_id;
2247 if (DO_BIC(BIC_X2APIC))
2248 average.threads.x2apic_id = t->x2apic_id;
2249
3f44a5c6
LB
2250 /* remember first tv_begin */
2251 if (average.threads.tv_begin.tv_sec == 0)
2252 average.threads.tv_begin = t->tv_begin;
2253
2254 /* remember last tv_end */
2255 average.threads.tv_end = t->tv_end;
2256
c98d5d94
LB
2257 average.threads.tsc += t->tsc;
2258 average.threads.aperf += t->aperf;
2259 average.threads.mperf += t->mperf;
2260 average.threads.c1 += t->c1;
103a8fea 2261
2af4f9b8
LB
2262 average.threads.instr_count += t->instr_count;
2263
562a2d37
LB
2264 average.threads.irq_count += t->irq_count;
2265 average.threads.smi_count += t->smi_count;
2266
388e9c81
LB
2267 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
2268 if (mp->format == FORMAT_RAW)
2269 continue;
2270 average.threads.counter[i] += t->counter[i];
2271 }
2272
c98d5d94
LB
2273 /* sum per-core values only for 1st thread in core */
2274 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
2275 return 0;
103a8fea 2276
c98d5d94
LB
2277 average.cores.c3 += c->c3;
2278 average.cores.c6 += c->c6;
2279 average.cores.c7 += c->c7;
0539ba11 2280 average.cores.mc6_us += c->mc6_us;
c98d5d94 2281
889facbe 2282 average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c);
eae97e05 2283 average.cores.core_throt_cnt = MAX(average.cores.core_throt_cnt, c->core_throt_cnt);
889facbe 2284
9392bd98
CW
2285 average.cores.core_energy += c->core_energy;
2286
388e9c81
LB
2287 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
2288 if (mp->format == FORMAT_RAW)
2289 continue;
2290 average.cores.counter[i] += c->counter[i];
2291 }
2292
c98d5d94
LB
2293 /* sum per-pkg values only for 1st core in pkg */
2294 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
2295 return 0;
2296
a99d8730 2297 if (DO_BIC(BIC_Totl_c0))
0b2bb692 2298 average.packages.pkg_wtd_core_c0 += p->pkg_wtd_core_c0;
a99d8730 2299 if (DO_BIC(BIC_Any_c0))
0b2bb692 2300 average.packages.pkg_any_core_c0 += p->pkg_any_core_c0;
a99d8730 2301 if (DO_BIC(BIC_GFX_c0))
0b2bb692 2302 average.packages.pkg_any_gfxe_c0 += p->pkg_any_gfxe_c0;
a99d8730 2303 if (DO_BIC(BIC_CPUGFX))
0b2bb692 2304 average.packages.pkg_both_core_gfxe_c0 += p->pkg_both_core_gfxe_c0;
0b2bb692 2305
c98d5d94 2306 average.packages.pc2 += p->pc2;
0f47c08d 2307 if (DO_BIC(BIC_Pkgpc3))
ee7e38e3 2308 average.packages.pc3 += p->pc3;
0f47c08d 2309 if (DO_BIC(BIC_Pkgpc6))
ee7e38e3 2310 average.packages.pc6 += p->pc6;
0f47c08d 2311 if (DO_BIC(BIC_Pkgpc7))
ee7e38e3 2312 average.packages.pc7 += p->pc7;
ca58710f
KCA
2313 average.packages.pc8 += p->pc8;
2314 average.packages.pc9 += p->pc9;
2315 average.packages.pc10 += p->pc10;
c98d5d94 2316
be0e54c4
LB
2317 average.packages.cpu_lpi = p->cpu_lpi;
2318 average.packages.sys_lpi = p->sys_lpi;
2319
889facbe
LB
2320 average.packages.energy_pkg += p->energy_pkg;
2321 average.packages.energy_dram += p->energy_dram;
2322 average.packages.energy_cores += p->energy_cores;
2323 average.packages.energy_gfx += p->energy_gfx;
2324
fdf676e5 2325 average.packages.gfx_rc6_ms = p->gfx_rc6_ms;
a5c6d65d 2326 average.packages.uncore_mhz = p->uncore_mhz;
27d47356 2327 average.packages.gfx_mhz = p->gfx_mhz;
b4b91569 2328 average.packages.gfx_act_mhz = p->gfx_act_mhz;
27d47356 2329
889facbe
LB
2330 average.packages.pkg_temp_c = MAX(average.packages.pkg_temp_c, p->pkg_temp_c);
2331
2332 average.packages.rapl_pkg_perf_status += p->rapl_pkg_perf_status;
2333 average.packages.rapl_dram_perf_status += p->rapl_dram_perf_status;
388e9c81
LB
2334
2335 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
2336 if (mp->format == FORMAT_RAW)
2337 continue;
2338 average.packages.counter[i] += p->counter[i];
2339 }
c98d5d94
LB
2340 return 0;
2341}
1b439f01 2342
c98d5d94
LB
2343/*
2344 * sum the counters for all cpus in the system
2345 * compute the weighted average
2346 */
1b439f01 2347void compute_average(struct thread_data *t, struct core_data *c, struct pkg_data *p)
c98d5d94 2348{
388e9c81
LB
2349 int i;
2350 struct msr_counter *mp;
2351
c98d5d94
LB
2352 clear_counters(&average.threads, &average.cores, &average.packages);
2353
2354 for_all_cpus(sum_counters, t, c, p);
2355
d4794f25
YG
2356 /* Use the global time delta for the average. */
2357 average.threads.tv_delta = tv_delta;
2358
c98d5d94
LB
2359 average.threads.tsc /= topo.num_cpus;
2360 average.threads.aperf /= topo.num_cpus;
2361 average.threads.mperf /= topo.num_cpus;
2af4f9b8 2362 average.threads.instr_count /= topo.num_cpus;
c98d5d94
LB
2363 average.threads.c1 /= topo.num_cpus;
2364
0de6c0df
LB
2365 if (average.threads.irq_count > 9999999)
2366 sums_need_wide_columns = 1;
2367
c98d5d94
LB
2368 average.cores.c3 /= topo.num_cores;
2369 average.cores.c6 /= topo.num_cores;
2370 average.cores.c7 /= topo.num_cores;
0539ba11 2371 average.cores.mc6_us /= topo.num_cores;
c98d5d94 2372
a99d8730 2373 if (DO_BIC(BIC_Totl_c0))
0b2bb692 2374 average.packages.pkg_wtd_core_c0 /= topo.num_packages;
a99d8730 2375 if (DO_BIC(BIC_Any_c0))
0b2bb692 2376 average.packages.pkg_any_core_c0 /= topo.num_packages;
a99d8730 2377 if (DO_BIC(BIC_GFX_c0))
0b2bb692 2378 average.packages.pkg_any_gfxe_c0 /= topo.num_packages;
a99d8730 2379 if (DO_BIC(BIC_CPUGFX))
0b2bb692 2380 average.packages.pkg_both_core_gfxe_c0 /= topo.num_packages;
0b2bb692 2381
c98d5d94 2382 average.packages.pc2 /= topo.num_packages;
0f47c08d 2383 if (DO_BIC(BIC_Pkgpc3))
ee7e38e3 2384 average.packages.pc3 /= topo.num_packages;
0f47c08d 2385 if (DO_BIC(BIC_Pkgpc6))
ee7e38e3 2386 average.packages.pc6 /= topo.num_packages;
0f47c08d 2387 if (DO_BIC(BIC_Pkgpc7))
ee7e38e3 2388 average.packages.pc7 /= topo.num_packages;
ca58710f
KCA
2389
2390 average.packages.pc8 /= topo.num_packages;
2391 average.packages.pc9 /= topo.num_packages;
2392 average.packages.pc10 /= topo.num_packages;
388e9c81
LB
2393
2394 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
2395 if (mp->format == FORMAT_RAW)
2396 continue;
0de6c0df
LB
2397 if (mp->type == COUNTER_ITEMS) {
2398 if (average.threads.counter[i] > 9999999)
2399 sums_need_wide_columns = 1;
41618e63 2400 continue;
0de6c0df 2401 }
388e9c81
LB
2402 average.threads.counter[i] /= topo.num_cpus;
2403 }
2404 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
2405 if (mp->format == FORMAT_RAW)
2406 continue;
0de6c0df
LB
2407 if (mp->type == COUNTER_ITEMS) {
2408 if (average.cores.counter[i] > 9999999)
2409 sums_need_wide_columns = 1;
2410 }
388e9c81
LB
2411 average.cores.counter[i] /= topo.num_cores;
2412 }
2413 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
2414 if (mp->format == FORMAT_RAW)
2415 continue;
0de6c0df
LB
2416 if (mp->type == COUNTER_ITEMS) {
2417 if (average.packages.counter[i] > 9999999)
2418 sums_need_wide_columns = 1;
2419 }
388e9c81
LB
2420 average.packages.counter[i] /= topo.num_packages;
2421 }
103a8fea
LB
2422}
2423
c98d5d94 2424static unsigned long long rdtsc(void)
103a8fea 2425{
c98d5d94 2426 unsigned int low, high;
15aaa346 2427
1b439f01 2428 asm volatile ("rdtsc":"=a" (low), "=d"(high));
15aaa346 2429
c98d5d94
LB
2430 return low | ((unsigned long long)high) << 32;
2431}
15aaa346 2432
495c7654
LB
2433/*
2434 * Open a file, and exit on failure
2435 */
2436FILE *fopen_or_die(const char *path, const char *mode)
2437{
2438 FILE *filep = fopen(path, mode);
2439
2440 if (!filep)
2441 err(1, "%s: open failed", path);
2442 return filep;
2443}
1b439f01 2444
495c7654
LB
2445/*
2446 * snapshot_sysfs_counter()
2447 *
2448 * return snapshot of given counter
2449 */
2450unsigned long long snapshot_sysfs_counter(char *path)
2451{
2452 FILE *fp;
2453 int retval;
2454 unsigned long long counter;
2455
2456 fp = fopen_or_die(path, "r");
2457
2458 retval = fscanf(fp, "%lld", &counter);
2459 if (retval != 1)
2460 err(1, "snapshot_sysfs_counter(%s)", path);
2461
2462 fclose(fp);
2463
2464 return counter;
2465}
2466
2467int get_mp(int cpu, struct msr_counter *mp, unsigned long long *counterp)
2468{
2469 if (mp->msr_num != 0) {
2470 if (get_msr(cpu, mp->msr_num, counterp))
2471 return -1;
2472 } else {
46c27978 2473 char path[128 + PATH_BYTES];
41618e63
LB
2474
2475 if (mp->flags & SYSFS_PERCPU) {
1b439f01 2476 sprintf(path, "/sys/devices/system/cpu/cpu%d/%s", cpu, mp->path);
41618e63
LB
2477
2478 *counterp = snapshot_sysfs_counter(path);
2479 } else {
2480 *counterp = snapshot_sysfs_counter(mp->path);
2481 }
495c7654
LB
2482 }
2483
2484 return 0;
2485}
2486
a5c6d65d
LB
2487unsigned long long get_uncore_mhz(int package, int die)
2488{
2489 char path[128];
2490
2491 sprintf(path, "/sys/devices/system/cpu/intel_uncore_frequency/package_0%d_die_0%d/current_freq_khz", package,
2492 die);
2493
2494 return (snapshot_sysfs_counter(path) / 1000);
2495}
2496
6d6501d9
BP
2497int get_epb(int cpu)
2498{
2499 char path[128 + PATH_BYTES];
7f1b11ba 2500 unsigned long long msr;
6d6501d9
BP
2501 int ret, epb = -1;
2502 FILE *fp;
2503
2504 sprintf(path, "/sys/devices/system/cpu/cpu%d/power/energy_perf_bias", cpu);
2505
7f1b11ba
BP
2506 fp = fopen(path, "r");
2507 if (!fp)
2508 goto msr_fallback;
6d6501d9
BP
2509
2510 ret = fscanf(fp, "%d", &epb);
2511 if (ret != 1)
2512 err(1, "%s(%s)", __func__, path);
2513
2514 fclose(fp);
2515
2516 return epb;
7f1b11ba
BP
2517
2518msr_fallback:
2519 get_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &msr);
2520
2521 return msr & 0xf;
6d6501d9
BP
2522}
2523
4c2122d4
LB
2524void get_apic_id(struct thread_data *t)
2525{
34041551 2526 unsigned int eax, ebx, ecx, edx;
4c2122d4 2527
34041551
LB
2528 if (DO_BIC(BIC_APIC)) {
2529 eax = ebx = ecx = edx = 0;
2530 __cpuid(1, eax, ebx, ecx, edx);
4c2122d4 2531
34041551
LB
2532 t->apic_id = (ebx >> 24) & 0xff;
2533 }
2534
2535 if (!DO_BIC(BIC_X2APIC))
4c2122d4
LB
2536 return;
2537
c1c10cc7 2538 if (authentic_amd || hygon_genuine) {
34041551 2539 unsigned int topology_extensions;
4c2122d4 2540
34041551
LB
2541 if (max_extended_level < 0x8000001e)
2542 return;
4c2122d4 2543
34041551
LB
2544 eax = ebx = ecx = edx = 0;
2545 __cpuid(0x80000001, eax, ebx, ecx, edx);
1b439f01 2546 topology_extensions = ecx & (1 << 22);
34041551
LB
2547
2548 if (topology_extensions == 0)
2549 return;
2550
2551 eax = ebx = ecx = edx = 0;
2552 __cpuid(0x8000001e, eax, ebx, ecx, edx);
2553
2554 t->x2apic_id = eax;
4c2122d4 2555 return;
34041551 2556 }
4c2122d4 2557
34041551
LB
2558 if (!genuine_intel)
2559 return;
2560
2561 if (max_level < 0xb)
4c2122d4
LB
2562 return;
2563
2564 ecx = 0;
2565 __cpuid(0xb, eax, ebx, ecx, edx);
2566 t->x2apic_id = edx;
2567
34041551 2568 if (debug && (t->apic_id != (t->x2apic_id & 0xff)))
1b439f01 2569 fprintf(outf, "cpu%d: BIOS BUG: apic 0x%x x2apic 0x%x\n", t->cpu_id, t->apic_id, t->x2apic_id);
4c2122d4
LB
2570}
2571
eae97e05
CY
2572int get_core_throt_cnt(int cpu, unsigned long long *cnt)
2573{
2574 char path[128 + PATH_BYTES];
2575 unsigned long long tmp;
2576 FILE *fp;
2577 int ret;
2578
2579 sprintf(path, "/sys/devices/system/cpu/cpu%d/thermal_throttle/core_throttle_count", cpu);
2580 fp = fopen(path, "r");
2581 if (!fp)
2582 return -1;
2583 ret = fscanf(fp, "%lld", &tmp);
5e5fd36c 2584 fclose(fp);
eae97e05
CY
2585 if (ret != 1)
2586 return -1;
eae97e05
CY
2587 *cnt = tmp;
2588
2589 return 0;
2590}
2591
c98d5d94
LB
2592/*
2593 * get_counters(...)
2594 * migrate to cpu
2595 * acquire and record local counters for that cpu
2596 */
2597int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2598{
2599 int cpu = t->cpu_id;
889facbe 2600 unsigned long long msr;
0102b067 2601 int aperf_mperf_retry_count = 0;
388e9c81
LB
2602 struct msr_counter *mp;
2603 int i;
88c3281f 2604
e52966c0 2605 if (cpu_migrate(cpu)) {
3d7772ea 2606 fprintf(outf, "get_counters: Could not migrate to CPU %d\n", cpu);
c98d5d94 2607 return -1;
e52966c0 2608 }
15aaa346 2609
d4794f25
YG
2610 gettimeofday(&t->tv_begin, (struct timezone *)NULL);
2611
4c2122d4
LB
2612 if (first_counter_read)
2613 get_apic_id(t);
0102b067 2614retry:
c98d5d94
LB
2615 t->tsc = rdtsc(); /* we are running on local CPU of interest */
2616
1b439f01 2617 if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz) || soft_c1_residency_display(BIC_Avg_MHz)) {
0102b067
LB
2618 unsigned long long tsc_before, tsc_between, tsc_after, aperf_time, mperf_time;
2619
2620 /*
2621 * The TSC, APERF and MPERF must be read together for
2622 * APERF/MPERF and MPERF/TSC to give accurate results.
2623 *
2624 * Unfortunately, APERF and MPERF are read by
2625 * individual system call, so delays may occur
2626 * between them. If the time to read them
2627 * varies by a large amount, we re-read them.
2628 */
2629
2630 /*
2631 * This initial dummy APERF read has been seen to
2632 * reduce jitter in the subsequent reads.
2633 */
2634
2635 if (get_msr(cpu, MSR_IA32_APERF, &t->aperf))
2636 return -3;
2637
2638 t->tsc = rdtsc(); /* re-read close to APERF */
2639
2640 tsc_before = t->tsc;
2641
9c63a650 2642 if (get_msr(cpu, MSR_IA32_APERF, &t->aperf))
c98d5d94 2643 return -3;
0102b067
LB
2644
2645 tsc_between = rdtsc();
2646
9c63a650 2647 if (get_msr(cpu, MSR_IA32_MPERF, &t->mperf))
c98d5d94 2648 return -4;
0102b067
LB
2649
2650 tsc_after = rdtsc();
2651
2652 aperf_time = tsc_between - tsc_before;
2653 mperf_time = tsc_after - tsc_between;
2654
2655 /*
2656 * If the system call latency to read APERF and MPERF
2657 * differ by more than 2x, then try again.
2658 */
2659 if ((aperf_time > (2 * mperf_time)) || (mperf_time > (2 * aperf_time))) {
2660 aperf_mperf_retry_count++;
2661 if (aperf_mperf_retry_count < 5)
2662 goto retry;
2663 else
1b439f01 2664 warnx("cpu%d jitter %lld %lld", cpu, aperf_time, mperf_time);
0102b067
LB
2665 }
2666 aperf_mperf_retry_count = 0;
2667
b2b34dfe
HC
2668 t->aperf = t->aperf * aperf_mperf_multiplier;
2669 t->mperf = t->mperf * aperf_mperf_multiplier;
c98d5d94
LB
2670 }
2671
2af4f9b8
LB
2672 if (DO_BIC(BIC_IPC))
2673 if (read(get_instr_count_fd(cpu), &t->instr_count, sizeof(long long)) != sizeof(long long))
2674 return -4;
2675
812db3f7 2676 if (DO_BIC(BIC_IRQ))
562a2d37 2677 t->irq_count = irqs_per_cpu[cpu];
812db3f7 2678 if (DO_BIC(BIC_SMI)) {
1ed51011
LB
2679 if (get_msr(cpu, MSR_SMI_COUNT, &msr))
2680 return -5;
2681 t->smi_count = msr & 0xFFFFFFFF;
2682 }
0539ba11 2683 if (DO_BIC(BIC_CPU_c1) && use_c1_residency_msr) {
144b44b1
LB
2684 if (get_msr(cpu, MSR_CORE_C1_RES, &t->c1))
2685 return -6;
2686 }
2687
388e9c81 2688 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
495c7654 2689 if (get_mp(cpu, mp, &t->counter[i]))
388e9c81
LB
2690 return -10;
2691 }
2692
c98d5d94
LB
2693 /* collect core counters only for 1st thread in core */
2694 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
f4fdf2b4 2695 goto done;
c98d5d94 2696
1e9042b9 2697 if (DO_BIC(BIC_CPU_c3) || soft_c1_residency_display(BIC_CPU_c3)) {
c98d5d94
LB
2698 if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3))
2699 return -6;
144b44b1
LB
2700 }
2701
1e9042b9 2702 if ((DO_BIC(BIC_CPU_c6) || soft_c1_residency_display(BIC_CPU_c6)) && !do_knl_cstates) {
c98d5d94
LB
2703 if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6))
2704 return -7;
137f01b3 2705 } else if (do_knl_cstates && soft_c1_residency_display(BIC_CPU_c6)) {
fb5d4327
DC
2706 if (get_msr(cpu, MSR_KNL_CORE_C6_RESIDENCY, &c->c6))
2707 return -7;
c98d5d94
LB
2708 }
2709
7ab5ff49 2710 if (DO_BIC(BIC_CPU_c7) || soft_c1_residency_display(BIC_CPU_c7)) {
c98d5d94
LB
2711 if (get_msr(cpu, MSR_CORE_C7_RESIDENCY, &c->c7))
2712 return -8;
7ab5ff49
ZR
2713 else if (t->is_atom) {
2714 /*
2715 * For Atom CPUs that has core cstate deeper than c6,
2716 * MSR_CORE_C6_RESIDENCY returns residency of cc6 and deeper.
2717 * Minus CC7 (and deeper cstates) residency to get
2718 * accturate cc6 residency.
2719 */
2720 c->c6 -= c->c7;
2721 }
2722 }
c98d5d94 2723
0539ba11
LB
2724 if (DO_BIC(BIC_Mod_c6))
2725 if (get_msr(cpu, MSR_MODULE_C6_RES_MS, &c->mc6_us))
2726 return -8;
2727
812db3f7 2728 if (DO_BIC(BIC_CoreTmp)) {
889facbe
LB
2729 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
2730 return -9;
55279aef 2731 c->core_temp_c = tj_max - ((msr >> 16) & 0x7F);
889facbe
LB
2732 }
2733
eae97e05
CY
2734 if (DO_BIC(BIC_CORE_THROT_CNT))
2735 get_core_throt_cnt(cpu, &c->core_throt_cnt);
2736
86ba263d 2737 if (platform->rapl_msrs & RAPL_AMD_F17H) {
9392bd98
CW
2738 if (get_msr(cpu, MSR_CORE_ENERGY_STAT, &msr))
2739 return -14;
2740 c->core_energy = msr & 0xFFFFFFFF;
2741 }
2742
388e9c81 2743 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
495c7654 2744 if (get_mp(cpu, mp, &c->counter[i]))
388e9c81
LB
2745 return -10;
2746 }
889facbe 2747
c98d5d94
LB
2748 /* collect package counters only for 1st core in package */
2749 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
f4fdf2b4 2750 goto done;
c98d5d94 2751
a99d8730 2752 if (DO_BIC(BIC_Totl_c0)) {
0b2bb692
LB
2753 if (get_msr(cpu, MSR_PKG_WEIGHTED_CORE_C0_RES, &p->pkg_wtd_core_c0))
2754 return -10;
a99d8730
LB
2755 }
2756 if (DO_BIC(BIC_Any_c0)) {
0b2bb692
LB
2757 if (get_msr(cpu, MSR_PKG_ANY_CORE_C0_RES, &p->pkg_any_core_c0))
2758 return -11;
a99d8730
LB
2759 }
2760 if (DO_BIC(BIC_GFX_c0)) {
0b2bb692
LB
2761 if (get_msr(cpu, MSR_PKG_ANY_GFXE_C0_RES, &p->pkg_any_gfxe_c0))
2762 return -12;
a99d8730
LB
2763 }
2764 if (DO_BIC(BIC_CPUGFX)) {
0b2bb692
LB
2765 if (get_msr(cpu, MSR_PKG_BOTH_CORE_GFXE_C0_RES, &p->pkg_both_core_gfxe_c0))
2766 return -13;
2767 }
0f47c08d 2768 if (DO_BIC(BIC_Pkgpc3))
c98d5d94
LB
2769 if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3))
2770 return -9;
0f47c08d 2771 if (DO_BIC(BIC_Pkgpc6)) {
0539ba11
LB
2772 if (do_slm_cstates) {
2773 if (get_msr(cpu, MSR_ATOM_PKG_C6_RESIDENCY, &p->pc6))
2774 return -10;
2775 } else {
2776 if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6))
2777 return -10;
2778 }
2779 }
2780
0f47c08d 2781 if (DO_BIC(BIC_Pkgpc2))
c98d5d94
LB
2782 if (get_msr(cpu, MSR_PKG_C2_RESIDENCY, &p->pc2))
2783 return -11;
0f47c08d 2784 if (DO_BIC(BIC_Pkgpc7))
c98d5d94
LB
2785 if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7))
2786 return -12;
0f47c08d 2787 if (DO_BIC(BIC_Pkgpc8))
ca58710f
KCA
2788 if (get_msr(cpu, MSR_PKG_C8_RESIDENCY, &p->pc8))
2789 return -13;
0f47c08d 2790 if (DO_BIC(BIC_Pkgpc9))
ca58710f
KCA
2791 if (get_msr(cpu, MSR_PKG_C9_RESIDENCY, &p->pc9))
2792 return -13;
0f47c08d 2793 if (DO_BIC(BIC_Pkgpc10))
ca58710f
KCA
2794 if (get_msr(cpu, MSR_PKG_C10_RESIDENCY, &p->pc10))
2795 return -13;
0f47c08d 2796
be0e54c4
LB
2797 if (DO_BIC(BIC_CPU_LPI))
2798 p->cpu_lpi = cpuidle_cur_cpu_lpi_us;
2799 if (DO_BIC(BIC_SYS_LPI))
2800 p->sys_lpi = cpuidle_cur_sys_lpi_us;
2801
86ba263d 2802 if (platform->rapl_msrs & RAPL_PKG) {
9972d5d8 2803 if (get_msr_sum(cpu, MSR_PKG_ENERGY_STATUS, &msr))
889facbe 2804 return -13;
9972d5d8 2805 p->energy_pkg = msr;
889facbe 2806 }
86ba263d 2807 if (platform->rapl_msrs & RAPL_CORE_ENERGY_STATUS) {
9972d5d8 2808 if (get_msr_sum(cpu, MSR_PP0_ENERGY_STATUS, &msr))
889facbe 2809 return -14;
9972d5d8 2810 p->energy_cores = msr;
889facbe 2811 }
86ba263d 2812 if (platform->rapl_msrs & RAPL_DRAM) {
9972d5d8 2813 if (get_msr_sum(cpu, MSR_DRAM_ENERGY_STATUS, &msr))
889facbe 2814 return -15;
9972d5d8 2815 p->energy_dram = msr;
889facbe 2816 }
86ba263d 2817 if (platform->rapl_msrs & RAPL_GFX) {
9972d5d8 2818 if (get_msr_sum(cpu, MSR_PP1_ENERGY_STATUS, &msr))
889facbe 2819 return -16;
9972d5d8 2820 p->energy_gfx = msr;
889facbe 2821 }
86ba263d 2822 if (platform->rapl_msrs & RAPL_PKG_PERF_STATUS) {
9972d5d8 2823 if (get_msr_sum(cpu, MSR_PKG_PERF_STATUS, &msr))
889facbe 2824 return -16;
9972d5d8 2825 p->rapl_pkg_perf_status = msr;
889facbe 2826 }
86ba263d 2827 if (platform->rapl_msrs & RAPL_DRAM_PERF_STATUS) {
9972d5d8 2828 if (get_msr_sum(cpu, MSR_DRAM_PERF_STATUS, &msr))
889facbe 2829 return -16;
9972d5d8 2830 p->rapl_dram_perf_status = msr;
889facbe 2831 }
86ba263d 2832 if (platform->rapl_msrs & RAPL_AMD_F17H) {
9972d5d8 2833 if (get_msr_sum(cpu, MSR_PKG_ENERGY_STAT, &msr))
3316f99a 2834 return -13;
9972d5d8 2835 p->energy_pkg = msr;
3316f99a 2836 }
812db3f7 2837 if (DO_BIC(BIC_PkgTmp)) {
889facbe
LB
2838 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
2839 return -17;
55279aef 2840 p->pkg_temp_c = tj_max - ((msr >> 16) & 0x7F);
889facbe 2841 }
fdf676e5 2842
812db3f7 2843 if (DO_BIC(BIC_GFX_rc6))
fdf676e5
LB
2844 p->gfx_rc6_ms = gfx_cur_rc6_ms;
2845
a5c6d65d
LB
2846 /* n.b. assume die0 uncore frequency applies to whole package */
2847 if (DO_BIC(BIC_UNCORE_MHZ))
2848 p->uncore_mhz = get_uncore_mhz(p->package_id, 0);
2849
812db3f7 2850 if (DO_BIC(BIC_GFXMHz))
27d47356
LB
2851 p->gfx_mhz = gfx_cur_mhz;
2852
b4b91569
RA
2853 if (DO_BIC(BIC_GFXACTMHz))
2854 p->gfx_act_mhz = gfx_act_mhz;
2855
388e9c81 2856 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
495c7654 2857 if (get_mp(cpu, mp, &p->counter[i]))
388e9c81
LB
2858 return -10;
2859 }
f4fdf2b4
LB
2860done:
2861 gettimeofday(&t->tv_end, (struct timezone *)NULL);
388e9c81 2862
15aaa346 2863 return 0;
103a8fea
LB
2864}
2865
ee7e38e3
LB
2866/*
2867 * MSR_PKG_CST_CONFIG_CONTROL decoding for pkg_cstate_limit:
2868 * If you change the values, note they are used both in comparisons
2869 * (>= PCL__7) and to index pkg_cstate_limit_strings[].
2870 */
2871
1b439f01
LB
2872#define PCLUKN 0 /* Unknown */
2873#define PCLRSV 1 /* Reserved */
2874#define PCL__0 2 /* PC0 */
2875#define PCL__1 3 /* PC1 */
2876#define PCL__2 4 /* PC2 */
2877#define PCL__3 5 /* PC3 */
2878#define PCL__4 6 /* PC4 */
2879#define PCL__6 7 /* PC6 */
2880#define PCL_6N 8 /* PC6 No Retention */
2881#define PCL_6R 9 /* PC6 Retention */
2882#define PCL__7 10 /* PC7 */
2883#define PCL_7S 11 /* PC7 Shrink */
2884#define PCL__8 12 /* PC8 */
2885#define PCL__9 13 /* PC9 */
2886#define PCL_10 14 /* PC10 */
2887#define PCLUNL 15 /* Unlimited */
ee7e38e3
LB
2888
2889int pkg_cstate_limit = PCLUKN;
2890char *pkg_cstate_limit_strings[] = { "reserved", "unknown", "pc0", "pc1", "pc2",
1b439f01
LB
2891 "pc3", "pc4", "pc6", "pc6n", "pc6r", "pc7", "pc7s", "pc8", "pc9", "pc10", "unlimited"
2892};
a2b7b749 2893
1b439f01
LB
2894int nhm_pkg_cstate_limits[16] =
2895 { PCL__0, PCL__1, PCL__3, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
38c6663a
LB
2896 PCLRSV, PCLRSV
2897};
2898
1b439f01
LB
2899int snb_pkg_cstate_limits[16] =
2900 { PCL__0, PCL__2, PCL_6N, PCL_6R, PCL__7, PCL_7S, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
38c6663a
LB
2901 PCLRSV, PCLRSV
2902};
2903
1b439f01
LB
2904int hsw_pkg_cstate_limits[16] =
2905 { PCL__0, PCL__2, PCL__3, PCL__6, PCL__7, PCL_7S, PCL__8, PCL__9, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
38c6663a
LB
2906 PCLRSV, PCLRSV
2907};
2908
1b439f01
LB
2909int slv_pkg_cstate_limits[16] =
2910 { PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
38c6663a
LB
2911 PCL__6, PCL__7
2912};
2913
1b439f01
LB
2914int amt_pkg_cstate_limits[16] =
2915 { PCLUNL, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
38c6663a
LB
2916 PCLRSV, PCLRSV
2917};
2918
1b439f01
LB
2919int phi_pkg_cstate_limits[16] =
2920 { PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
38c6663a
LB
2921 PCLRSV, PCLRSV
2922};
2923
1b439f01
LB
2924int glm_pkg_cstate_limits[16] =
2925 { PCLUNL, PCL__1, PCL__3, PCL__6, PCL__7, PCL_7S, PCL__8, PCL__9, PCL_10, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
38c6663a
LB
2926 PCLRSV, PCLRSV
2927};
2928
1b439f01
LB
2929int skx_pkg_cstate_limits[16] =
2930 { PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
38c6663a
LB
2931 PCLRSV, PCLRSV
2932};
2933
1b439f01 2934int icx_pkg_cstate_limits[16] =
a1b6f487 2935 { PCL__0, PCL__2, PCL__6, PCL__6, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
38c6663a
LB
2936 PCLRSV, PCLRSV
2937};
1b439f01 2938
3989fc89
ZR
2939void probe_cst_limit(void)
2940{
2941 unsigned long long msr;
2942 int *pkg_cstate_limits;
2943
fcfa1ce0 2944 if (!platform->has_nhm_msrs)
3989fc89
ZR
2945 return;
2946
2947 switch (platform->cst_limit) {
2948 case CST_LIMIT_NHM:
2949 pkg_cstate_limits = nhm_pkg_cstate_limits;
2950 break;
2951 case CST_LIMIT_SNB:
2952 pkg_cstate_limits = snb_pkg_cstate_limits;
2953 break;
2954 case CST_LIMIT_HSW:
2955 pkg_cstate_limits = hsw_pkg_cstate_limits;
2956 break;
2957 case CST_LIMIT_SKX:
2958 pkg_cstate_limits = skx_pkg_cstate_limits;
2959 break;
2960 case CST_LIMIT_ICX:
2961 pkg_cstate_limits = icx_pkg_cstate_limits;
2962 break;
2963 case CST_LIMIT_SLV:
2964 pkg_cstate_limits = slv_pkg_cstate_limits;
2965 break;
2966 case CST_LIMIT_AMT:
2967 pkg_cstate_limits = amt_pkg_cstate_limits;
2968 break;
2969 case CST_LIMIT_KNL:
2970 pkg_cstate_limits = phi_pkg_cstate_limits;
2971 break;
2972 case CST_LIMIT_GMT:
2973 pkg_cstate_limits = glm_pkg_cstate_limits;
2974 break;
2975 default:
2976 return;
2977 }
2978
2979 get_msr(base_cpu, MSR_PKG_CST_CONFIG_CONTROL, &msr);
2980 pkg_cstate_limit = pkg_cstate_limits[msr & 0xF];
2981}
2982
aeb01e6d
CY
2983void prewake_cstate_probe(unsigned int family, unsigned int model);
2984
8b7199c0 2985static void dump_platform_info(void)
103a8fea
LB
2986{
2987 unsigned long long msr;
2988 unsigned int ratio;
2989
ec0adc53 2990 get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
103a8fea 2991
b7d8c148 2992 fprintf(outf, "cpu%d: MSR_PLATFORM_INFO: 0x%08llx\n", base_cpu, msr);
6574a5d5 2993
103a8fea 2994 ratio = (msr >> 40) & 0xFF;
1b439f01 2995 fprintf(outf, "%d * %.1f = %.1f MHz max efficiency frequency\n", ratio, bclk, ratio * bclk);
103a8fea
LB
2996
2997 ratio = (msr >> 8) & 0xFF;
1b439f01 2998 fprintf(outf, "%d * %.1f = %.1f MHz base frequency\n", ratio, bclk, ratio * bclk);
103a8fea 2999
7ce7d5de 3000 get_msr(base_cpu, MSR_IA32_POWER_CTL, &msr);
b7d8c148 3001 fprintf(outf, "cpu%d: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n",
bfae2052 3002 base_cpu, msr, msr & 0x2 ? "EN" : "DIS");
67920418 3003
aeb01e6d
CY
3004 /* C-state Pre-wake Disable (CSTATE_PREWAKE_DISABLE) */
3005 if (dis_cstate_prewake)
1b439f01 3006 fprintf(outf, "C-state Pre-wake: %sabled\n", msr & 0x40000000 ? "DIS" : "EN");
aeb01e6d 3007
fcd17211
LB
3008 return;
3009}
3010
a3943dea 3011static void dump_turbo_ratio_limit2(void)
fcd17211
LB
3012{
3013 unsigned long long msr;
3014 unsigned int ratio;
3015
7ce7d5de 3016 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT2, &msr);
fcd17211 3017
b7d8c148 3018 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT2: 0x%08llx\n", base_cpu, msr);
fcd17211
LB
3019
3020 ratio = (msr >> 8) & 0xFF;
3021 if (ratio)
1b439f01 3022 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 18 active cores\n", ratio, bclk, ratio * bclk);
fcd17211
LB
3023
3024 ratio = (msr >> 0) & 0xFF;
3025 if (ratio)
1b439f01 3026 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 17 active cores\n", ratio, bclk, ratio * bclk);
fcd17211
LB
3027 return;
3028}
3029
a3943dea 3030static void dump_turbo_ratio_limit1(void)
fcd17211
LB
3031{
3032 unsigned long long msr;
3033 unsigned int ratio;
6574a5d5 3034
7ce7d5de 3035 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &msr);
6574a5d5 3036
b7d8c148 3037 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, msr);
6574a5d5
LB
3038
3039 ratio = (msr >> 56) & 0xFF;
3040 if (ratio)
1b439f01 3041 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 16 active cores\n", ratio, bclk, ratio * bclk);
6574a5d5
LB
3042
3043 ratio = (msr >> 48) & 0xFF;
3044 if (ratio)
1b439f01 3045 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 15 active cores\n", ratio, bclk, ratio * bclk);
6574a5d5
LB
3046
3047 ratio = (msr >> 40) & 0xFF;
3048 if (ratio)
1b439f01 3049 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 14 active cores\n", ratio, bclk, ratio * bclk);
6574a5d5
LB
3050
3051 ratio = (msr >> 32) & 0xFF;
3052 if (ratio)
1b439f01 3053 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 13 active cores\n", ratio, bclk, ratio * bclk);
6574a5d5
LB
3054
3055 ratio = (msr >> 24) & 0xFF;
3056 if (ratio)
1b439f01 3057 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 12 active cores\n", ratio, bclk, ratio * bclk);
6574a5d5
LB
3058
3059 ratio = (msr >> 16) & 0xFF;
3060 if (ratio)
1b439f01 3061 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 11 active cores\n", ratio, bclk, ratio * bclk);
6574a5d5
LB
3062
3063 ratio = (msr >> 8) & 0xFF;
3064 if (ratio)
1b439f01 3065 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 10 active cores\n", ratio, bclk, ratio * bclk);
6574a5d5
LB
3066
3067 ratio = (msr >> 0) & 0xFF;
3068 if (ratio)
1b439f01 3069 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 9 active cores\n", ratio, bclk, ratio * bclk);
fcd17211
LB
3070 return;
3071}
1b439f01 3072
10d85d85 3073static void dump_turbo_ratio_limits(int trl_msr_offset)
fcd17211 3074{
31e07522 3075 unsigned long long msr, core_counts;
5d622845 3076 int shift;
103a8fea 3077
4af184ee
LB
3078 get_msr(base_cpu, trl_msr_offset, &msr);
3079 fprintf(outf, "cpu%d: MSR_%sTURBO_RATIO_LIMIT: 0x%08llx\n",
884a1f95 3080 base_cpu, trl_msr_offset == MSR_SECONDARY_TURBO_RATIO_LIMIT ? "SECONDARY_" : "", msr);
6574a5d5 3081
10d85d85 3082 if (platform->trl_msrs & TRL_CORECOUNT) {
31e07522
LB
3083 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &core_counts);
3084 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, core_counts);
3085 } else {
3086 core_counts = 0x0807060504030201;
3087 }
3088
5d622845
LB
3089 for (shift = 56; shift >= 0; shift -= 8) {
3090 unsigned int ratio, group_size;
6574a5d5 3091
5d622845
LB
3092 ratio = (msr >> shift) & 0xFF;
3093 group_size = (core_counts >> shift) & 0xFF;
3094 if (ratio)
3095 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
3096 ratio, bclk, ratio * bclk, group_size);
3097 }
103a8fea 3098
fcd17211
LB
3099 return;
3100}
3a9a941d 3101
1b439f01 3102static void dump_atom_turbo_ratio_limits(void)
0f7887c4
LB
3103{
3104 unsigned long long msr;
3105 unsigned int ratio;
3106
3107 get_msr(base_cpu, MSR_ATOM_CORE_RATIOS, &msr);
3108 fprintf(outf, "cpu%d: MSR_ATOM_CORE_RATIOS: 0x%08llx\n", base_cpu, msr & 0xFFFFFFFF);
3109
3110 ratio = (msr >> 0) & 0x3F;
3111 if (ratio)
1b439f01 3112 fprintf(outf, "%d * %.1f = %.1f MHz minimum operating frequency\n", ratio, bclk, ratio * bclk);
0f7887c4
LB
3113
3114 ratio = (msr >> 8) & 0x3F;
3115 if (ratio)
1b439f01 3116 fprintf(outf, "%d * %.1f = %.1f MHz low frequency mode (LFM)\n", ratio, bclk, ratio * bclk);
0f7887c4
LB
3117
3118 ratio = (msr >> 16) & 0x3F;
3119 if (ratio)
1b439f01 3120 fprintf(outf, "%d * %.1f = %.1f MHz base frequency\n", ratio, bclk, ratio * bclk);
0f7887c4
LB
3121
3122 get_msr(base_cpu, MSR_ATOM_CORE_TURBO_RATIOS, &msr);
3123 fprintf(outf, "cpu%d: MSR_ATOM_CORE_TURBO_RATIOS: 0x%08llx\n", base_cpu, msr & 0xFFFFFFFF);
3124
3125 ratio = (msr >> 24) & 0x3F;
3126 if (ratio)
1b439f01 3127 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 4 active cores\n", ratio, bclk, ratio * bclk);
0f7887c4
LB
3128
3129 ratio = (msr >> 16) & 0x3F;
3130 if (ratio)
1b439f01 3131 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 3 active cores\n", ratio, bclk, ratio * bclk);
0f7887c4
LB
3132
3133 ratio = (msr >> 8) & 0x3F;
3134 if (ratio)
1b439f01 3135 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 2 active cores\n", ratio, bclk, ratio * bclk);
0f7887c4
LB
3136
3137 ratio = (msr >> 0) & 0x3F;
3138 if (ratio)
1b439f01 3139 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 1 active core\n", ratio, bclk, ratio * bclk);
0f7887c4
LB
3140}
3141
1b439f01 3142static void dump_knl_turbo_ratio_limits(void)
fb5d4327 3143{
cbf97aba
HC
3144 const unsigned int buckets_no = 7;
3145
fb5d4327 3146 unsigned long long msr;
cbf97aba
HC
3147 int delta_cores, delta_ratio;
3148 int i, b_nr;
3149 unsigned int cores[buckets_no];
3150 unsigned int ratio[buckets_no];
fb5d4327 3151
ebf5926a 3152 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
fb5d4327 3153
1b439f01 3154 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", base_cpu, msr);
fb5d4327 3155
1e3ec5cd 3156 /*
fb5d4327 3157 * Turbo encoding in KNL is as follows:
cbf97aba
HC
3158 * [0] -- Reserved
3159 * [7:1] -- Base value of number of active cores of bucket 1.
fb5d4327
DC
3160 * [15:8] -- Base value of freq ratio of bucket 1.
3161 * [20:16] -- +ve delta of number of active cores of bucket 2.
3162 * i.e. active cores of bucket 2 =
3163 * active cores of bucket 1 + delta
3164 * [23:21] -- Negative delta of freq ratio of bucket 2.
3165 * i.e. freq ratio of bucket 2 =
3166 * freq ratio of bucket 1 - delta
3167 * [28:24]-- +ve delta of number of active cores of bucket 3.
3168 * [31:29]-- -ve delta of freq ratio of bucket 3.
3169 * [36:32]-- +ve delta of number of active cores of bucket 4.
3170 * [39:37]-- -ve delta of freq ratio of bucket 4.
3171 * [44:40]-- +ve delta of number of active cores of bucket 5.
3172 * [47:45]-- -ve delta of freq ratio of bucket 5.
3173 * [52:48]-- +ve delta of number of active cores of bucket 6.
3174 * [55:53]-- -ve delta of freq ratio of bucket 6.
3175 * [60:56]-- +ve delta of number of active cores of bucket 7.
3176 * [63:61]-- -ve delta of freq ratio of bucket 7.
3177 */
cbf97aba
HC
3178
3179 b_nr = 0;
3180 cores[b_nr] = (msr & 0xFF) >> 1;
3181 ratio[b_nr] = (msr >> 8) & 0xFF;
3182
3183 for (i = 16; i < 64; i += 8) {
fb5d4327 3184 delta_cores = (msr >> i) & 0x1F;
cbf97aba
HC
3185 delta_ratio = (msr >> (i + 5)) & 0x7;
3186
3187 cores[b_nr + 1] = cores[b_nr] + delta_cores;
3188 ratio[b_nr + 1] = ratio[b_nr] - delta_ratio;
3189 b_nr++;
fb5d4327 3190 }
cbf97aba
HC
3191
3192 for (i = buckets_no - 1; i >= 0; i--)
3193 if (i > 0 ? ratio[i] != ratio[i - 1] : 1)
b7d8c148 3194 fprintf(outf,
710f273b 3195 "%d * %.1f = %.1f MHz max turbo %d active cores\n",
cbf97aba 3196 ratio[i], bclk, ratio[i] * bclk, cores[i]);
fb5d4327
DC
3197}
3198
8b7199c0 3199static void dump_cst_cfg(void)
fcd17211
LB
3200{
3201 unsigned long long msr;
3202
1df2e55a 3203 get_msr(base_cpu, MSR_PKG_CST_CONFIG_CONTROL, &msr);
fcd17211 3204
1df2e55a 3205 fprintf(outf, "cpu%d: MSR_PKG_CST_CONFIG_CONTROL: 0x%08llx", base_cpu, msr);
fcd17211 3206
3e8b62bf 3207 fprintf(outf, " (%s%s%s%s%slocked, pkg-cstate-limit=%d (%s)",
fcd17211
LB
3208 (msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "",
3209 (msr & SNB_C1_AUTO_UNDEMOTE) ? "UNdemote-C1, " : "",
3210 (msr & NHM_C3_AUTO_DEMOTE) ? "demote-C3, " : "",
3211 (msr & NHM_C1_AUTO_DEMOTE) ? "demote-C1, " : "",
1b439f01 3212 (msr & (1 << 15)) ? "" : "UN", (unsigned int)msr & 0xF, pkg_cstate_limit_strings[pkg_cstate_limit]);
ac980e13
AB
3213
3214#define AUTOMATIC_CSTATE_CONVERSION (1UL << 16)
d90120bf 3215 if (platform->has_cst_auto_convension) {
1b439f01 3216 fprintf(outf, ", automatic c-state conversion=%s", (msr & AUTOMATIC_CSTATE_CONVERSION) ? "on" : "off");
ac980e13
AB
3217 }
3218
3219 fprintf(outf, ")\n");
3220
fcd17211 3221 return;
103a8fea
LB
3222}
3223
1b439f01 3224static void dump_config_tdp(void)
6fb3143b
LB
3225{
3226 unsigned long long msr;
3227
3228 get_msr(base_cpu, MSR_CONFIG_TDP_NOMINAL, &msr);
b7d8c148 3229 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_NOMINAL: 0x%08llx", base_cpu, msr);
685b535b 3230 fprintf(outf, " (base_ratio=%d)\n", (unsigned int)msr & 0xFF);
6fb3143b
LB
3231
3232 get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_1, &msr);
b7d8c148 3233 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_1: 0x%08llx (", base_cpu, msr);
6fb3143b 3234 if (msr) {
685b535b
CY
3235 fprintf(outf, "PKG_MIN_PWR_LVL1=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
3236 fprintf(outf, "PKG_MAX_PWR_LVL1=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
3237 fprintf(outf, "LVL1_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
3238 fprintf(outf, "PKG_TDP_LVL1=%d", (unsigned int)(msr) & 0x7FFF);
6fb3143b 3239 }
b7d8c148 3240 fprintf(outf, ")\n");
6fb3143b
LB
3241
3242 get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_2, &msr);
b7d8c148 3243 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_2: 0x%08llx (", base_cpu, msr);
6fb3143b 3244 if (msr) {
685b535b
CY
3245 fprintf(outf, "PKG_MIN_PWR_LVL2=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
3246 fprintf(outf, "PKG_MAX_PWR_LVL2=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
3247 fprintf(outf, "LVL2_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
3248 fprintf(outf, "PKG_TDP_LVL2=%d", (unsigned int)(msr) & 0x7FFF);
6fb3143b 3249 }
b7d8c148 3250 fprintf(outf, ")\n");
6fb3143b
LB
3251
3252 get_msr(base_cpu, MSR_CONFIG_TDP_CONTROL, &msr);
b7d8c148 3253 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_CONTROL: 0x%08llx (", base_cpu, msr);
6fb3143b 3254 if ((msr) & 0x3)
b7d8c148
LB
3255 fprintf(outf, "TDP_LEVEL=%d ", (unsigned int)(msr) & 0x3);
3256 fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
3257 fprintf(outf, ")\n");
36229897 3258
6fb3143b 3259 get_msr(base_cpu, MSR_TURBO_ACTIVATION_RATIO, &msr);
b7d8c148 3260 fprintf(outf, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu, msr);
685b535b 3261 fprintf(outf, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0xFF);
b7d8c148
LB
3262 fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
3263 fprintf(outf, ")\n");
6fb3143b 3264}
5a63426e 3265
1b439f01 3266unsigned int irtl_time_units[] = { 1, 32, 1024, 32768, 1048576, 33554432, 0, 0 };
5a63426e
LB
3267
3268void print_irtl(void)
3269{
3270 unsigned long long msr;
3271
3272 get_msr(base_cpu, MSR_PKGC3_IRTL, &msr);
3273 fprintf(outf, "cpu%d: MSR_PKGC3_IRTL: 0x%08llx (", base_cpu, msr);
3274 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
3275 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
3276
3277 get_msr(base_cpu, MSR_PKGC6_IRTL, &msr);
3278 fprintf(outf, "cpu%d: MSR_PKGC6_IRTL: 0x%08llx (", base_cpu, msr);
3279 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
3280 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
3281
3282 get_msr(base_cpu, MSR_PKGC7_IRTL, &msr);
3283 fprintf(outf, "cpu%d: MSR_PKGC7_IRTL: 0x%08llx (", base_cpu, msr);
3284 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
3285 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
3286
3287 if (!do_irtl_hsw)
3288 return;
3289
3290 get_msr(base_cpu, MSR_PKGC8_IRTL, &msr);
3291 fprintf(outf, "cpu%d: MSR_PKGC8_IRTL: 0x%08llx (", base_cpu, msr);
3292 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
3293 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
3294
3295 get_msr(base_cpu, MSR_PKGC9_IRTL, &msr);
3296 fprintf(outf, "cpu%d: MSR_PKGC9_IRTL: 0x%08llx (", base_cpu, msr);
3297 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
3298 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
3299
3300 get_msr(base_cpu, MSR_PKGC10_IRTL, &msr);
3301 fprintf(outf, "cpu%d: MSR_PKGC10_IRTL: 0x%08llx (", base_cpu, msr);
3302 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
3303 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
3304
3305}
1b439f01 3306
36229897
LB
3307void free_fd_percpu(void)
3308{
3309 int i;
3310
01a67adf 3311 for (i = 0; i < topo.max_cpu_num + 1; ++i) {
36229897
LB
3312 if (fd_percpu[i] != 0)
3313 close(fd_percpu[i]);
3314 }
3315
3316 free(fd_percpu);
6fb3143b
LB
3317}
3318
c98d5d94 3319void free_all_buffers(void)
103a8fea 3320{
0e2d8f05
LB
3321 int i;
3322
c98d5d94
LB
3323 CPU_FREE(cpu_present_set);
3324 cpu_present_set = NULL;
36229897 3325 cpu_present_setsize = 0;
103a8fea 3326
c98d5d94
LB
3327 CPU_FREE(cpu_affinity_set);
3328 cpu_affinity_set = NULL;
3329 cpu_affinity_setsize = 0;
103a8fea 3330
c98d5d94
LB
3331 free(thread_even);
3332 free(core_even);
3333 free(package_even);
103a8fea 3334
c98d5d94
LB
3335 thread_even = NULL;
3336 core_even = NULL;
3337 package_even = NULL;
103a8fea 3338
c98d5d94
LB
3339 free(thread_odd);
3340 free(core_odd);
3341 free(package_odd);
103a8fea 3342
c98d5d94
LB
3343 thread_odd = NULL;
3344 core_odd = NULL;
3345 package_odd = NULL;
103a8fea 3346
c98d5d94
LB
3347 free(output_buffer);
3348 output_buffer = NULL;
3349 outp = NULL;
36229897
LB
3350
3351 free_fd_percpu();
562a2d37
LB
3352
3353 free(irq_column_2_cpu);
3354 free(irqs_per_cpu);
0e2d8f05
LB
3355
3356 for (i = 0; i <= topo.max_cpu_num; ++i) {
3357 if (cpus[i].put_ids)
3358 CPU_FREE(cpus[i].put_ids);
3359 }
3360 free(cpus);
103a8fea
LB
3361}
3362
c98d5d94 3363/*
95aebc44 3364 * Parse a file containing a single int.
6de68fe1
LB
3365 * Return 0 if file can not be opened
3366 * Exit if file can be opened, but can not be parsed
c98d5d94 3367 */
95aebc44 3368int parse_int_file(const char *fmt, ...)
103a8fea 3369{
95aebc44
JT
3370 va_list args;
3371 char path[PATH_MAX];
c98d5d94 3372 FILE *filep;
95aebc44 3373 int value;
103a8fea 3374
95aebc44
JT
3375 va_start(args, fmt);
3376 vsnprintf(path, sizeof(path), fmt, args);
3377 va_end(args);
6de68fe1
LB
3378 filep = fopen(path, "r");
3379 if (!filep)
3380 return 0;
b2c95d90
JT
3381 if (fscanf(filep, "%d", &value) != 1)
3382 err(1, "%s: failed to parse number from file", path);
c98d5d94 3383 fclose(filep);
95aebc44
JT
3384 return value;
3385}
3386
c98d5d94
LB
3387/*
3388 * cpu_is_first_core_in_package(cpu)
3389 * return 1 if given CPU is 1st core in package
3390 */
3391int cpu_is_first_core_in_package(int cpu)
103a8fea 3392{
95aebc44 3393 return cpu == parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_siblings_list", cpu);
103a8fea
LB
3394}
3395
3396int get_physical_package_id(int cpu)
3397{
95aebc44 3398 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu);
103a8fea
LB
3399}
3400
6de68fe1
LB
3401int get_die_id(int cpu)
3402{
3403 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/die_id", cpu);
3404}
3405
103a8fea
LB
3406int get_core_id(int cpu)
3407{
95aebc44 3408 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", cpu);
103a8fea
LB
3409}
3410
ef605741
PB
3411void set_node_data(void)
3412{
2ffbb224
PB
3413 int pkg, node, lnode, cpu, cpux;
3414 int cpu_count;
3415
3416 /* initialize logical_node_id */
3417 for (cpu = 0; cpu <= topo.max_cpu_num; ++cpu)
3418 cpus[cpu].logical_node_id = -1;
3419
3420 cpu_count = 0;
3421 for (pkg = 0; pkg < topo.num_packages; pkg++) {
3422 lnode = 0;
3423 for (cpu = 0; cpu <= topo.max_cpu_num; ++cpu) {
3424 if (cpus[cpu].physical_package_id != pkg)
3425 continue;
3426 /* find a cpu with an unset logical_node_id */
3427 if (cpus[cpu].logical_node_id != -1)
3428 continue;
3429 cpus[cpu].logical_node_id = lnode;
3430 node = cpus[cpu].physical_node_id;
3431 cpu_count++;
3432 /*
3433 * find all matching cpus on this pkg and set
3434 * the logical_node_id
3435 */
3436 for (cpux = cpu; cpux <= topo.max_cpu_num; cpux++) {
1b439f01 3437 if ((cpus[cpux].physical_package_id == pkg) && (cpus[cpux].physical_node_id == node)) {
2ffbb224
PB
3438 cpus[cpux].logical_node_id = lnode;
3439 cpu_count++;
3440 }
3441 }
3442 lnode++;
3443 if (lnode > topo.nodes_per_pkg)
3444 topo.nodes_per_pkg = lnode;
3445 }
3446 if (cpu_count >= topo.max_cpu_num)
3447 break;
ef605741 3448 }
ef605741
PB
3449}
3450
3451int get_physical_node_id(struct cpu_topology *thiscpu)
c98d5d94
LB
3452{
3453 char path[80];
3454 FILE *filep;
0e2d8f05
LB
3455 int i;
3456 int cpu = thiscpu->logical_cpu_id;
e275b388 3457
0e2d8f05 3458 for (i = 0; i <= topo.max_cpu_num; i++) {
1b439f01 3459 sprintf(path, "/sys/devices/system/cpu/cpu%d/node%i/cpulist", cpu, i);
0e2d8f05
LB
3460 filep = fopen(path, "r");
3461 if (!filep)
3462 continue;
3463 fclose(filep);
3464 return i;
e275b388 3465 }
0e2d8f05
LB
3466 return -1;
3467}
c98d5d94 3468
0e2d8f05
LB
3469int get_thread_siblings(struct cpu_topology *thiscpu)
3470{
3471 char path[80], character;
3472 FILE *filep;
3473 unsigned long map;
8cb48b32 3474 int so, shift, sib_core;
0e2d8f05
LB
3475 int cpu = thiscpu->logical_cpu_id;
3476 int offset = topo.max_cpu_num + 1;
3477 size_t size;
8cb48b32 3478 int thread_id = 0;
0e2d8f05
LB
3479
3480 thiscpu->put_ids = CPU_ALLOC((topo.max_cpu_num + 1));
8cb48b32
PB
3481 if (thiscpu->thread_id < 0)
3482 thiscpu->thread_id = thread_id++;
0e2d8f05
LB
3483 if (!thiscpu->put_ids)
3484 return -1;
3485
3486 size = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
3487 CPU_ZERO_S(size, thiscpu->put_ids);
3488
1b439f01 3489 sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", cpu);
3d7772ea
LB
3490 filep = fopen(path, "r");
3491
3492 if (!filep) {
3493 warnx("%s: open failed", path);
3494 return -1;
3495 }
0e2d8f05
LB
3496 do {
3497 offset -= BITMASK_SIZE;
8173c336
BH
3498 if (fscanf(filep, "%lx%c", &map, &character) != 2)
3499 err(1, "%s: failed to parse file", path);
0e2d8f05
LB
3500 for (shift = 0; shift < BITMASK_SIZE; shift++) {
3501 if ((map >> shift) & 0x1) {
8cb48b32
PB
3502 so = shift + offset;
3503 sib_core = get_core_id(so);
3504 if (sib_core == thiscpu->physical_core_id) {
3505 CPU_SET_S(so, size, thiscpu->put_ids);
1b439f01
LB
3506 if ((so != cpu) && (cpus[so].thread_id < 0))
3507 cpus[so].thread_id = thread_id++;
8cb48b32 3508 }
0e2d8f05
LB
3509 }
3510 }
e13da9a1 3511 } while (character == ',');
c98d5d94 3512 fclose(filep);
0e2d8f05
LB
3513
3514 return CPU_COUNT_S(size, thiscpu->put_ids);
c98d5d94
LB
3515}
3516
103a8fea 3517/*
c98d5d94
LB
3518 * run func(thread, core, package) in topology order
3519 * skip non-present cpus
103a8fea
LB
3520 */
3521
1b439f01
LB
3522int for_all_cpus_2(int (func) (struct thread_data *, struct core_data *,
3523 struct pkg_data *, struct thread_data *, struct core_data *,
3524 struct pkg_data *), struct thread_data *thread_base,
3525 struct core_data *core_base, struct pkg_data *pkg_base,
3526 struct thread_data *thread_base2, struct core_data *core_base2, struct pkg_data *pkg_base2)
c98d5d94 3527{
40f5cfe7 3528 int retval, pkg_no, node_no, core_no, thread_no;
c98d5d94
LB
3529
3530 for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) {
40f5cfe7 3531 for (node_no = 0; node_no < topo.nodes_per_pkg; ++node_no) {
1b439f01
LB
3532 for (core_no = 0; core_no < topo.cores_per_node; ++core_no) {
3533 for (thread_no = 0; thread_no < topo.threads_per_core; ++thread_no) {
40f5cfe7
PB
3534 struct thread_data *t, *t2;
3535 struct core_data *c, *c2;
3536 struct pkg_data *p, *p2;
3537
1b439f01 3538 t = GET_THREAD(thread_base, thread_no, core_no, node_no, pkg_no);
40f5cfe7
PB
3539
3540 if (cpu_is_not_present(t->cpu_id))
3541 continue;
3542
1b439f01 3543 t2 = GET_THREAD(thread_base2, thread_no, core_no, node_no, pkg_no);
40f5cfe7 3544
1b439f01
LB
3545 c = GET_CORE(core_base, core_no, node_no, pkg_no);
3546 c2 = GET_CORE(core_base2, core_no, node_no, pkg_no);
40f5cfe7
PB
3547
3548 p = GET_PKG(pkg_base, pkg_no);
3549 p2 = GET_PKG(pkg_base2, pkg_no);
3550
3551 retval = func(t, c, p, t2, c2, p2);
3552 if (retval)
3553 return retval;
3554 }
c98d5d94
LB
3555 }
3556 }
3557 }
3558 return 0;
3559}
3560
3561/*
3562 * run func(cpu) on every cpu in /proc/stat
3563 * return max_cpu number
3564 */
1b439f01 3565int for_all_proc_cpus(int (func) (int))
103a8fea
LB
3566{
3567 FILE *fp;
c98d5d94 3568 int cpu_num;
103a8fea
LB
3569 int retval;
3570
57a42a34 3571 fp = fopen_or_die(proc_stat, "r");
103a8fea
LB
3572
3573 retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n");
b2c95d90
JT
3574 if (retval != 0)
3575 err(1, "%s: failed to parse format", proc_stat);
103a8fea 3576
c98d5d94
LB
3577 while (1) {
3578 retval = fscanf(fp, "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n", &cpu_num);
103a8fea
LB
3579 if (retval != 1)
3580 break;
3581
c98d5d94
LB
3582 retval = func(cpu_num);
3583 if (retval) {
3584 fclose(fp);
1b439f01 3585 return (retval);
c98d5d94 3586 }
103a8fea
LB
3587 }
3588 fclose(fp);
c98d5d94 3589 return 0;
103a8fea
LB
3590}
3591
3592void re_initialize(void)
3593{
c98d5d94
LB
3594 free_all_buffers();
3595 setup_all_buffers();
3d7772ea 3596 fprintf(outf, "turbostat: re-initialized with num_cpus %d\n", topo.num_cpus);
103a8fea
LB
3597}
3598
843c5791
PB
3599void set_max_cpu_num(void)
3600{
3601 FILE *filep;
8201a028 3602 int base_cpu;
843c5791 3603 unsigned long dummy;
8201a028 3604 char pathname[64];
843c5791 3605
8201a028
PB
3606 base_cpu = sched_getcpu();
3607 if (base_cpu < 0)
3608 err(1, "cannot find calling cpu ID");
1b439f01 3609 sprintf(pathname, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", base_cpu);
8201a028
PB
3610
3611 filep = fopen_or_die(pathname, "r");
843c5791 3612 topo.max_cpu_num = 0;
843c5791 3613 while (fscanf(filep, "%lx,", &dummy) == 1)
0e2d8f05 3614 topo.max_cpu_num += BITMASK_SIZE;
843c5791 3615 fclose(filep);
1b439f01 3616 topo.max_cpu_num--; /* 0 based */
843c5791 3617}
c98d5d94 3618
103a8fea 3619/*
c98d5d94
LB
3620 * count_cpus()
3621 * remember the last one seen, it will be the max
103a8fea 3622 */
c98d5d94 3623int count_cpus(int cpu)
103a8fea 3624{
9878bf7a
LB
3625 UNUSED(cpu);
3626
843c5791 3627 topo.num_cpus++;
c98d5d94
LB
3628 return 0;
3629}
1b439f01 3630
c98d5d94
LB
3631int mark_cpu_present(int cpu)
3632{
3633 CPU_SET_S(cpu, cpu_present_setsize, cpu_present_set);
15aaa346 3634 return 0;
103a8fea
LB
3635}
3636
8cb48b32
PB
3637int init_thread_id(int cpu)
3638{
3639 cpus[cpu].thread_id = -1;
3640 return 0;
3641}
3642
562a2d37
LB
3643/*
3644 * snapshot_proc_interrupts()
3645 *
3646 * read and record summary of /proc/interrupts
3647 *
3648 * return 1 if config change requires a restart, else return 0
3649 */
3650int snapshot_proc_interrupts(void)
3651{
3652 static FILE *fp;
3653 int column, retval;
3654
3655 if (fp == NULL)
3656 fp = fopen_or_die("/proc/interrupts", "r");
3657 else
3658 rewind(fp);
3659
3660 /* read 1st line of /proc/interrupts to get cpu* name for each column */
3661 for (column = 0; column < topo.num_cpus; ++column) {
3662 int cpu_number;
3663
3664 retval = fscanf(fp, " CPU%d", &cpu_number);
3665 if (retval != 1)
3666 break;
3667
3668 if (cpu_number > topo.max_cpu_num) {
3669 warn("/proc/interrupts: cpu%d: > %d", cpu_number, topo.max_cpu_num);
3670 return 1;
3671 }
3672
3673 irq_column_2_cpu[column] = cpu_number;
3674 irqs_per_cpu[cpu_number] = 0;
3675 }
3676
3677 /* read /proc/interrupt count lines and sum up irqs per cpu */
3678 while (1) {
3679 int column;
3680 char buf[64];
3681
3682 retval = fscanf(fp, " %s:", buf); /* flush irq# "N:" */
3683 if (retval != 1)
3684 break;
3685
3686 /* read the count per cpu */
3687 for (column = 0; column < topo.num_cpus; ++column) {
3688
3689 int cpu_number, irq_count;
3690
3691 retval = fscanf(fp, " %d", &irq_count);
3692 if (retval != 1)
3693 break;
3694
3695 cpu_number = irq_column_2_cpu[column];
3696 irqs_per_cpu[cpu_number] += irq_count;
3697
3698 }
3699
1b439f01 3700 while (getc(fp) != '\n') ; /* flush interrupt description */
562a2d37
LB
3701
3702 }
3703 return 0;
3704}
1b439f01 3705
fdf676e5
LB
3706/*
3707 * snapshot_gfx_rc6_ms()
3708 *
3709 * record snapshot of
3710 * /sys/class/drm/card0/power/rc6_residency_ms
3711 *
3712 * return 1 if config change requires a restart, else return 0
3713 */
3714int snapshot_gfx_rc6_ms(void)
3715{
3716 FILE *fp;
3717 int retval;
3718
3719 fp = fopen_or_die("/sys/class/drm/card0/power/rc6_residency_ms", "r");
3720
3721 retval = fscanf(fp, "%lld", &gfx_cur_rc6_ms);
3722 if (retval != 1)
3723 err(1, "GFX rc6");
3724
3725 fclose(fp);
3726
3727 return 0;
3728}
1b439f01 3729
27d47356
LB
3730/*
3731 * snapshot_gfx_mhz()
3732 *
2c019d65
ZR
3733 * fall back to /sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz
3734 * when /sys/class/drm/card0/gt_cur_freq_mhz is not available.
27d47356
LB
3735 *
3736 * return 1 if config change requires a restart, else return 0
3737 */
3738int snapshot_gfx_mhz(void)
3739{
3740 static FILE *fp;
3741 int retval;
3742
2c019d65
ZR
3743 if (fp == NULL) {
3744 fp = fopen("/sys/class/drm/card0/gt_cur_freq_mhz", "r");
3745 if (!fp)
3746 fp = fopen_or_die("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", "r");
3747 } else {
27d47356 3748 rewind(fp);
22048c54
LB
3749 fflush(fp);
3750 }
27d47356
LB
3751
3752 retval = fscanf(fp, "%d", &gfx_cur_mhz);
3753 if (retval != 1)
3754 err(1, "GFX MHz");
3755
3756 return 0;
3757}
562a2d37 3758
b4b91569
RA
3759/*
3760 * snapshot_gfx_cur_mhz()
3761 *
2c019d65
ZR
3762 * fall back to /sys/class/graphics/fb0/device/drm/card0/gt_act_freq_mhz
3763 * when /sys/class/drm/card0/gt_act_freq_mhz is not available.
b4b91569
RA
3764 *
3765 * return 1 if config change requires a restart, else return 0
3766 */
3767int snapshot_gfx_act_mhz(void)
3768{
3769 static FILE *fp;
3770 int retval;
3771
2c019d65
ZR
3772 if (fp == NULL) {
3773 fp = fopen("/sys/class/drm/card0/gt_act_freq_mhz", "r");
3774 if (!fp)
3775 fp = fopen_or_die("/sys/class/graphics/fb0/device/drm/card0/gt_act_freq_mhz", "r");
3776 } else {
b4b91569
RA
3777 rewind(fp);
3778 fflush(fp);
3779 }
3780
3781 retval = fscanf(fp, "%d", &gfx_act_mhz);
3782 if (retval != 1)
3783 err(1, "GFX ACT MHz");
3784
3785 return 0;
3786}
3787
be0e54c4
LB
3788/*
3789 * snapshot_cpu_lpi()
3790 *
3791 * record snapshot of
3792 * /sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us
be0e54c4
LB
3793 */
3794int snapshot_cpu_lpi_us(void)
3795{
3796 FILE *fp;
3797 int retval;
3798
3799 fp = fopen_or_die("/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us", "r");
3800
3801 retval = fscanf(fp, "%lld", &cpuidle_cur_cpu_lpi_us);
5ea7647b
PB
3802 if (retval != 1) {
3803 fprintf(stderr, "Disabling Low Power Idle CPU output\n");
3804 BIC_NOT_PRESENT(BIC_CPU_LPI);
605736c6 3805 fclose(fp);
5ea7647b
PB
3806 return -1;
3807 }
be0e54c4
LB
3808
3809 fclose(fp);
3810
3811 return 0;
3812}
1b439f01 3813
be0e54c4
LB
3814/*
3815 * snapshot_sys_lpi()
3816 *
1f81c5ef 3817 * record snapshot of sys_lpi_file
be0e54c4
LB
3818 */
3819int snapshot_sys_lpi_us(void)
3820{
3821 FILE *fp;
3822 int retval;
3823
1f81c5ef 3824 fp = fopen_or_die(sys_lpi_file, "r");
be0e54c4
LB
3825
3826 retval = fscanf(fp, "%lld", &cpuidle_cur_sys_lpi_us);
5ea7647b
PB
3827 if (retval != 1) {
3828 fprintf(stderr, "Disabling Low Power Idle System output\n");
3829 BIC_NOT_PRESENT(BIC_SYS_LPI);
15423b95 3830 fclose(fp);
5ea7647b
PB
3831 return -1;
3832 }
be0e54c4
LB
3833 fclose(fp);
3834
3835 return 0;
3836}
1b439f01 3837
562a2d37
LB
3838/*
3839 * snapshot /proc and /sys files
3840 *
3841 * return 1 if configuration restart needed, else return 0
3842 */
3843int snapshot_proc_sysfs_files(void)
3844{
218f0e8d
LB
3845 if (DO_BIC(BIC_IRQ))
3846 if (snapshot_proc_interrupts())
3847 return 1;
562a2d37 3848
812db3f7 3849 if (DO_BIC(BIC_GFX_rc6))
fdf676e5
LB
3850 snapshot_gfx_rc6_ms();
3851
812db3f7 3852 if (DO_BIC(BIC_GFXMHz))
27d47356
LB
3853 snapshot_gfx_mhz();
3854
b4b91569
RA
3855 if (DO_BIC(BIC_GFXACTMHz))
3856 snapshot_gfx_act_mhz();
3857
be0e54c4
LB
3858 if (DO_BIC(BIC_CPU_LPI))
3859 snapshot_cpu_lpi_us();
3860
3861 if (DO_BIC(BIC_SYS_LPI))
3862 snapshot_sys_lpi_us();
3863
562a2d37
LB
3864 return 0;
3865}
3866
8aa2ed0b
LB
3867int exit_requested;
3868
1b439f01 3869static void signal_handler(int signal)
8aa2ed0b
LB
3870{
3871 switch (signal) {
3872 case SIGINT:
3873 exit_requested = 1;
3874 if (debug)
3875 fprintf(stderr, " SIGINT\n");
3876 break;
07211960
LB
3877 case SIGUSR1:
3878 if (debug > 1)
3879 fprintf(stderr, "SIGUSR1\n");
3880 break;
8aa2ed0b
LB
3881 }
3882}
3883
3884void setup_signal_handler(void)
3885{
3886 struct sigaction sa;
3887
3888 memset(&sa, 0, sizeof(sa));
3889
3890 sa.sa_handler = &signal_handler;
3891
3892 if (sigaction(SIGINT, &sa, NULL) < 0)
3893 err(1, "sigaction SIGINT");
07211960
LB
3894 if (sigaction(SIGUSR1, &sa, NULL) < 0)
3895 err(1, "sigaction SIGUSR1");
8aa2ed0b 3896}
b9ad8ee0 3897
47936f94 3898void do_sleep(void)
b9ad8ee0 3899{
c026c236
AB
3900 struct timeval tout;
3901 struct timespec rest;
b9ad8ee0
LB
3902 fd_set readfds;
3903 int retval;
3904
3905 FD_ZERO(&readfds);
3906 FD_SET(0, &readfds);
3907
c026c236 3908 if (ignore_stdin) {
47936f94
AB
3909 nanosleep(&interval_ts, NULL);
3910 return;
3911 }
b9ad8ee0 3912
c026c236
AB
3913 tout = interval_tv;
3914 retval = select(1, &readfds, NULL, NULL, &tout);
b9ad8ee0
LB
3915
3916 if (retval == 1) {
b9ad8ee0
LB
3917 switch (getc(stdin)) {
3918 case 'q':
3919 exit_requested = 1;
3920 break;
c026c236
AB
3921 case EOF:
3922 /*
3923 * 'stdin' is a pipe closed on the other end. There
3924 * won't be any further input.
3925 */
3926 ignore_stdin = 1;
3927 /* Sleep the rest of the time */
3928 rest.tv_sec = (tout.tv_sec + tout.tv_usec / 1000000);
3929 rest.tv_nsec = (tout.tv_usec % 1000000) * 1000;
3930 nanosleep(&rest, NULL);
b9ad8ee0 3931 }
b9ad8ee0 3932 }
b9ad8ee0 3933}
47936f94 3934
87e15da9
CY
3935int get_msr_sum(int cpu, off_t offset, unsigned long long *msr)
3936{
3937 int ret, idx;
3938 unsigned long long msr_cur, msr_last;
3939
3940 if (!per_cpu_msr_sum)
3941 return 1;
3942
3943 idx = offset_to_idx(offset);
3944 if (idx < 0)
3945 return idx;
3946 /* get_msr_sum() = sum + (get_msr() - last) */
3947 ret = get_msr(cpu, offset, &msr_cur);
3948 if (ret)
3949 return ret;
3950 msr_last = per_cpu_msr_sum[cpu].entries[idx].last;
3951 DELTA_WRAP32(msr_cur, msr_last);
3952 *msr = msr_last + per_cpu_msr_sum[cpu].entries[idx].sum;
3953
3954 return 0;
3955}
3956
3957timer_t timerid;
3958
3959/* Timer callback, update the sum of MSRs periodically. */
3960static int update_msr_sum(struct thread_data *t, struct core_data *c, struct pkg_data *p)
3961{
3962 int i, ret;
3963 int cpu = t->cpu_id;
3964
9878bf7a
LB
3965 UNUSED(c);
3966 UNUSED(p);
3967
87e15da9
CY
3968 for (i = IDX_PKG_ENERGY; i < IDX_COUNT; i++) {
3969 unsigned long long msr_cur, msr_last;
13a779de 3970 off_t offset;
87e15da9
CY
3971
3972 if (!idx_valid(i))
3973 continue;
3974 offset = idx_to_offset(i);
3975 if (offset < 0)
3976 continue;
3977 ret = get_msr(cpu, offset, &msr_cur);
3978 if (ret) {
1b439f01 3979 fprintf(outf, "Can not update msr(0x%llx)\n", (unsigned long long)offset);
87e15da9
CY
3980 continue;
3981 }
3982
3983 msr_last = per_cpu_msr_sum[cpu].entries[i].last;
3984 per_cpu_msr_sum[cpu].entries[i].last = msr_cur & 0xffffffff;
3985
3986 DELTA_WRAP32(msr_cur, msr_last);
3987 per_cpu_msr_sum[cpu].entries[i].sum += msr_last;
3988 }
3989 return 0;
3990}
3991
1b439f01 3992static void msr_record_handler(union sigval v)
87e15da9 3993{
9878bf7a
LB
3994 UNUSED(v);
3995
87e15da9
CY
3996 for_all_cpus(update_msr_sum, EVEN_COUNTERS);
3997}
3998
3999void msr_sum_record(void)
4000{
4001 struct itimerspec its;
4002 struct sigevent sev;
4003
4004 per_cpu_msr_sum = calloc(topo.max_cpu_num + 1, sizeof(struct msr_sum_array));
4005 if (!per_cpu_msr_sum) {
4006 fprintf(outf, "Can not allocate memory for long time MSR.\n");
4007 return;
4008 }
4009 /*
4010 * Signal handler might be restricted, so use thread notifier instead.
4011 */
4012 memset(&sev, 0, sizeof(struct sigevent));
4013 sev.sigev_notify = SIGEV_THREAD;
4014 sev.sigev_notify_function = msr_record_handler;
4015
4016 sev.sigev_value.sival_ptr = &timerid;
4017 if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) {
4018 fprintf(outf, "Can not create timer.\n");
4019 goto release_msr;
4020 }
4021
4022 its.it_value.tv_sec = 0;
4023 its.it_value.tv_nsec = 1;
4024 /*
4025 * A wraparound time has been calculated early.
4026 * Some sources state that the peak power for a
4027 * microprocessor is usually 1.5 times the TDP rating,
4028 * use 2 * TDP for safety.
4029 */
4030 its.it_interval.tv_sec = rapl_joule_counter_range / 2;
4031 its.it_interval.tv_nsec = 0;
4032
4033 if (timer_settime(timerid, 0, &its, NULL) == -1) {
4034 fprintf(outf, "Can not set timer.\n");
4035 goto release_timer;
4036 }
4037 return;
4038
1b439f01 4039release_timer:
87e15da9 4040 timer_delete(timerid);
1b439f01 4041release_msr:
87e15da9
CY
4042 free(per_cpu_msr_sum);
4043}
4c2122d4 4044
38c6663a
LB
4045/*
4046 * set_my_sched_priority(pri)
4047 * return previous
4048 */
4049int set_my_sched_priority(int priority)
4050{
4051 int retval;
4052 int original_priority;
4053
4054 errno = 0;
4055 original_priority = getpriority(PRIO_PROCESS, 0);
4056 if (errno && (original_priority == -1))
4057 err(errno, "getpriority");
4058
4059 retval = setpriority(PRIO_PROCESS, 0, priority);
4060 if (retval)
de7839ee 4061 errx(retval, "capget(CAP_SYS_NICE) failed,try \"# setcap cap_sys_nice=ep %s\"", progname);
38c6663a
LB
4062
4063 errno = 0;
4064 retval = getpriority(PRIO_PROCESS, 0);
4065 if (retval != priority)
164d7a96 4066 err(retval, "getpriority(%d) != setpriority(%d)", retval, priority);
38c6663a
LB
4067
4068 return original_priority;
4069}
4070
103a8fea
LB
4071void turbostat_loop()
4072{
c98d5d94 4073 int retval;
e52966c0 4074 int restarted = 0;
9878bf7a 4075 unsigned int done_iters = 0;
c98d5d94 4076
8aa2ed0b
LB
4077 setup_signal_handler();
4078
38c6663a
LB
4079 /*
4080 * elevate own priority for interval mode
4081 */
4082 set_my_sched_priority(-20);
4083
103a8fea 4084restart:
e52966c0
LB
4085 restarted++;
4086
562a2d37 4087 snapshot_proc_sysfs_files();
c98d5d94 4088 retval = for_all_cpus(get_counters, EVEN_COUNTERS);
4c2122d4 4089 first_counter_read = 0;
d91bb17c
LB
4090 if (retval < -1) {
4091 exit(retval);
4092 } else if (retval == -1) {
3d7772ea 4093 if (restarted > 10) {
e52966c0
LB
4094 exit(retval);
4095 }
c98d5d94
LB
4096 re_initialize();
4097 goto restart;
4098 }
e52966c0 4099 restarted = 0;
023fe0ac 4100 done_iters = 0;
103a8fea
LB
4101 gettimeofday(&tv_even, (struct timezone *)NULL);
4102
4103 while (1) {
c98d5d94 4104 if (for_all_proc_cpus(cpu_is_not_present)) {
103a8fea
LB
4105 re_initialize();
4106 goto restart;
4107 }
b9ad8ee0 4108 do_sleep();
562a2d37
LB
4109 if (snapshot_proc_sysfs_files())
4110 goto restart;
c98d5d94 4111 retval = for_all_cpus(get_counters, ODD_COUNTERS);
d91bb17c
LB
4112 if (retval < -1) {
4113 exit(retval);
4114 } else if (retval == -1) {
15aaa346
LB
4115 re_initialize();
4116 goto restart;
4117 }
103a8fea 4118 gettimeofday(&tv_odd, (struct timezone *)NULL);
103a8fea 4119 timersub(&tv_odd, &tv_even, &tv_delta);
ba3dec99
LB
4120 if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS)) {
4121 re_initialize();
4122 goto restart;
4123 }
c98d5d94
LB
4124 compute_average(EVEN_COUNTERS);
4125 format_all_counters(EVEN_COUNTERS);
b7d8c148 4126 flush_output_stdout();
8aa2ed0b
LB
4127 if (exit_requested)
4128 break;
023fe0ac
CY
4129 if (num_iterations && ++done_iters >= num_iterations)
4130 break;
b9ad8ee0 4131 do_sleep();
562a2d37
LB
4132 if (snapshot_proc_sysfs_files())
4133 goto restart;
c98d5d94 4134 retval = for_all_cpus(get_counters, EVEN_COUNTERS);
d91bb17c
LB
4135 if (retval < -1) {
4136 exit(retval);
4137 } else if (retval == -1) {
103a8fea
LB
4138 re_initialize();
4139 goto restart;
4140 }
103a8fea 4141 gettimeofday(&tv_even, (struct timezone *)NULL);
103a8fea 4142 timersub(&tv_even, &tv_odd, &tv_delta);
ba3dec99
LB
4143 if (for_all_cpus_2(delta_cpu, EVEN_COUNTERS, ODD_COUNTERS)) {
4144 re_initialize();
4145 goto restart;
4146 }
c98d5d94
LB
4147 compute_average(ODD_COUNTERS);
4148 format_all_counters(ODD_COUNTERS);
b7d8c148 4149 flush_output_stdout();
8aa2ed0b
LB
4150 if (exit_requested)
4151 break;
023fe0ac
CY
4152 if (num_iterations && ++done_iters >= num_iterations)
4153 break;
103a8fea
LB
4154 }
4155}
4156
4157void check_dev_msr()
4158{
4159 struct stat sb;
7ce7d5de 4160 char pathname[32];
103a8fea 4161
7ce7d5de
PB
4162 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
4163 if (stat(pathname, &sb))
1b439f01 4164 if (system("/sbin/modprobe msr > /dev/null 2>&1"))
a21d38c8 4165 err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" ");
103a8fea
LB
4166}
4167
fcaa681c
LB
4168/*
4169 * check for CAP_SYS_RAWIO
4170 * return 0 on success
4171 * return 1 on fail
4172 */
4173int check_for_cap_sys_rawio(void)
103a8fea 4174{
fcaa681c
LB
4175 cap_t caps;
4176 cap_flag_value_t cap_flag_value;
98481e79 4177
fcaa681c
LB
4178 caps = cap_get_proc();
4179 if (caps == NULL)
4180 err(-6, "cap_get_proc\n");
98481e79 4181
fcaa681c
LB
4182 if (cap_get_flag(caps, CAP_SYS_RAWIO, CAP_EFFECTIVE, &cap_flag_value))
4183 err(-6, "cap_get\n");
4184
4185 if (cap_flag_value != CAP_SET) {
1b439f01 4186 warnx("capget(CAP_SYS_RAWIO) failed," " try \"# setcap cap_sys_rawio=ep %s\"", progname);
fcaa681c 4187 return 1;
98481e79
LB
4188 }
4189
fcaa681c
LB
4190 if (cap_free(caps) == -1)
4191 err(-6, "cap_free\n");
4192
4193 return 0;
4194}
1b439f01 4195
fcaa681c
LB
4196void check_permissions(void)
4197{
4198 int do_exit = 0;
4199 char pathname[32];
4200
4201 /* check for CAP_SYS_RAWIO */
4202 do_exit += check_for_cap_sys_rawio();
4203
98481e79 4204 /* test file permissions */
7ce7d5de
PB
4205 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
4206 if (euidaccess(pathname, R_OK)) {
98481e79
LB
4207 do_exit++;
4208 warn("/dev/cpu/0/msr open failed, try chown or chmod +r /dev/cpu/*/msr");
4209 }
4210
4211 /* if all else fails, thell them to be root */
4212 if (do_exit)
4213 if (getuid() != 0)
d7899447 4214 warnx("... or simply run as root");
98481e79
LB
4215
4216 if (do_exit)
4217 exit(-6);
103a8fea
LB
4218}
4219
71e84129
ZR
4220void probe_bclk(void)
4221{
4222 unsigned long long msr;
4223 unsigned int base_ratio;
4224
fcfa1ce0 4225 if (!platform->has_nhm_msrs)
71e84129
ZR
4226 return;
4227
4228 if (platform->bclk_freq == BCLK_100MHZ)
4229 bclk = 100.00;
4230 else if (platform->bclk_freq == BCLK_133MHZ)
4231 bclk = 133.33;
4232 else if (platform->bclk_freq == BCLK_SLV)
4233 bclk = slm_bclk();
4234 else
4235 return;
4236
4237 get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
4238 base_ratio = (msr >> 8) & 0xFF;
4239
4240 base_hz = base_ratio * bclk * 1000000;
4241 has_base_hz = 1;
485a017c
ZR
4242
4243 if (platform->enable_tsc_tweak)
4244 tsc_tweak = base_hz / tsc_hz;
71e84129
ZR
4245}
4246
0f7887c4 4247/*
495c7654 4248 * SLV client has support for unique MSRs:
0f7887c4
LB
4249 *
4250 * MSR_CC6_DEMOTION_POLICY_CONFIG
4251 * MSR_MC6_DEMOTION_POLICY_CONFIG
4252 */
4253
4254int has_slv_msrs(unsigned int family, unsigned int model)
4255{
4256 if (!genuine_intel)
4257 return 0;
4258
9878bf7a
LB
4259 if (family != 6)
4260 return 0;
4261
0f7887c4 4262 switch (model) {
f2c4db1b 4263 case INTEL_FAM6_ATOM_SILVERMONT:
0f7887c4
LB
4264 return 1;
4265 }
4266 return 0;
4267}
1b439f01 4268
7170a374
LB
4269int is_dnv(unsigned int family, unsigned int model)
4270{
4271
4272 if (!genuine_intel)
4273 return 0;
4274
9878bf7a
LB
4275 if (family != 6)
4276 return 0;
4277
7170a374 4278 switch (model) {
5ebb34ed 4279 case INTEL_FAM6_ATOM_GOLDMONT_D:
7170a374
LB
4280 return 1;
4281 }
4282 return 0;
4283}
1b439f01 4284
25368d7c
CY
4285int is_icx(unsigned int family, unsigned int model)
4286{
4287
4288 if (!genuine_intel)
4289 return 0;
4290
9878bf7a
LB
4291 if (family != 6)
4292 return 0;
4293
25368d7c
CY
4294 switch (model) {
4295 case INTEL_FAM6_ICELAKE_X:
4296 return 1;
4297 }
4298 return 0;
4299}
4300
684e40e9
AB
4301int is_spr(unsigned int family, unsigned int model)
4302{
4303
4304 if (!genuine_intel)
4305 return 0;
4306
4307 if (family != 6)
4308 return 0;
4309
4310 switch (model) {
4311 case INTEL_FAM6_SAPPHIRERAPIDS_X:
4312 return 1;
4313 }
4314 return 0;
4315}
4316
f6708400
CY
4317int is_ehl(unsigned int family, unsigned int model)
4318{
4319 if (!genuine_intel)
4320 return 0;
4321
9878bf7a
LB
4322 if (family != 6)
4323 return 0;
4324
f6708400
CY
4325 switch (model) {
4326 case INTEL_FAM6_ATOM_TREMONT:
4327 return 1;
4328 }
4329 return 0;
4330}
1b439f01 4331
1b439f01 4332static void remove_underbar(char *s)
fecb3bc8
DA
4333{
4334 char *to = s;
4335
4336 while (*s) {
4337 if (*s != '_')
4338 *to++ = *s;
4339 s++;
4340 }
4341
4342 *to = 0;
4343}
4344
a61c9cb4 4345static void dump_turbo_ratio_info(void)
fcd17211 4346{
3ea8e52e 4347 if (!has_turbo)
fcd17211
LB
4348 return;
4349
10d85d85 4350 if (platform->trl_msrs & TRL_LIMIT2)
a3943dea 4351 dump_turbo_ratio_limit2();
fcd17211 4352
10d85d85 4353 if (platform->trl_msrs & TRL_LIMIT1)
a3943dea 4354 dump_turbo_ratio_limit1();
fcd17211 4355
10d85d85
ZR
4356 if (platform->trl_msrs & TRL_BASE) {
4357 dump_turbo_ratio_limits(MSR_TURBO_RATIO_LIMIT);
4af184ee
LB
4358
4359 if (is_hybrid)
10d85d85 4360 dump_turbo_ratio_limits(MSR_SECONDARY_TURBO_RATIO_LIMIT);
4af184ee 4361 }
fcd17211 4362
10d85d85 4363 if (platform->trl_msrs & TRL_ATOM)
0f7887c4
LB
4364 dump_atom_turbo_ratio_limits();
4365
10d85d85 4366 if (platform->trl_msrs & TRL_KNL)
fb5d4327
DC
4367 dump_knl_turbo_ratio_limits();
4368
a61c9cb4 4369 if (platform->has_config_tdp)
6fb3143b 4370 dump_config_tdp();
3ea8e52e 4371}
6fb3143b 4372
a61c9cb4 4373static void dump_cstate_pstate_config_info(void)
3ea8e52e 4374{
fcfa1ce0 4375 if (!platform->has_nhm_msrs)
3ea8e52e
AB
4376 return;
4377
8b7199c0 4378 dump_platform_info();
a61c9cb4 4379 dump_turbo_ratio_info();
8b7199c0 4380 dump_cst_cfg();
fcd17211
LB
4381}
4382
a5c6d65d
LB
4383static int read_sysfs_int(char *path)
4384{
4385 FILE *input;
4386 int retval = -1;
4387
4388 input = fopen(path, "r");
4389 if (input == NULL) {
4390 if (debug)
4391 fprintf(outf, "NSFOD %s\n", path);
4392 return (-1);
4393 }
4394 if (fscanf(input, "%d", &retval) != 1)
4395 err(1, "%s: failed to read int from file", path);
4396 fclose(input);
4397
4398 return (retval);
4399}
4400
abdcbdb2
LB
4401static void dump_sysfs_file(char *path)
4402{
4403 FILE *input;
4404 char cpuidle_buf[64];
4405
4406 input = fopen(path, "r");
4407 if (input == NULL) {
4408 if (debug)
4409 fprintf(outf, "NSFOD %s\n", path);
4410 return;
4411 }
4412 if (!fgets(cpuidle_buf, sizeof(cpuidle_buf), input))
4413 err(1, "%s: failed to read file", path);
4414 fclose(input);
4415
4416 fprintf(outf, "%s: %s", strrchr(path, '/') + 1, cpuidle_buf);
4417}
1b439f01 4418
a5c6d65d
LB
4419static void intel_uncore_frequency_probe(void)
4420{
4421 int i, j;
4422 char path[128];
4423
4424 if (!genuine_intel)
4425 return;
4426
4427 if (access("/sys/devices/system/cpu/intel_uncore_frequency/package_00_die_00", R_OK))
4428 return;
4429
4d182748
ZR
4430 /* Cluster level sysfs not supported yet. */
4431 if (!access("/sys/devices/system/cpu/intel_uncore_frequency/uncore00", R_OK))
4432 return;
4433
a5c6d65d
LB
4434 if (!access("/sys/devices/system/cpu/intel_uncore_frequency/package_00_die_00/current_freq_khz", R_OK))
4435 BIC_PRESENT(BIC_UNCORE_MHZ);
4436
4437 if (quiet)
4438 return;
4439
4440 for (i = 0; i < topo.num_packages; ++i) {
4441 for (j = 0; j < topo.num_die; ++j) {
4442 int k, l;
4443
4444 sprintf(path, "/sys/devices/system/cpu/intel_uncore_frequency/package_0%d_die_0%d/min_freq_khz",
4445 i, j);
4446 k = read_sysfs_int(path);
4447 sprintf(path, "/sys/devices/system/cpu/intel_uncore_frequency/package_0%d_die_0%d/max_freq_khz",
4448 i, j);
4449 l = read_sysfs_int(path);
4450 fprintf(outf, "Uncore Frequency pkg%d die%d: %d - %d MHz ", i, j, k / 1000, l / 1000);
4451
4452 sprintf(path,
4453 "/sys/devices/system/cpu/intel_uncore_frequency/package_0%d_die_0%d/initial_min_freq_khz",
4454 i, j);
4455 k = read_sysfs_int(path);
4456 sprintf(path,
4457 "/sys/devices/system/cpu/intel_uncore_frequency/package_0%d_die_0%d/initial_max_freq_khz",
4458 i, j);
4459 l = read_sysfs_int(path);
4460 fprintf(outf, "(%d - %d MHz)\n", k / 1000, l / 1000);
4461 }
4462 }
4463}
4464
1b439f01 4465static void dump_sysfs_cstate_config(void)
41618e63
LB
4466{
4467 char path[64];
4468 char name_buf[16];
4469 char desc[64];
4470 FILE *input;
4471 int state;
4472 char *sp;
4473
abdcbdb2
LB
4474 if (access("/sys/devices/system/cpu/cpuidle", R_OK)) {
4475 fprintf(outf, "cpuidle not loaded\n");
4476 return;
4477 }
4478
4479 dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_driver");
4480 dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_governor");
4481 dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_governor_ro");
4482
41618e63
LB
4483 for (state = 0; state < 10; ++state) {
4484
1b439f01 4485 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", base_cpu, state);
41618e63
LB
4486 input = fopen(path, "r");
4487 if (input == NULL)
4488 continue;
8173c336
BH
4489 if (!fgets(name_buf, sizeof(name_buf), input))
4490 err(1, "%s: failed to read file", path);
41618e63 4491
1b439f01 4492 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
41618e63
LB
4493 sp = strchr(name_buf, '-');
4494 if (!sp)
4495 sp = strchrnul(name_buf, '\n');
4496 *sp = '\0';
41618e63
LB
4497 fclose(input);
4498
fecb3bc8
DA
4499 remove_underbar(name_buf);
4500
1b439f01 4501 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/desc", base_cpu, state);
41618e63
LB
4502 input = fopen(path, "r");
4503 if (input == NULL)
4504 continue;
8173c336
BH
4505 if (!fgets(desc, sizeof(desc), input))
4506 err(1, "%s: failed to read file", path);
41618e63
LB
4507
4508 fprintf(outf, "cpu%d: %s: %s", base_cpu, name_buf, desc);
4509 fclose(input);
4510 }
4511}
1b439f01
LB
4512
4513static void dump_sysfs_pstate_config(void)
7293fccd
LB
4514{
4515 char path[64];
4516 char driver_buf[64];
4517 char governor_buf[64];
4518 FILE *input;
4519 int turbo;
4520
1b439f01 4521 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_driver", base_cpu);
7293fccd
LB
4522 input = fopen(path, "r");
4523 if (input == NULL) {
0a42d235 4524 fprintf(outf, "NSFOD %s\n", path);
7293fccd
LB
4525 return;
4526 }
8173c336
BH
4527 if (!fgets(driver_buf, sizeof(driver_buf), input))
4528 err(1, "%s: failed to read file", path);
7293fccd
LB
4529 fclose(input);
4530
1b439f01 4531 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", base_cpu);
7293fccd
LB
4532 input = fopen(path, "r");
4533 if (input == NULL) {
0a42d235 4534 fprintf(outf, "NSFOD %s\n", path);
7293fccd
LB
4535 return;
4536 }
8173c336
BH
4537 if (!fgets(governor_buf, sizeof(governor_buf), input))
4538 err(1, "%s: failed to read file", path);
7293fccd
LB
4539 fclose(input);
4540
4541 fprintf(outf, "cpu%d: cpufreq driver: %s", base_cpu, driver_buf);
4542 fprintf(outf, "cpu%d: cpufreq governor: %s", base_cpu, governor_buf);
4543
4544 sprintf(path, "/sys/devices/system/cpu/cpufreq/boost");
4545 input = fopen(path, "r");
4546 if (input != NULL) {
8173c336
BH
4547 if (fscanf(input, "%d", &turbo) != 1)
4548 err(1, "%s: failed to parse number from file", path);
7293fccd
LB
4549 fprintf(outf, "cpufreq boost: %d\n", turbo);
4550 fclose(input);
4551 }
4552
4553 sprintf(path, "/sys/devices/system/cpu/intel_pstate/no_turbo");
4554 input = fopen(path, "r");
4555 if (input != NULL) {
8173c336
BH
4556 if (fscanf(input, "%d", &turbo) != 1)
4557 err(1, "%s: failed to parse number from file", path);
7293fccd
LB
4558 fprintf(outf, "cpufreq intel_pstate no_turbo: %d\n", turbo);
4559 fclose(input);
4560 }
4561}
41618e63 4562
889facbe
LB
4563/*
4564 * print_epb()
4565 * Decode the ENERGY_PERF_BIAS MSR
4566 */
4567int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p)
4568{
889facbe 4569 char *epb_string;
6d6501d9 4570 int cpu, epb;
889facbe 4571
9878bf7a
LB
4572 UNUSED(c);
4573 UNUSED(p);
4574
889facbe
LB
4575 if (!has_epb)
4576 return 0;
4577
4578 cpu = t->cpu_id;
4579
4580 /* EPB is per-package */
4581 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
4582 return 0;
4583
4584 if (cpu_migrate(cpu)) {
3d7772ea 4585 fprintf(outf, "print_epb: Could not migrate to CPU %d\n", cpu);
889facbe
LB
4586 return -1;
4587 }
4588
6d6501d9
BP
4589 epb = get_epb(cpu);
4590 if (epb < 0)
889facbe
LB
4591 return 0;
4592
6d6501d9 4593 switch (epb) {
889facbe
LB
4594 case ENERGY_PERF_BIAS_PERFORMANCE:
4595 epb_string = "performance";
4596 break;
4597 case ENERGY_PERF_BIAS_NORMAL:
4598 epb_string = "balanced";
4599 break;
4600 case ENERGY_PERF_BIAS_POWERSAVE:
4601 epb_string = "powersave";
4602 break;
4603 default:
4604 epb_string = "custom";
4605 break;
4606 }
6d6501d9 4607 fprintf(outf, "cpu%d: EPB: %d (%s)\n", cpu, epb, epb_string);
889facbe
LB
4608
4609 return 0;
4610}
1b439f01 4611
7f5c258e
LB
4612/*
4613 * print_hwp()
4614 * Decode the MSR_HWP_CAPABILITIES
4615 */
4616int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p)
4617{
4618 unsigned long long msr;
4619 int cpu;
4620
9878bf7a
LB
4621 UNUSED(c);
4622 UNUSED(p);
4623
7f5c258e
LB
4624 if (!has_hwp)
4625 return 0;
4626
4627 cpu = t->cpu_id;
4628
4629 /* MSR_HWP_CAPABILITIES is per-package */
4630 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
4631 return 0;
4632
4633 if (cpu_migrate(cpu)) {
3d7772ea 4634 fprintf(outf, "print_hwp: Could not migrate to CPU %d\n", cpu);
7f5c258e
LB
4635 return -1;
4636 }
4637
4638 if (get_msr(cpu, MSR_PM_ENABLE, &msr))
4639 return 0;
4640
1b439f01 4641 fprintf(outf, "cpu%d: MSR_PM_ENABLE: 0x%08llx (%sHWP)\n", cpu, msr, (msr & (1 << 0)) ? "" : "No-");
7f5c258e
LB
4642
4643 /* MSR_PM_ENABLE[1] == 1 if HWP is enabled and MSRs visible */
4644 if ((msr & (1 << 0)) == 0)
4645 return 0;
4646
4647 if (get_msr(cpu, MSR_HWP_CAPABILITIES, &msr))
4648 return 0;
4649
b7d8c148 4650 fprintf(outf, "cpu%d: MSR_HWP_CAPABILITIES: 0x%08llx "
1b439f01
LB
4651 "(high %d guar %d eff %d low %d)\n",
4652 cpu, msr,
4653 (unsigned int)HWP_HIGHEST_PERF(msr),
4654 (unsigned int)HWP_GUARANTEED_PERF(msr),
4655 (unsigned int)HWP_MOSTEFFICIENT_PERF(msr), (unsigned int)HWP_LOWEST_PERF(msr));
7f5c258e
LB
4656
4657 if (get_msr(cpu, MSR_HWP_REQUEST, &msr))
4658 return 0;
4659
b7d8c148 4660 fprintf(outf, "cpu%d: MSR_HWP_REQUEST: 0x%08llx "
1b439f01
LB
4661 "(min %d max %d des %d epp 0x%x window 0x%x pkg 0x%x)\n",
4662 cpu, msr,
4663 (unsigned int)(((msr) >> 0) & 0xff),
4664 (unsigned int)(((msr) >> 8) & 0xff),
4665 (unsigned int)(((msr) >> 16) & 0xff),
4666 (unsigned int)(((msr) >> 24) & 0xff),
4667 (unsigned int)(((msr) >> 32) & 0xff3), (unsigned int)(((msr) >> 42) & 0x1));
7f5c258e
LB
4668
4669 if (has_hwp_pkg) {
4670 if (get_msr(cpu, MSR_HWP_REQUEST_PKG, &msr))
4671 return 0;
4672
b7d8c148 4673 fprintf(outf, "cpu%d: MSR_HWP_REQUEST_PKG: 0x%08llx "
6dbd25a2 4674 "(min %d max %d des %d epp 0x%x window 0x%x)\n",
7f5c258e
LB
4675 cpu, msr,
4676 (unsigned int)(((msr) >> 0) & 0xff),
4677 (unsigned int)(((msr) >> 8) & 0xff),
4678 (unsigned int)(((msr) >> 16) & 0xff),
1b439f01 4679 (unsigned int)(((msr) >> 24) & 0xff), (unsigned int)(((msr) >> 32) & 0xff3));
7f5c258e
LB
4680 }
4681 if (has_hwp_notify) {
4682 if (get_msr(cpu, MSR_HWP_INTERRUPT, &msr))
4683 return 0;
4684
b7d8c148 4685 fprintf(outf, "cpu%d: MSR_HWP_INTERRUPT: 0x%08llx "
7f5c258e 4686 "(%s_Guaranteed_Perf_Change, %s_Excursion_Min)\n",
1b439f01 4687 cpu, msr, ((msr) & 0x1) ? "EN" : "Dis", ((msr) & 0x2) ? "EN" : "Dis");
7f5c258e
LB
4688 }
4689 if (get_msr(cpu, MSR_HWP_STATUS, &msr))
4690 return 0;
4691
b7d8c148 4692 fprintf(outf, "cpu%d: MSR_HWP_STATUS: 0x%08llx "
1b439f01 4693 "(%sGuaranteed_Perf_Change, %sExcursion_Min)\n",
92c25393 4694 cpu, msr, ((msr) & 0x1) ? "" : "No-", ((msr) & 0x4) ? "" : "No-");
889facbe
LB
4695
4696 return 0;
4697}
4698
3a9a941d
LB
4699/*
4700 * print_perf_limit()
4701 */
4702int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data *p)
4703{
4704 unsigned long long msr;
4705 int cpu;
4706
9878bf7a
LB
4707 UNUSED(c);
4708 UNUSED(p);
4709
3a9a941d
LB
4710 cpu = t->cpu_id;
4711
4712 /* per-package */
4713 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
4714 return 0;
4715
4716 if (cpu_migrate(cpu)) {
3d7772ea 4717 fprintf(outf, "print_perf_limit: Could not migrate to CPU %d\n", cpu);
3a9a941d
LB
4718 return -1;
4719 }
4720
0c057cf7 4721 if (platform->plr_msrs & PLR_CORE) {
3a9a941d 4722 get_msr(cpu, MSR_CORE_PERF_LIMIT_REASONS, &msr);
b7d8c148
LB
4723 fprintf(outf, "cpu%d: MSR_CORE_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
4724 fprintf(outf, " (Active: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)",
e33cbe85 4725 (msr & 1 << 15) ? "bit15, " : "",
3a9a941d 4726 (msr & 1 << 14) ? "bit14, " : "",
e33cbe85
LB
4727 (msr & 1 << 13) ? "Transitions, " : "",
4728 (msr & 1 << 12) ? "MultiCoreTurbo, " : "",
4729 (msr & 1 << 11) ? "PkgPwrL2, " : "",
4730 (msr & 1 << 10) ? "PkgPwrL1, " : "",
4731 (msr & 1 << 9) ? "CorePwr, " : "",
4732 (msr & 1 << 8) ? "Amps, " : "",
4733 (msr & 1 << 6) ? "VR-Therm, " : "",
4734 (msr & 1 << 5) ? "Auto-HWP, " : "",
4735 (msr & 1 << 4) ? "Graphics, " : "",
4736 (msr & 1 << 2) ? "bit2, " : "",
1b439f01 4737 (msr & 1 << 1) ? "ThermStatus, " : "", (msr & 1 << 0) ? "PROCHOT, " : "");
b7d8c148 4738 fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n",
e33cbe85 4739 (msr & 1 << 31) ? "bit31, " : "",
3a9a941d 4740 (msr & 1 << 30) ? "bit30, " : "",
e33cbe85
LB
4741 (msr & 1 << 29) ? "Transitions, " : "",
4742 (msr & 1 << 28) ? "MultiCoreTurbo, " : "",
4743 (msr & 1 << 27) ? "PkgPwrL2, " : "",
4744 (msr & 1 << 26) ? "PkgPwrL1, " : "",
4745 (msr & 1 << 25) ? "CorePwr, " : "",
4746 (msr & 1 << 24) ? "Amps, " : "",
4747 (msr & 1 << 22) ? "VR-Therm, " : "",
4748 (msr & 1 << 21) ? "Auto-HWP, " : "",
4749 (msr & 1 << 20) ? "Graphics, " : "",
4750 (msr & 1 << 18) ? "bit18, " : "",
1b439f01 4751 (msr & 1 << 17) ? "ThermStatus, " : "", (msr & 1 << 16) ? "PROCHOT, " : "");
3a9a941d
LB
4752
4753 }
0c057cf7 4754 if (platform->plr_msrs & PLR_GFX) {
3a9a941d 4755 get_msr(cpu, MSR_GFX_PERF_LIMIT_REASONS, &msr);
b7d8c148
LB
4756 fprintf(outf, "cpu%d: MSR_GFX_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
4757 fprintf(outf, " (Active: %s%s%s%s%s%s%s%s)",
3a9a941d
LB
4758 (msr & 1 << 0) ? "PROCHOT, " : "",
4759 (msr & 1 << 1) ? "ThermStatus, " : "",
4760 (msr & 1 << 4) ? "Graphics, " : "",
4761 (msr & 1 << 6) ? "VR-Therm, " : "",
4762 (msr & 1 << 8) ? "Amps, " : "",
4763 (msr & 1 << 9) ? "GFXPwr, " : "",
1b439f01 4764 (msr & 1 << 10) ? "PkgPwrL1, " : "", (msr & 1 << 11) ? "PkgPwrL2, " : "");
b7d8c148 4765 fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s)\n",
3a9a941d
LB
4766 (msr & 1 << 16) ? "PROCHOT, " : "",
4767 (msr & 1 << 17) ? "ThermStatus, " : "",
4768 (msr & 1 << 20) ? "Graphics, " : "",
4769 (msr & 1 << 22) ? "VR-Therm, " : "",
4770 (msr & 1 << 24) ? "Amps, " : "",
4771 (msr & 1 << 25) ? "GFXPwr, " : "",
1b439f01 4772 (msr & 1 << 26) ? "PkgPwrL1, " : "", (msr & 1 << 27) ? "PkgPwrL2, " : "");
3a9a941d 4773 }
0c057cf7 4774 if (platform->plr_msrs & PLR_RING) {
3a9a941d 4775 get_msr(cpu, MSR_RING_PERF_LIMIT_REASONS, &msr);
b7d8c148
LB
4776 fprintf(outf, "cpu%d: MSR_RING_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
4777 fprintf(outf, " (Active: %s%s%s%s%s%s)",
3a9a941d
LB
4778 (msr & 1 << 0) ? "PROCHOT, " : "",
4779 (msr & 1 << 1) ? "ThermStatus, " : "",
4780 (msr & 1 << 6) ? "VR-Therm, " : "",
4781 (msr & 1 << 8) ? "Amps, " : "",
1b439f01 4782 (msr & 1 << 10) ? "PkgPwrL1, " : "", (msr & 1 << 11) ? "PkgPwrL2, " : "");
b7d8c148 4783 fprintf(outf, " (Logged: %s%s%s%s%s%s)\n",
3a9a941d
LB
4784 (msr & 1 << 16) ? "PROCHOT, " : "",
4785 (msr & 1 << 17) ? "ThermStatus, " : "",
4786 (msr & 1 << 22) ? "VR-Therm, " : "",
4787 (msr & 1 << 24) ? "Amps, " : "",
1b439f01 4788 (msr & 1 << 26) ? "PkgPwrL1, " : "", (msr & 1 << 27) ? "PkgPwrL2, " : "");
3a9a941d
LB
4789 }
4790 return 0;
4791}
4792
889facbe 4793#define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */
1b439f01 4794#define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */
889facbe 4795
7c604093
ZR
4796double get_quirk_tdp(void)
4797{
4798 if (platform->rapl_quirk_tdp)
4799 return platform->rapl_quirk_tdp;
4800
4801 return 135.0;
4802}
4803
bf1ad57c 4804double get_tdp_intel(void)
144b44b1
LB
4805{
4806 unsigned long long msr;
4807
86ba263d 4808 if (platform->rapl_msrs & RAPL_PKG_POWER_INFO)
7ce7d5de 4809 if (!get_msr(base_cpu, MSR_PKG_POWER_INFO, &msr))
144b44b1 4810 return ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units;
7c604093 4811 return get_quirk_tdp();
144b44b1
LB
4812}
4813
bf1ad57c 4814double get_tdp_amd(void)
9392bd98 4815{
7c604093 4816 return get_quirk_tdp();
9392bd98
CW
4817}
4818
bf1ad57c 4819void rapl_probe_intel(void)
889facbe
LB
4820{
4821 unsigned long long msr;
144b44b1 4822 unsigned int time_unit;
889facbe
LB
4823 double tdp;
4824
a98f8860 4825 if (rapl_joules) {
86ba263d 4826 if (platform->rapl_msrs & RAPL_PKG_ENERGY_STATUS)
812db3f7 4827 BIC_PRESENT(BIC_Pkg_J);
86ba263d 4828 if (platform->rapl_msrs & RAPL_CORE_ENERGY_STATUS)
812db3f7 4829 BIC_PRESENT(BIC_Cor_J);
86ba263d 4830 if (platform->rapl_msrs & RAPL_DRAM_ENERGY_STATUS)
812db3f7 4831 BIC_PRESENT(BIC_RAM_J);
86ba263d 4832 if (platform->rapl_msrs & RAPL_GFX_ENERGY_STATUS)
a98f8860
ZR
4833 BIC_PRESENT(BIC_GFX_J);
4834 } else {
86ba263d 4835 if (platform->rapl_msrs & RAPL_PKG_ENERGY_STATUS)
812db3f7 4836 BIC_PRESENT(BIC_PkgWatt);
86ba263d 4837 if (platform->rapl_msrs & RAPL_CORE_ENERGY_STATUS)
812db3f7 4838 BIC_PRESENT(BIC_CorWatt);
86ba263d 4839 if (platform->rapl_msrs & RAPL_DRAM_ENERGY_STATUS)
812db3f7 4840 BIC_PRESENT(BIC_RAMWatt);
86ba263d 4841 if (platform->rapl_msrs & RAPL_GFX_ENERGY_STATUS)
a98f8860 4842 BIC_PRESENT(BIC_GFXWatt);
889facbe
LB
4843 }
4844
86ba263d 4845 if (platform->rapl_msrs & RAPL_PKG_PERF_STATUS)
a98f8860 4846 BIC_PRESENT(BIC_PKG__);
86ba263d 4847 if (platform->rapl_msrs & RAPL_DRAM_PERF_STATUS)
a98f8860
ZR
4848 BIC_PRESENT(BIC_RAM__);
4849
889facbe 4850 /* units on package 0, verify later other packages match */
7ce7d5de 4851 if (get_msr(base_cpu, MSR_RAPL_POWER_UNIT, &msr))
889facbe
LB
4852 return;
4853
4854 rapl_power_units = 1.0 / (1 << (msr & 0xF));
6d35b8c4 4855 if (platform->has_rapl_divisor)
144b44b1
LB
4856 rapl_energy_units = 1.0 * (1 << (msr >> 8 & 0x1F)) / 1000000;
4857 else
4858 rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F));
889facbe 4859
9e6f3515
ZR
4860 if (platform->has_fixed_rapl_unit)
4861 rapl_dram_energy_units = (15.3 / 1000000);
4862 else
4863 rapl_dram_energy_units = rapl_energy_units;
40ee8e3b 4864
144b44b1
LB
4865 time_unit = msr >> 16 & 0xF;
4866 if (time_unit == 0)
4867 time_unit = 0xA;
889facbe 4868
144b44b1 4869 rapl_time_units = 1.0 / (1 << (time_unit));
889facbe 4870
bf1ad57c 4871 tdp = get_tdp_intel();
889facbe 4872
144b44b1 4873 rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
96e47158 4874 if (!quiet)
b7d8c148 4875 fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
9392bd98 4876}
889facbe 4877
bf1ad57c 4878void rapl_probe_amd(void)
9392bd98
CW
4879{
4880 unsigned long long msr;
9392bd98
CW
4881 double tdp;
4882
33eb8225
KP
4883 if (rapl_joules) {
4884 BIC_PRESENT(BIC_Pkg_J);
4885 BIC_PRESENT(BIC_Cor_J);
4886 } else {
4887 BIC_PRESENT(BIC_PkgWatt);
4888 BIC_PRESENT(BIC_CorWatt);
9392bd98
CW
4889 }
4890
4891 if (get_msr(base_cpu, MSR_RAPL_PWR_UNIT, &msr))
4892 return;
4893
4894 rapl_time_units = ldexp(1.0, -(msr >> 16 & 0xf));
4895 rapl_energy_units = ldexp(1.0, -(msr >> 8 & 0x1f));
4896 rapl_power_units = ldexp(1.0, -(msr & 0xf));
4897
bf1ad57c 4898 tdp = get_tdp_amd();
9392bd98
CW
4899
4900 rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
4901 if (!quiet)
4902 fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
4903}
4904
4905/*
4906 * rapl_probe()
4907 *
86ba263d 4908 * sets rapl_power_units, rapl_energy_units, rapl_time_units
9392bd98 4909 */
bf1ad57c 4910void rapl_probe(void)
9392bd98 4911{
86ba263d
ZR
4912 if (!platform->rapl_msrs)
4913 return;
4914
9392bd98 4915 if (genuine_intel)
bf1ad57c 4916 rapl_probe_intel();
c1c10cc7 4917 if (authentic_amd || hygon_genuine)
bf1ad57c 4918 rapl_probe_amd();
889facbe
LB
4919}
4920
aeb01e6d
CY
4921void prewake_cstate_probe(unsigned int family, unsigned int model)
4922{
684e40e9 4923 if (is_icx(family, model) || is_spr(family, model))
aeb01e6d
CY
4924 dis_cstate_prewake = 1;
4925}
4926
889facbe
LB
4927int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p)
4928{
4929 unsigned long long msr;
f4896fa5 4930 unsigned int dts, dts2;
889facbe
LB
4931 int cpu;
4932
9878bf7a
LB
4933 UNUSED(c);
4934 UNUSED(p);
4935
889facbe
LB
4936 if (!(do_dts || do_ptm))
4937 return 0;
4938
4939 cpu = t->cpu_id;
4940
4941 /* DTS is per-core, no need to print for each thread */
388e9c81 4942 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
889facbe
LB
4943 return 0;
4944
4945 if (cpu_migrate(cpu)) {
3d7772ea 4946 fprintf(outf, "print_thermal: Could not migrate to CPU %d\n", cpu);
889facbe
LB
4947 return -1;
4948 }
4949
4950 if (do_ptm && (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) {
4951 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
4952 return 0;
4953
4954 dts = (msr >> 16) & 0x7F;
1b439f01 4955 fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_STATUS: 0x%08llx (%d C)\n", cpu, msr, tj_max - dts);
889facbe 4956
889facbe
LB
4957 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, &msr))
4958 return 0;
4959
4960 dts = (msr >> 16) & 0x7F;
4961 dts2 = (msr >> 8) & 0x7F;
b7d8c148 4962 fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
55279aef 4963 cpu, msr, tj_max - dts, tj_max - dts2);
889facbe
LB
4964 }
4965
f4896fa5 4966 if (do_dts && debug) {
889facbe
LB
4967 unsigned int resolution;
4968
4969 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
4970 return 0;
4971
4972 dts = (msr >> 16) & 0x7F;
4973 resolution = (msr >> 27) & 0xF;
b7d8c148 4974 fprintf(outf, "cpu%d: MSR_IA32_THERM_STATUS: 0x%08llx (%d C +/- %d)\n",
55279aef 4975 cpu, msr, tj_max - dts, resolution);
889facbe 4976
889facbe
LB
4977 if (get_msr(cpu, MSR_IA32_THERM_INTERRUPT, &msr))
4978 return 0;
4979
4980 dts = (msr >> 16) & 0x7F;
4981 dts2 = (msr >> 8) & 0x7F;
b7d8c148 4982 fprintf(outf, "cpu%d: MSR_IA32_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
55279aef 4983 cpu, msr, tj_max - dts, tj_max - dts2);
889facbe
LB
4984 }
4985
4986 return 0;
4987}
36229897 4988
889facbe
LB
4989void print_power_limit_msr(int cpu, unsigned long long msr, char *label)
4990{
6b398625 4991 fprintf(outf, "cpu%d: %s: %sabled (%0.3f Watts, %f sec, clamp %sabled)\n",
889facbe
LB
4992 cpu, label,
4993 ((msr >> 15) & 1) ? "EN" : "DIS",
4994 ((msr >> 0) & 0x7FFF) * rapl_power_units,
1b439f01 4995 (1.0 + (((msr >> 22) & 0x3) / 4.0)) * (1 << ((msr >> 17) & 0x1F)) * rapl_time_units,
889facbe
LB
4996 (((msr >> 16) & 1) ? "EN" : "DIS"));
4997
4998 return;
4999}
5000
5001int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
5002{
5003 unsigned long long msr;
9392bd98 5004 const char *msr_name;
889facbe 5005 int cpu;
889facbe 5006
9878bf7a
LB
5007 UNUSED(c);
5008 UNUSED(p);
5009
86ba263d 5010 if (!platform->rapl_msrs)
889facbe
LB
5011 return 0;
5012
5013 /* RAPL counters are per package, so print only for 1st thread/package */
5014 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
5015 return 0;
5016
5017 cpu = t->cpu_id;
5018 if (cpu_migrate(cpu)) {
3d7772ea 5019 fprintf(outf, "print_rapl: Could not migrate to CPU %d\n", cpu);
889facbe
LB
5020 return -1;
5021 }
5022
86ba263d 5023 if (platform->rapl_msrs & RAPL_AMD_F17H) {
9392bd98
CW
5024 msr_name = "MSR_RAPL_PWR_UNIT";
5025 if (get_msr(cpu, MSR_RAPL_PWR_UNIT, &msr))
5026 return -1;
5027 } else {
5028 msr_name = "MSR_RAPL_POWER_UNIT";
5029 if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr))
5030 return -1;
5031 }
889facbe 5032
9392bd98 5033 fprintf(outf, "cpu%d: %s: 0x%08llx (%f Watts, %f Joules, %f sec.)\n", cpu, msr_name, msr,
96e47158
LB
5034 rapl_power_units, rapl_energy_units, rapl_time_units);
5035
86ba263d 5036 if (platform->rapl_msrs & RAPL_PKG_POWER_INFO) {
144b44b1 5037
889facbe 5038 if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr))
1b439f01 5039 return -5;
889facbe 5040
b7d8c148 5041 fprintf(outf, "cpu%d: MSR_PKG_POWER_INFO: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
889facbe 5042 cpu, msr,
1b439f01 5043 ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
889facbe
LB
5044 ((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
5045 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units,
5046 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
5047
144b44b1 5048 }
86ba263d 5049 if (platform->rapl_msrs & RAPL_PKG) {
144b44b1 5050
889facbe
LB
5051 if (get_msr(cpu, MSR_PKG_POWER_LIMIT, &msr))
5052 return -9;
5053
b7d8c148 5054 fprintf(outf, "cpu%d: MSR_PKG_POWER_LIMIT: 0x%08llx (%slocked)\n",
96e47158 5055 cpu, msr, (msr >> 63) & 1 ? "" : "UN");
889facbe
LB
5056
5057 print_power_limit_msr(cpu, msr, "PKG Limit #1");
6b398625 5058 fprintf(outf, "cpu%d: PKG Limit #2: %sabled (%0.3f Watts, %f* sec, clamp %sabled)\n",
889facbe
LB
5059 cpu,
5060 ((msr >> 47) & 1) ? "EN" : "DIS",
5061 ((msr >> 32) & 0x7FFF) * rapl_power_units,
1b439f01 5062 (1.0 + (((msr >> 54) & 0x3) / 4.0)) * (1 << ((msr >> 49) & 0x1F)) * rapl_time_units,
889facbe 5063 ((msr >> 48) & 1) ? "EN" : "DIS");
f52ba931
SP
5064
5065 if (get_msr(cpu, MSR_VR_CURRENT_CONFIG, &msr))
5066 return -9;
5067
5068 fprintf(outf, "cpu%d: MSR_VR_CURRENT_CONFIG: 0x%08llx\n", cpu, msr);
5069 fprintf(outf, "cpu%d: PKG Limit #4: %f Watts (%slocked)\n",
164d7a96 5070 cpu, ((msr >> 0) & 0x1FFF) * rapl_power_units, (msr >> 31) & 1 ? "" : "UN");
889facbe
LB
5071 }
5072
86ba263d 5073 if (platform->rapl_msrs & RAPL_DRAM_POWER_INFO) {
889facbe 5074 if (get_msr(cpu, MSR_DRAM_POWER_INFO, &msr))
1b439f01 5075 return -6;
889facbe 5076
b7d8c148 5077 fprintf(outf, "cpu%d: MSR_DRAM_POWER_INFO,: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
889facbe 5078 cpu, msr,
1b439f01 5079 ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
889facbe
LB
5080 ((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
5081 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units,
5082 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
0b2bb692 5083 }
86ba263d 5084 if (platform->rapl_msrs & RAPL_DRAM) {
889facbe
LB
5085 if (get_msr(cpu, MSR_DRAM_POWER_LIMIT, &msr))
5086 return -9;
b7d8c148 5087 fprintf(outf, "cpu%d: MSR_DRAM_POWER_LIMIT: 0x%08llx (%slocked)\n",
1b439f01 5088 cpu, msr, (msr >> 31) & 1 ? "" : "UN");
889facbe
LB
5089
5090 print_power_limit_msr(cpu, msr, "DRAM Limit");
5091 }
86ba263d 5092 if (platform->rapl_msrs & RAPL_CORE_POLICY) {
96e47158
LB
5093 if (get_msr(cpu, MSR_PP0_POLICY, &msr))
5094 return -7;
889facbe 5095
96e47158 5096 fprintf(outf, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF);
144b44b1 5097 }
86ba263d 5098 if (platform->rapl_msrs & RAPL_CORE_POWER_LIMIT) {
96e47158
LB
5099 if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr))
5100 return -9;
5101 fprintf(outf, "cpu%d: MSR_PP0_POWER_LIMIT: 0x%08llx (%slocked)\n",
1b439f01 5102 cpu, msr, (msr >> 31) & 1 ? "" : "UN");
96e47158 5103 print_power_limit_msr(cpu, msr, "Cores Limit");
889facbe 5104 }
86ba263d 5105 if (platform->rapl_msrs & RAPL_GFX) {
96e47158
LB
5106 if (get_msr(cpu, MSR_PP1_POLICY, &msr))
5107 return -8;
889facbe 5108
96e47158 5109 fprintf(outf, "cpu%d: MSR_PP1_POLICY: %lld\n", cpu, msr & 0xF);
889facbe 5110
96e47158
LB
5111 if (get_msr(cpu, MSR_PP1_POWER_LIMIT, &msr))
5112 return -9;
5113 fprintf(outf, "cpu%d: MSR_PP1_POWER_LIMIT: 0x%08llx (%slocked)\n",
1b439f01 5114 cpu, msr, (msr >> 31) & 1 ? "" : "UN");
96e47158 5115 print_power_limit_msr(cpu, msr, "GFX Limit");
889facbe
LB
5116 }
5117 return 0;
5118}
5119
d7899447
LB
5120/*
5121 * SNB adds support for additional MSRs:
5122 *
5123 * MSR_PKG_C7_RESIDENCY 0x000003fa
5124 * MSR_CORE_C7_RESIDENCY 0x000003fe
5125 * MSR_PKG_C2_RESIDENCY 0x0000060d
5126 */
103a8fea 5127
d7899447 5128int has_snb_msrs(unsigned int family, unsigned int model)
103a8fea
LB
5129{
5130 if (!genuine_intel)
5131 return 0;
5132
9878bf7a
LB
5133 if (family != 6)
5134 return 0;
5135
103a8fea 5136 switch (model) {
869ce69e
LB
5137 case INTEL_FAM6_SANDYBRIDGE:
5138 case INTEL_FAM6_SANDYBRIDGE_X:
1b439f01
LB
5139 case INTEL_FAM6_IVYBRIDGE: /* IVB */
5140 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
5141 case INTEL_FAM6_HASWELL: /* HSW */
5142 case INTEL_FAM6_HASWELL_X: /* HSW */
5143 case INTEL_FAM6_HASWELL_L: /* HSW */
5144 case INTEL_FAM6_HASWELL_G: /* HSW */
5145 case INTEL_FAM6_BROADWELL: /* BDW */
5146 case INTEL_FAM6_BROADWELL_G: /* BDW */
5147 case INTEL_FAM6_BROADWELL_X: /* BDX */
5148 case INTEL_FAM6_SKYLAKE_L: /* SKL */
5149 case INTEL_FAM6_CANNONLAKE_L: /* CNL */
5150 case INTEL_FAM6_SKYLAKE_X: /* SKX */
5151 case INTEL_FAM6_ICELAKE_X: /* ICX */
684e40e9 5152 case INTEL_FAM6_SAPPHIRERAPIDS_X: /* SPR */
1b439f01 5153 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
f2c4db1b 5154 case INTEL_FAM6_ATOM_GOLDMONT_PLUS:
5ebb34ed 5155 case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */
1b439f01
LB
5156 case INTEL_FAM6_ATOM_TREMONT: /* EHL */
5157 case INTEL_FAM6_ATOM_TREMONT_D: /* JVL */
103a8fea
LB
5158 return 1;
5159 }
5160 return 0;
5161}
5162
d7899447 5163/*
570992fc 5164 * HSW ULT added support for C8/C9/C10 MSRs:
d7899447 5165 *
5a63426e
LB
5166 * MSR_PKG_C8_RESIDENCY 0x00000630
5167 * MSR_PKG_C9_RESIDENCY 0x00000631
5168 * MSR_PKG_C10_RESIDENCY 0x00000632
5169 *
5170 * MSR_PKGC8_IRTL 0x00000633
5171 * MSR_PKGC9_IRTL 0x00000634
5172 * MSR_PKGC10_IRTL 0x00000635
5173 *
d7899447 5174 */
570992fc 5175int has_c8910_msrs(unsigned int family, unsigned int model)
ca58710f
KCA
5176{
5177 if (!genuine_intel)
5178 return 0;
5179
9878bf7a
LB
5180 if (family != 6)
5181 return 0;
5182
ca58710f 5183 switch (model) {
77e5517c 5184 case INTEL_FAM6_HASWELL_L: /* HSW */
c66f78a6 5185 case INTEL_FAM6_BROADWELL: /* BDW */
af239c44
PZ
5186 case INTEL_FAM6_SKYLAKE_L: /* SKL */
5187 case INTEL_FAM6_CANNONLAKE_L: /* CNL */
869ce69e 5188 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
f2c4db1b 5189 case INTEL_FAM6_ATOM_GOLDMONT_PLUS:
f6708400 5190 case INTEL_FAM6_ATOM_TREMONT: /* EHL */
0b2bb692
LB
5191 return 1;
5192 }
5193 return 0;
5194}
5195
5196/*
5197 * SKL adds support for additional MSRS:
5198 *
5199 * MSR_PKG_WEIGHTED_CORE_C0_RES 0x00000658
5200 * MSR_PKG_ANY_CORE_C0_RES 0x00000659
5201 * MSR_PKG_ANY_GFXE_C0_RES 0x0000065A
5202 * MSR_PKG_BOTH_CORE_GFXE_C0_RES 0x0000065B
5203 */
5204int has_skl_msrs(unsigned int family, unsigned int model)
5205{
5206 if (!genuine_intel)
5207 return 0;
5208
9878bf7a
LB
5209 if (family != 6)
5210 return 0;
5211
0b2bb692 5212 switch (model) {
af239c44
PZ
5213 case INTEL_FAM6_SKYLAKE_L: /* SKL */
5214 case INTEL_FAM6_CANNONLAKE_L: /* CNL */
ca58710f
KCA
5215 return 1;
5216 }
5217 return 0;
5218}
5219
144b44b1
LB
5220int is_slm(unsigned int family, unsigned int model)
5221{
5222 if (!genuine_intel)
5223 return 0;
9878bf7a
LB
5224
5225 if (family != 6)
5226 return 0;
5227
144b44b1 5228 switch (model) {
f2c4db1b 5229 case INTEL_FAM6_ATOM_SILVERMONT: /* BYT */
5ebb34ed 5230 case INTEL_FAM6_ATOM_SILVERMONT_D: /* AVN */
144b44b1
LB
5231 return 1;
5232 }
5233 return 0;
5234}
5235
fb5d4327
DC
5236int is_knl(unsigned int family, unsigned int model)
5237{
5238 if (!genuine_intel)
5239 return 0;
9878bf7a
LB
5240
5241 if (family != 6)
5242 return 0;
5243
fb5d4327 5244 switch (model) {
869ce69e 5245 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
fb5d4327
DC
5246 return 1;
5247 }
5248 return 0;
5249}
5250
997e5395
SP
5251int is_cnl(unsigned int family, unsigned int model)
5252{
5253 if (!genuine_intel)
5254 return 0;
5255
9878bf7a
LB
5256 if (family != 6)
5257 return 0;
5258
997e5395 5259 switch (model) {
1b439f01 5260 case INTEL_FAM6_CANNONLAKE_L: /* CNL */
997e5395
SP
5261 return 1;
5262 }
5263
5264 return 0;
5265}
5266
b2b34dfe
HC
5267unsigned int get_aperf_mperf_multiplier(unsigned int family, unsigned int model)
5268{
5269 if (is_knl(family, model))
5270 return 1024;
5271 return 1;
5272}
5273
7ab5ff49
ZR
5274int get_cpu_type(struct thread_data *t, struct core_data *c, struct pkg_data *p)
5275{
5276 unsigned int eax, ebx, ecx, edx;
5277
9878bf7a
LB
5278 UNUSED(c);
5279 UNUSED(p);
5280
7ab5ff49
ZR
5281 if (!genuine_intel)
5282 return 0;
5283
5284 if (cpu_migrate(t->cpu_id)) {
5285 fprintf(outf, "Could not migrate to CPU %d\n", t->cpu_id);
5286 return -1;
5287 }
5288
5289 if (max_level < 0x1a)
5290 return 0;
5291
5292 __cpuid(0x1a, eax, ebx, ecx, edx);
5293 eax = (eax >> 24) & 0xFF;
1b439f01 5294 if (eax == 0x20)
7ab5ff49
ZR
5295 t->is_atom = true;
5296 return 0;
5297}
5298
889facbe
LB
5299/*
5300 * MSR_IA32_TEMPERATURE_TARGET indicates the temperature where
5301 * the Thermal Control Circuit (TCC) activates.
5302 * This is usually equal to tjMax.
5303 *
5304 * Older processors do not have this MSR, so there we guess,
5305 * but also allow cmdline over-ride with -T.
5306 *
5307 * Several MSR temperature values are in units of degrees-C
5308 * below this value, including the Digital Thermal Sensor (DTS),
5309 * Package Thermal Management Sensor (PTM), and thermal event thresholds.
5310 */
b2b94be7 5311int set_temperature_target(struct thread_data *t, struct core_data *c, struct pkg_data *p)
889facbe
LB
5312{
5313 unsigned long long msr;
55279aef 5314 unsigned int tcc_default, tcc_offset;
b2b94be7 5315 int cpu;
6ff7cb37 5316
9878bf7a
LB
5317 UNUSED(c);
5318 UNUSED(p);
5319
55279aef 5320 /* tj_max is used only for dts or ptm */
889facbe
LB
5321 if (!(do_dts || do_ptm))
5322 return 0;
5323
5324 /* this is a per-package concept */
5325 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
5326 return 0;
5327
b2b94be7
LB
5328 cpu = t->cpu_id;
5329 if (cpu_migrate(cpu)) {
5330 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
5331 return -1;
5332 }
5333
55279aef
ZR
5334 if (tj_max_override != 0) {
5335 tj_max = tj_max_override;
1b439f01 5336 fprintf(outf, "cpu%d: Using cmdline TCC Target (%d C)\n", cpu, tj_max);
889facbe
LB
5337 return 0;
5338 }
5339
b2b94be7 5340 /* Temperature Target MSR is Nehalem and newer only */
fcfa1ce0 5341 if (!platform->has_nhm_msrs)
b2b94be7
LB
5342 goto guess;
5343
5344 if (get_msr(base_cpu, MSR_IA32_TEMPERATURE_TARGET, &msr))
5345 goto guess;
5346
55279aef 5347 tcc_default = (msr >> 16) & 0xFF;
b2b94be7 5348
0b9a0b9b 5349 if (!quiet) {
d8e1623b
ZR
5350 int bits = platform->tcc_offset_bits;
5351 unsigned long long enabled = 0;
5352
5353 if (bits && !get_msr(base_cpu, MSR_PLATFORM_INFO, &enabled))
5354 enabled = (enabled >> 30) & 1;
5355
5356 if (bits && enabled) {
5357 tcc_offset = (msr >> 24) & GENMASK(bits - 1, 0);
0b9a0b9b 5358 fprintf(outf, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C) (%d default - %d offset)\n",
1b439f01 5359 cpu, msr, tcc_default - tcc_offset, tcc_default, tcc_offset);
d8e1623b 5360 } else {
1b439f01 5361 fprintf(outf, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n", cpu, msr, tcc_default);
0b9a0b9b
ZR
5362 }
5363 }
b2b94be7 5364
55279aef 5365 if (!tcc_default)
b2b94be7
LB
5366 goto guess;
5367
55279aef 5368 tj_max = tcc_default;
b2b94be7
LB
5369
5370 return 0;
889facbe 5371
b2b94be7 5372guess:
55279aef 5373 tj_max = TJMAX_DEFAULT;
1b439f01 5374 fprintf(outf, "cpu%d: Guessing tjMax %d C, Please use -T to specify\n", cpu, tj_max);
889facbe
LB
5375
5376 return 0;
5377}
69807a63 5378
aa8d8cc7
LB
5379void decode_feature_control_msr(void)
5380{
5381 unsigned long long msr;
5382
f6505c88 5383 if (!get_msr(base_cpu, MSR_IA32_FEAT_CTL, &msr))
aa8d8cc7 5384 fprintf(outf, "cpu%d: MSR_IA32_FEATURE_CONTROL: 0x%08llx (%sLocked %s)\n",
1b439f01 5385 base_cpu, msr, msr & FEAT_CTL_LOCKED ? "" : "UN-", msr & (1 << 18) ? "SGX" : "");
aa8d8cc7
LB
5386}
5387
69807a63
LB
5388void decode_misc_enable_msr(void)
5389{
5390 unsigned long long msr;
5391
f26b1519
LB
5392 if (!genuine_intel)
5393 return;
5394
69807a63 5395 if (!get_msr(base_cpu, MSR_IA32_MISC_ENABLE, &msr))
e6512624 5396 fprintf(outf, "cpu%d: MSR_IA32_MISC_ENABLE: 0x%08llx (%sTCC %sEIST %sMWAIT %sPREFETCH %sTURBO)\n",
69807a63 5397 base_cpu, msr,
e6512624
LB
5398 msr & MSR_IA32_MISC_ENABLE_TM1 ? "" : "No-",
5399 msr & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP ? "" : "No-",
fd3933ca 5400 msr & MSR_IA32_MISC_ENABLE_MWAIT ? "" : "No-",
e6512624
LB
5401 msr & MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE ? "No-" : "",
5402 msr & MSR_IA32_MISC_ENABLE_TURBO_DISABLE ? "No-" : "");
69807a63
LB
5403}
5404
33148d67
LB
5405void decode_misc_feature_control(void)
5406{
5407 unsigned long long msr;
5408
778fc34a 5409 if (!platform->has_msr_misc_feature_control)
33148d67
LB
5410 return;
5411
5412 if (!get_msr(base_cpu, MSR_MISC_FEATURE_CONTROL, &msr))
1b439f01
LB
5413 fprintf(outf,
5414 "cpu%d: MSR_MISC_FEATURE_CONTROL: 0x%08llx (%sL2-Prefetch %sL2-Prefetch-pair %sL1-Prefetch %sL1-IP-Prefetch)\n",
5415 base_cpu, msr, msr & (0 << 0) ? "No-" : "", msr & (1 << 0) ? "No-" : "",
5416 msr & (2 << 0) ? "No-" : "", msr & (3 << 0) ? "No-" : "");
33148d67 5417}
1b439f01 5418
f0057310
LB
5419/*
5420 * Decode MSR_MISC_PWR_MGMT
5421 *
5422 * Decode the bits according to the Nehalem documentation
5423 * bit[0] seems to continue to have same meaning going forward
5424 * bit[1] less so...
5425 */
5426void decode_misc_pwr_mgmt_msr(void)
5427{
5428 unsigned long long msr;
5429
3dd0e754 5430 if (!platform->has_msr_misc_pwr_mgmt)
cf4cbe53
LB
5431 return;
5432
f0057310 5433 if (!get_msr(base_cpu, MSR_MISC_PWR_MGMT, &msr))
ddadb8ad 5434 fprintf(outf, "cpu%d: MSR_MISC_PWR_MGMT: 0x%08llx (%sable-EIST_Coordination %sable-EPB %sable-OOB)\n",
f0057310 5435 base_cpu, msr,
1b439f01 5436 msr & (1 << 0) ? "DIS" : "EN", msr & (1 << 1) ? "EN" : "DIS", msr & (1 << 8) ? "EN" : "DIS");
f0057310 5437}
1b439f01 5438
71616c8e
LB
5439/*
5440 * Decode MSR_CC6_DEMOTION_POLICY_CONFIG, MSR_MC6_DEMOTION_POLICY_CONFIG
5441 *
5442 * This MSRs are present on Silvermont processors,
5443 * Intel Atom processor E3000 series (Baytrail), and friends.
5444 */
5445void decode_c6_demotion_policy_msr(void)
5446{
5447 unsigned long long msr;
5448
5449 if (!get_msr(base_cpu, MSR_CC6_DEMOTION_POLICY_CONFIG, &msr))
5450 fprintf(outf, "cpu%d: MSR_CC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-CC6-Demotion)\n",
5451 base_cpu, msr, msr & (1 << 0) ? "EN" : "DIS");
5452
5453 if (!get_msr(base_cpu, MSR_MC6_DEMOTION_POLICY_CONFIG, &msr))
5454 fprintf(outf, "cpu%d: MSR_MC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-MC6-Demotion)\n",
5455 base_cpu, msr, msr & (1 << 0) ? "EN" : "DIS");
5456}
7f5c258e 5457
f5a4c76a
LB
5458/*
5459 * When models are the same, for the purpose of turbostat, reuse
5460 */
5461unsigned int intel_model_duplicates(unsigned int model)
5462{
5463
1b439f01 5464 switch (model) {
f5a4c76a 5465 case INTEL_FAM6_NEHALEM_EP: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */
6d306d6e 5466 case INTEL_FAM6_NEHALEM_G: /* Core i7 and i5 Processor - Nehalem */
f5a4c76a
LB
5467 case INTEL_FAM6_WESTMERE: /* Westmere Client - Clarkdale, Arrandale */
5468 case INTEL_FAM6_WESTMERE_EP: /* Westmere EP - Gulftown */
5469 return INTEL_FAM6_NEHALEM;
5470
f5a4c76a
LB
5471 case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */
5472 return INTEL_FAM6_NEHALEM_EX;
5473
5474 case INTEL_FAM6_XEON_PHI_KNM:
5475 return INTEL_FAM6_XEON_PHI_KNL;
5476
5ebb34ed 5477 case INTEL_FAM6_BROADWELL_D: /* BDX-DE */
f5a4c76a
LB
5478 return INTEL_FAM6_BROADWELL_X;
5479
c66f78a6 5480 case INTEL_FAM6_SKYLAKE:
af239c44 5481 case INTEL_FAM6_KABYLAKE_L:
c66f78a6 5482 case INTEL_FAM6_KABYLAKE:
081c5432
CY
5483 case INTEL_FAM6_COMETLAKE_L:
5484 case INTEL_FAM6_COMETLAKE:
af239c44 5485 return INTEL_FAM6_SKYLAKE_L;
937807d3 5486
af239c44 5487 case INTEL_FAM6_ICELAKE_L:
d93ea567 5488 case INTEL_FAM6_ICELAKE_NNPI:
4bf7132a
CY
5489 case INTEL_FAM6_TIGERLAKE_L:
5490 case INTEL_FAM6_TIGERLAKE:
e7af1ed3
LB
5491 case INTEL_FAM6_ROCKETLAKE:
5492 case INTEL_FAM6_LAKEFIELD:
5493 case INTEL_FAM6_ALDERLAKE:
5683460b 5494 case INTEL_FAM6_ALDERLAKE_L:
882cdb06 5495 case INTEL_FAM6_ATOM_GRACEMONT:
fb5e29df 5496 case INTEL_FAM6_RAPTORLAKE:
6f9cf553 5497 case INTEL_FAM6_RAPTORLAKE_P:
9b1c2ecf 5498 case INTEL_FAM6_RAPTORLAKE_S:
8e45a9bf
ZR
5499 case INTEL_FAM6_METEORLAKE:
5500 case INTEL_FAM6_METEORLAKE_L:
af239c44 5501 return INTEL_FAM6_CANNONLAKE_L;
b62b3184 5502
d7814c30
CY
5503 case INTEL_FAM6_ATOM_TREMONT_L:
5504 return INTEL_FAM6_ATOM_TREMONT;
5505
6c5c6560 5506 case INTEL_FAM6_ICELAKE_D:
25368d7c 5507 return INTEL_FAM6_ICELAKE_X;
93cac415
ZR
5508
5509 case INTEL_FAM6_EMERALDRAPIDS_X:
5510 return INTEL_FAM6_SAPPHIRERAPIDS_X;
f5a4c76a
LB
5511 }
5512 return model;
5513}
d76bb7a0
LB
5514
5515void print_dev_latency(void)
5516{
5517 char *path = "/dev/cpu_dma_latency";
5518 int fd;
5519 int value;
5520 int retval;
5521
5522 fd = open(path, O_RDONLY);
5523 if (fd < 0) {
de7839ee 5524 warnx("capget(CAP_SYS_ADMIN) failed, try \"# setcap cap_sys_admin=ep %s\"", progname);
d76bb7a0
LB
5525 return;
5526 }
5527
5528 retval = read(fd, (void *)&value, sizeof(int));
5529 if (retval != sizeof(int)) {
6cbfedc7 5530 warn("read failed %s", path);
d76bb7a0
LB
5531 close(fd);
5532 return;
5533 }
1b439f01 5534 fprintf(outf, "/dev/cpu_dma_latency: %d usec (%s)\n", value, value == 2000000000 ? "default" : "constrained");
d76bb7a0
LB
5535
5536 close(fd);
5537}
5538
2af4f9b8 5539/*
2db0e5eb 5540 * Linux-perf manages the HW instructions-retired counter
2af4f9b8
LB
5541 * by enabling when requested, and hiding rollover
5542 */
5543void linux_perf_init(void)
5544{
5545 if (!BIC_IS_ENABLED(BIC_IPC))
5546 return;
5547
5548 if (access("/proc/sys/kernel/perf_event_paranoid", F_OK))
5549 return;
5550
5551 fd_instr_count_percpu = calloc(topo.max_cpu_num + 1, sizeof(int));
5552 if (fd_instr_count_percpu == NULL)
5553 err(-1, "calloc fd_instr_count_percpu");
5554
5555 BIC_PRESENT(BIC_IPC);
5556}
5557
3c6a17b8
ZR
5558void probe_cstates(void)
5559{
5560 probe_cst_limit();
5561
5562 if (platform->supported_cstates & CC1)
5563 BIC_PRESENT(BIC_CPU_c1);
5564
5565 if (platform->supported_cstates & CC3)
5566 BIC_PRESENT(BIC_CPU_c3);
5567
5568 if (platform->supported_cstates & CC6)
5569 BIC_PRESENT(BIC_CPU_c6);
5570
5571 if (platform->supported_cstates & CC7)
5572 BIC_PRESENT(BIC_CPU_c7);
5573
5574 if (platform->supported_cstates & PC2 && (pkg_cstate_limit >= PCL__2))
5575 BIC_PRESENT(BIC_Pkgpc2);
5576
5577 if (platform->supported_cstates & PC3 && (pkg_cstate_limit >= PCL__3))
5578 BIC_PRESENT(BIC_Pkgpc3);
5579
5580 if (platform->supported_cstates & PC6 && (pkg_cstate_limit >= PCL__6))
5581 BIC_PRESENT(BIC_Pkgpc6);
5582
5583 if (platform->supported_cstates & PC7 && (pkg_cstate_limit >= PCL__7))
5584 BIC_PRESENT(BIC_Pkgpc7);
5585
5586 if (platform->supported_cstates & PC8 && (pkg_cstate_limit >= PCL__8))
5587 BIC_PRESENT(BIC_Pkgpc8);
5588
5589 if (platform->supported_cstates & PC9 && (pkg_cstate_limit >= PCL__9))
5590 BIC_PRESENT(BIC_Pkgpc9);
5591
5592 if (platform->supported_cstates & PC10 && (pkg_cstate_limit >= PCL_10))
5593 BIC_PRESENT(BIC_Pkgpc10);
5594}
5595
fcd17211 5596void process_cpuid()
103a8fea 5597{
34041551
LB
5598 unsigned int eax, ebx, ecx, edx;
5599 unsigned int fms, family, model, stepping, ecx_flags, edx_flags;
ed0757b8 5600 unsigned long long ucode_patch = 0;
103a8fea
LB
5601
5602 eax = ebx = ecx = edx = 0;
5603
5aea2f7f 5604 __cpuid(0, max_level, ebx, ecx, edx);
103a8fea 5605
34041551 5606 if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69)
103a8fea 5607 genuine_intel = 1;
34041551
LB
5608 else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65)
5609 authentic_amd = 1;
c1c10cc7
PW
5610 else if (ebx == 0x6f677948 && ecx == 0x656e6975 && edx == 0x6e65476e)
5611 hygon_genuine = 1;
103a8fea 5612
96e47158 5613 if (!quiet)
ed0757b8
LB
5614 fprintf(outf, "CPUID(0): %.4s%.4s%.4s 0x%x CPUID levels\n",
5615 (char *)&ebx, (char *)&edx, (char *)&ecx, max_level);
103a8fea 5616
5aea2f7f 5617 __cpuid(1, fms, ebx, ecx, edx);
103a8fea
LB
5618 family = (fms >> 8) & 0xf;
5619 model = (fms >> 4) & 0xf;
5620 stepping = fms & 0xf;
5aa3d1a2
CW
5621 if (family == 0xf)
5622 family += (fms >> 20) & 0xff;
5623 if (family >= 6)
103a8fea 5624 model += ((fms >> 16) & 0xf) << 4;
34041551
LB
5625 ecx_flags = ecx;
5626 edx_flags = edx;
103a8fea 5627
ed0757b8 5628 if (get_msr(sched_getcpu(), MSR_IA32_UCODE_REV, &ucode_patch))
6cbfedc7 5629 warnx("get_msr(UCODE)");
ed0757b8 5630
103a8fea
LB
5631 /*
5632 * check max extended function levels of CPUID.
5633 * This is needed to check for invariant TSC.
5634 * This check is valid for both Intel and AMD.
5635 */
5636 ebx = ecx = edx = 0;
5aea2f7f 5637 __cpuid(0x80000000, max_extended_level, ebx, ecx, edx);
103a8fea 5638
34041551 5639 if (!quiet) {
ed0757b8 5640 fprintf(outf, "CPUID(1): family:model:stepping 0x%x:%x:%x (%d:%d:%d) microcode 0x%x\n",
1b439f01
LB
5641 family, model, stepping, family, model, stepping,
5642 (unsigned int)((ucode_patch >> 32) & 0xFFFFFFFF));
ed0757b8 5643 fprintf(outf, "CPUID(0x80000000): max_extended_levels: 0x%x\n", max_extended_level);
34041551
LB
5644 fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s %s\n",
5645 ecx_flags & (1 << 0) ? "SSE3" : "-",
5646 ecx_flags & (1 << 3) ? "MONITOR" : "-",
5647 ecx_flags & (1 << 6) ? "SMX" : "-",
5648 ecx_flags & (1 << 7) ? "EIST" : "-",
5649 ecx_flags & (1 << 8) ? "TM2" : "-",
5650 edx_flags & (1 << 4) ? "TSC" : "-",
5651 edx_flags & (1 << 5) ? "MSR" : "-",
5652 edx_flags & (1 << 22) ? "ACPI-TM" : "-",
1b439f01 5653 edx_flags & (1 << 28) ? "HT" : "-", edx_flags & (1 << 29) ? "TM" : "-");
34041551 5654 }
b98a6d78 5655
45232ab1 5656 probe_platform_features(family, model);
b98a6d78 5657 if (genuine_intel)
f5a4c76a 5658 model = intel_model_duplicates(model);
34041551
LB
5659
5660 if (!(edx_flags & (1 << 5)))
5661 errx(1, "CPUID: no MSR");
5662
61a87ba7 5663 if (max_extended_level >= 0x80000007) {
103a8fea 5664
d7899447
LB
5665 /*
5666 * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8
5667 * this check is valid for both Intel and AMD
5668 */
5aea2f7f 5669 __cpuid(0x80000007, eax, ebx, ecx, edx);
d7899447
LB
5670 has_invariant_tsc = edx & (1 << 8);
5671 }
103a8fea
LB
5672
5673 /*
5674 * APERF/MPERF is advertised by CPUID.EAX=0x6: ECX.bit0
5675 * this check is valid for both Intel and AMD
5676 */
5677
5aea2f7f 5678 __cpuid(0x6, eax, ebx, ecx, edx);
8209e054 5679 has_aperf = ecx & (1 << 0);
812db3f7
LB
5680 if (has_aperf) {
5681 BIC_PRESENT(BIC_Avg_MHz);
5682 BIC_PRESENT(BIC_Busy);
5683 BIC_PRESENT(BIC_Bzy_MHz);
5684 }
889facbe 5685 do_dts = eax & (1 << 0);
812db3f7
LB
5686 if (do_dts)
5687 BIC_PRESENT(BIC_CoreTmp);
b3a34e93 5688 has_turbo = eax & (1 << 1);
889facbe 5689 do_ptm = eax & (1 << 6);
812db3f7
LB
5690 if (do_ptm)
5691 BIC_PRESENT(BIC_PkgTmp);
7f5c258e
LB
5692 has_hwp = eax & (1 << 7);
5693 has_hwp_notify = eax & (1 << 8);
5694 has_hwp_activity_window = eax & (1 << 9);
5695 has_hwp_epp = eax & (1 << 10);
5696 has_hwp_pkg = eax & (1 << 11);
889facbe
LB
5697 has_epb = ecx & (1 << 3);
5698
96e47158 5699 if (!quiet)
b3a34e93 5700 fprintf(outf, "CPUID(6): %sAPERF, %sTURBO, %sDTS, %sPTM, %sHWP, "
7f5c258e
LB
5701 "%sHWPnotify, %sHWPwindow, %sHWPepp, %sHWPpkg, %sEPB\n",
5702 has_aperf ? "" : "No-",
b3a34e93 5703 has_turbo ? "" : "No-",
7f5c258e
LB
5704 do_dts ? "" : "No-",
5705 do_ptm ? "" : "No-",
5706 has_hwp ? "" : "No-",
5707 has_hwp_notify ? "" : "No-",
5708 has_hwp_activity_window ? "" : "No-",
1b439f01 5709 has_hwp_epp ? "" : "No-", has_hwp_pkg ? "" : "No-", has_epb ? "" : "No-");
103a8fea 5710
96e47158 5711 if (!quiet)
69807a63
LB
5712 decode_misc_enable_msr();
5713
96e47158 5714 if (max_level >= 0x7 && !quiet) {
aa8d8cc7 5715 int has_sgx;
103a8fea 5716
aa8d8cc7
LB
5717 ecx = 0;
5718
5719 __cpuid_count(0x7, 0, eax, ebx, ecx, edx);
5720
5721 has_sgx = ebx & (1 << 2);
774627c5
LB
5722
5723 is_hybrid = edx & (1 << 15);
5724
5725 fprintf(outf, "CPUID(7): %sSGX %sHybrid\n", has_sgx ? "" : "No-", is_hybrid ? "" : "No-");
aa8d8cc7
LB
5726
5727 if (has_sgx)
5728 decode_feature_control_msr();
5729 }
5730
61a87ba7 5731 if (max_level >= 0x15) {
8a5bdf41
LB
5732 unsigned int eax_crystal;
5733 unsigned int ebx_tsc;
5734
5735 /*
5736 * CPUID 15H TSC/Crystal ratio, possibly Crystal Hz
5737 */
5738 eax_crystal = ebx_tsc = crystal_hz = edx = 0;
5aea2f7f 5739 __cpuid(0x15, eax_crystal, ebx_tsc, crystal_hz, edx);
8a5bdf41
LB
5740
5741 if (ebx_tsc != 0) {
96e47158 5742 if (!quiet && (ebx != 0))
b7d8c148 5743 fprintf(outf, "CPUID(0x15): eax_crystal: %d ebx_tsc: %d ecx_crystal_hz: %d\n",
8a5bdf41
LB
5744 eax_crystal, ebx_tsc, crystal_hz);
5745
5746 if (crystal_hz == 0)
a5d1ab93 5747 crystal_hz = platform->crystal_freq;
8a5bdf41
LB
5748
5749 if (crystal_hz) {
1b439f01 5750 tsc_hz = (unsigned long long)crystal_hz *ebx_tsc / eax_crystal;
96e47158 5751 if (!quiet)
b7d8c148 5752 fprintf(outf, "TSC: %lld MHz (%d Hz * %d / %d / 1000000)\n",
1b439f01 5753 tsc_hz / 1000000, crystal_hz, ebx_tsc, eax_crystal);
8a5bdf41
LB
5754 }
5755 }
5756 }
61a87ba7
LB
5757 if (max_level >= 0x16) {
5758 unsigned int base_mhz, max_mhz, bus_mhz, edx;
5759
5760 /*
5761 * CPUID 16H Base MHz, Max MHz, Bus MHz
5762 */
5763 base_mhz = max_mhz = bus_mhz = edx = 0;
5764
5aea2f7f 5765 __cpuid(0x16, base_mhz, max_mhz, bus_mhz, edx);
96e47158 5766 if (!quiet)
b7d8c148 5767 fprintf(outf, "CPUID(0x16): base_mhz: %d max_mhz: %d bus_mhz: %d\n",
61a87ba7
LB
5768 base_mhz, max_mhz, bus_mhz);
5769 }
8a5bdf41 5770
b2b34dfe
HC
5771 if (has_aperf)
5772 aperf_mperf_multiplier = get_aperf_mperf_multiplier(family, model);
5773
812db3f7
LB
5774 BIC_PRESENT(BIC_IRQ);
5775 BIC_PRESENT(BIC_TSC_MHz);
5776
3c6a17b8
ZR
5777 probe_cstates();
5778
ce7ddf8a 5779 if (platform->has_nhm_msrs)
812db3f7 5780 BIC_PRESENT(BIC_SMI);
71e84129 5781 probe_bclk();
812db3f7 5782
5a63426e 5783 do_irtl_snb = has_snb_msrs(family, model);
0539ba11 5784 if (has_slv_msrs(family, model)) {
0539ba11
LB
5785 BIC_PRESENT(BIC_Mod_c6);
5786 use_c1_residency_msr = 1;
5787 }
7170a374 5788 if (is_dnv(family, model)) {
7170a374
LB
5789 use_c1_residency_msr = 1;
5790 }
570992fc 5791 do_irtl_hsw = has_c8910_msrs(family, model);
a99d8730
LB
5792 if (has_skl_msrs(family, model)) {
5793 BIC_PRESENT(BIC_Totl_c0);
5794 BIC_PRESENT(BIC_Any_c0);
5795 BIC_PRESENT(BIC_GFX_c0);
5796 BIC_PRESENT(BIC_CPUGFX);
5797 }
144b44b1 5798 do_slm_cstates = is_slm(family, model);
1b439f01 5799 do_knl_cstates = is_knl(family, model);
103a8fea 5800
1b439f01 5801 if (do_slm_cstates || do_knl_cstates || is_cnl(family, model) || is_ehl(family, model))
562855ee 5802 BIC_NOT_PRESENT(BIC_CPU_c3);
103a8fea 5803
96e47158 5804 if (!quiet)
f0057310
LB
5805 decode_misc_pwr_mgmt_msr();
5806
96e47158 5807 if (!quiet && has_slv_msrs(family, model))
71616c8e
LB
5808 decode_c6_demotion_policy_msr();
5809
bf1ad57c 5810 rapl_probe();
b61b7d8c 5811 prewake_cstate_probe(family, model);
889facbe 5812
96e47158 5813 if (!quiet)
a61c9cb4 5814 dump_cstate_pstate_config_info();
a5c6d65d 5815 intel_uncore_frequency_probe();
fcd17211 5816
d76bb7a0
LB
5817 if (!quiet)
5818 print_dev_latency();
41618e63
LB
5819 if (!quiet)
5820 dump_sysfs_cstate_config();
7293fccd
LB
5821 if (!quiet)
5822 dump_sysfs_pstate_config();
41618e63 5823
812db3f7
LB
5824 if (!access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK))
5825 BIC_PRESENT(BIC_GFX_rc6);
fdf676e5 5826
2c019d65
ZR
5827 if (!access("/sys/class/drm/card0/gt_cur_freq_mhz", R_OK) ||
5828 !access("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", R_OK))
812db3f7 5829 BIC_PRESENT(BIC_GFXMHz);
27d47356 5830
2c019d65
ZR
5831 if (!access("/sys/class/drm/card0/gt_act_freq_mhz", R_OK) ||
5832 !access("/sys/class/graphics/fb0/device/drm/card0/gt_act_freq_mhz", R_OK))
b4b91569
RA
5833 BIC_PRESENT(BIC_GFXACTMHz);
5834
be0e54c4
LB
5835 if (!access("/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us", R_OK))
5836 BIC_PRESENT(BIC_CPU_LPI);
5837 else
5838 BIC_NOT_PRESENT(BIC_CPU_LPI);
5839
eae97e05
CY
5840 if (!access("/sys/devices/system/cpu/cpu0/thermal_throttle/core_throttle_count", R_OK))
5841 BIC_PRESENT(BIC_CORE_THROT_CNT);
5842 else
5843 BIC_NOT_PRESENT(BIC_CORE_THROT_CNT);
5844
1f81c5ef
LB
5845 if (!access(sys_lpi_file_sysfs, R_OK)) {
5846 sys_lpi_file = sys_lpi_file_sysfs;
be0e54c4 5847 BIC_PRESENT(BIC_SYS_LPI);
1f81c5ef
LB
5848 } else if (!access(sys_lpi_file_debugfs, R_OK)) {
5849 sys_lpi_file = sys_lpi_file_debugfs;
5850 BIC_PRESENT(BIC_SYS_LPI);
5851 } else {
5852 sys_lpi_file_sysfs = NULL;
be0e54c4 5853 BIC_NOT_PRESENT(BIC_SYS_LPI);
1f81c5ef 5854 }
be0e54c4 5855
96e47158 5856 if (!quiet)
33148d67
LB
5857 decode_misc_feature_control();
5858
889facbe 5859 return;
103a8fea
LB
5860}
5861
103a8fea
LB
5862/*
5863 * in /dev/cpu/ return success for names that are numbers
5864 * ie. filter out ".", "..", "microcode".
5865 */
5866int dir_filter(const struct dirent *dirp)
5867{
5868 if (isdigit(dirp->d_name[0]))
5869 return 1;
5870 else
5871 return 0;
5872}
5873
c98d5d94
LB
5874void topology_probe()
5875{
5876 int i;
5877 int max_core_id = 0;
5878 int max_package_id = 0;
6de68fe1 5879 int max_die_id = 0;
c98d5d94 5880 int max_siblings = 0;
c98d5d94
LB
5881
5882 /* Initialize num_cpus, max_cpu_num */
843c5791 5883 set_max_cpu_num();
c98d5d94 5884 topo.num_cpus = 0;
c98d5d94
LB
5885 for_all_proc_cpus(count_cpus);
5886 if (!summary_only && topo.num_cpus > 1)
812db3f7 5887 BIC_PRESENT(BIC_CPU);
c98d5d94 5888
d8af6f5f 5889 if (debug > 1)
b7d8c148 5890 fprintf(outf, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num);
c98d5d94 5891
1b439f01 5892 cpus = calloc(1, (topo.max_cpu_num + 1) * sizeof(struct cpu_topology));
b2c95d90
JT
5893 if (cpus == NULL)
5894 err(1, "calloc cpus");
c98d5d94
LB
5895
5896 /*
5897 * Allocate and initialize cpu_present_set
5898 */
5899 cpu_present_set = CPU_ALLOC((topo.max_cpu_num + 1));
b2c95d90
JT
5900 if (cpu_present_set == NULL)
5901 err(3, "CPU_ALLOC");
c98d5d94
LB
5902 cpu_present_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
5903 CPU_ZERO_S(cpu_present_setsize, cpu_present_set);
5904 for_all_proc_cpus(mark_cpu_present);
5905
1ef7d21a
LB
5906 /*
5907 * Validate that all cpus in cpu_subset are also in cpu_present_set
5908 */
5909 for (i = 0; i < CPU_SUBSET_MAXCPUS; ++i) {
5910 if (CPU_ISSET_S(i, cpu_subset_size, cpu_subset))
5911 if (!CPU_ISSET_S(i, cpu_present_setsize, cpu_present_set))
5912 err(1, "cpu%d not present", i);
5913 }
5914
c98d5d94
LB
5915 /*
5916 * Allocate and initialize cpu_affinity_set
5917 */
5918 cpu_affinity_set = CPU_ALLOC((topo.max_cpu_num + 1));
b2c95d90
JT
5919 if (cpu_affinity_set == NULL)
5920 err(3, "CPU_ALLOC");
c98d5d94
LB
5921 cpu_affinity_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
5922 CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
5923
8cb48b32 5924 for_all_proc_cpus(init_thread_id);
c98d5d94
LB
5925
5926 /*
5927 * For online cpus
5928 * find max_core_id, max_package_id
5929 */
5930 for (i = 0; i <= topo.max_cpu_num; ++i) {
5931 int siblings;
5932
5933 if (cpu_is_not_present(i)) {
d8af6f5f 5934 if (debug > 1)
b7d8c148 5935 fprintf(outf, "cpu%d NOT PRESENT\n", i);
c98d5d94
LB
5936 continue;
5937 }
c98d5d94 5938
0e2d8f05
LB
5939 cpus[i].logical_cpu_id = i;
5940
5941 /* get package information */
c98d5d94
LB
5942 cpus[i].physical_package_id = get_physical_package_id(i);
5943 if (cpus[i].physical_package_id > max_package_id)
5944 max_package_id = cpus[i].physical_package_id;
5945
6de68fe1
LB
5946 /* get die information */
5947 cpus[i].die_id = get_die_id(i);
5948 if (cpus[i].die_id > max_die_id)
5949 max_die_id = cpus[i].die_id;
5950
0e2d8f05 5951 /* get numa node information */
ef605741
PB
5952 cpus[i].physical_node_id = get_physical_node_id(&cpus[i]);
5953 if (cpus[i].physical_node_id > topo.max_node_num)
5954 topo.max_node_num = cpus[i].physical_node_id;
0e2d8f05
LB
5955
5956 /* get core information */
5957 cpus[i].physical_core_id = get_core_id(i);
5958 if (cpus[i].physical_core_id > max_core_id)
5959 max_core_id = cpus[i].physical_core_id;
5960
5961 /* get thread information */
5962 siblings = get_thread_siblings(&cpus[i]);
c98d5d94
LB
5963 if (siblings > max_siblings)
5964 max_siblings = siblings;
4f206a0f 5965 if (cpus[i].thread_id == 0)
8cb48b32 5966 topo.num_cores++;
c98d5d94 5967 }
ef605741 5968
70a9c6e8 5969 topo.cores_per_node = max_core_id + 1;
d8af6f5f 5970 if (debug > 1)
1b439f01 5971 fprintf(outf, "max_core_id %d, sizing for %d cores per package\n", max_core_id, topo.cores_per_node);
70a9c6e8 5972 if (!summary_only && topo.cores_per_node > 1)
812db3f7 5973 BIC_PRESENT(BIC_Core);
c98d5d94 5974
6de68fe1
LB
5975 topo.num_die = max_die_id + 1;
5976 if (debug > 1)
1b439f01 5977 fprintf(outf, "max_die_id %d, sizing for %d die\n", max_die_id, topo.num_die);
6de68fe1
LB
5978 if (!summary_only && topo.num_die > 1)
5979 BIC_PRESENT(BIC_Die);
5980
c98d5d94 5981 topo.num_packages = max_package_id + 1;
d8af6f5f 5982 if (debug > 1)
1b439f01 5983 fprintf(outf, "max_package_id %d, sizing for %d packages\n", max_package_id, topo.num_packages);
7da6e3e2 5984 if (!summary_only && topo.num_packages > 1)
812db3f7 5985 BIC_PRESENT(BIC_Package);
c98d5d94 5986
ef605741
PB
5987 set_node_data();
5988 if (debug > 1)
70a9c6e8 5989 fprintf(outf, "nodes_per_pkg %d\n", topo.nodes_per_pkg);
01235041
PB
5990 if (!summary_only && topo.nodes_per_pkg > 1)
5991 BIC_PRESENT(BIC_Node);
ef605741 5992
70a9c6e8 5993 topo.threads_per_core = max_siblings;
d8af6f5f 5994 if (debug > 1)
b7d8c148 5995 fprintf(outf, "max_siblings %d\n", max_siblings);
2ffbb224
PB
5996
5997 if (debug < 1)
5998 return;
5999
6000 for (i = 0; i <= topo.max_cpu_num; ++i) {
0ec712e3
LB
6001 if (cpu_is_not_present(i))
6002 continue;
2ffbb224 6003 fprintf(outf,
6de68fe1
LB
6004 "cpu %d pkg %d die %d node %d lnode %d core %d thread %d\n",
6005 i, cpus[i].physical_package_id, cpus[i].die_id,
1b439f01 6006 cpus[i].physical_node_id, cpus[i].logical_node_id, cpus[i].physical_core_id, cpus[i].thread_id);
2ffbb224
PB
6007 }
6008
c98d5d94
LB
6009}
6010
1b439f01 6011void allocate_counters(struct thread_data **t, struct core_data **c, struct pkg_data **p)
c98d5d94
LB
6012{
6013 int i;
1b439f01 6014 int num_cores = topo.cores_per_node * topo.nodes_per_pkg * topo.num_packages;
40f5cfe7 6015 int num_threads = topo.threads_per_core * num_cores;
c98d5d94 6016
40f5cfe7 6017 *t = calloc(num_threads, sizeof(struct thread_data));
c98d5d94
LB
6018 if (*t == NULL)
6019 goto error;
6020
40f5cfe7 6021 for (i = 0; i < num_threads; i++)
c98d5d94
LB
6022 (*t)[i].cpu_id = -1;
6023
40f5cfe7 6024 *c = calloc(num_cores, sizeof(struct core_data));
c98d5d94
LB
6025 if (*c == NULL)
6026 goto error;
6027
40f5cfe7 6028 for (i = 0; i < num_cores; i++)
c98d5d94
LB
6029 (*c)[i].core_id = -1;
6030
678a3bd1 6031 *p = calloc(topo.num_packages, sizeof(struct pkg_data));
c98d5d94
LB
6032 if (*p == NULL)
6033 goto error;
6034
6035 for (i = 0; i < topo.num_packages; i++)
6036 (*p)[i].package_id = i;
6037
6038 return;
6039error:
b2c95d90 6040 err(1, "calloc counters");
c98d5d94 6041}
1b439f01 6042
c98d5d94
LB
6043/*
6044 * init_counter()
6045 *
c98d5d94 6046 * set FIRST_THREAD_IN_CORE and FIRST_CORE_IN_PACKAGE
c98d5d94 6047 */
1b439f01 6048void init_counter(struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base, int cpu_id)
c98d5d94 6049{
8cb48b32 6050 int pkg_id = cpus[cpu_id].physical_package_id;
40f5cfe7 6051 int node_id = cpus[cpu_id].logical_node_id;
8cb48b32
PB
6052 int core_id = cpus[cpu_id].physical_core_id;
6053 int thread_id = cpus[cpu_id].thread_id;
c98d5d94
LB
6054 struct thread_data *t;
6055 struct core_data *c;
6056 struct pkg_data *p;
6057
42dd4520
NC
6058 /* Workaround for systems where physical_node_id==-1
6059 * and logical_node_id==(-1 - topo.num_cpus)
6060 */
6061 if (node_id < 0)
6062 node_id = 0;
6063
40f5cfe7
PB
6064 t = GET_THREAD(thread_base, thread_id, core_id, node_id, pkg_id);
6065 c = GET_CORE(core_base, core_id, node_id, pkg_id);
8cb48b32 6066 p = GET_PKG(pkg_base, pkg_id);
c98d5d94
LB
6067
6068 t->cpu_id = cpu_id;
8cb48b32 6069 if (thread_id == 0) {
c98d5d94
LB
6070 t->flags |= CPU_IS_FIRST_THREAD_IN_CORE;
6071 if (cpu_is_first_core_in_package(cpu_id))
6072 t->flags |= CPU_IS_FIRST_CORE_IN_PACKAGE;
6073 }
6074
8cb48b32
PB
6075 c->core_id = core_id;
6076 p->package_id = pkg_id;
c98d5d94
LB
6077}
6078
c98d5d94
LB
6079int initialize_counters(int cpu_id)
6080{
8cb48b32
PB
6081 init_counter(EVEN_COUNTERS, cpu_id);
6082 init_counter(ODD_COUNTERS, cpu_id);
c98d5d94
LB
6083 return 0;
6084}
6085
6086void allocate_output_buffer()
6087{
eeb71c95 6088 output_buffer = calloc(1, (1 + topo.num_cpus) * 2048);
c98d5d94 6089 outp = output_buffer;
b2c95d90
JT
6090 if (outp == NULL)
6091 err(-1, "calloc output buffer");
c98d5d94 6092}
1b439f01 6093
36229897
LB
6094void allocate_fd_percpu(void)
6095{
01a67adf 6096 fd_percpu = calloc(topo.max_cpu_num + 1, sizeof(int));
36229897
LB
6097 if (fd_percpu == NULL)
6098 err(-1, "calloc fd_percpu");
6099}
1b439f01 6100
562a2d37
LB
6101void allocate_irq_buffers(void)
6102{
6103 irq_column_2_cpu = calloc(topo.num_cpus, sizeof(int));
6104 if (irq_column_2_cpu == NULL)
6105 err(-1, "calloc %d", topo.num_cpus);
c98d5d94 6106
01a67adf 6107 irqs_per_cpu = calloc(topo.max_cpu_num + 1, sizeof(int));
562a2d37 6108 if (irqs_per_cpu == NULL)
01a67adf 6109 err(-1, "calloc %d", topo.max_cpu_num + 1);
562a2d37 6110}
1b439f01 6111
c98d5d94
LB
6112void setup_all_buffers(void)
6113{
6114 topology_probe();
562a2d37 6115 allocate_irq_buffers();
36229897 6116 allocate_fd_percpu();
c98d5d94
LB
6117 allocate_counters(&thread_even, &core_even, &package_even);
6118 allocate_counters(&thread_odd, &core_odd, &package_odd);
6119 allocate_output_buffer();
6120 for_all_proc_cpus(initialize_counters);
6121}
3b4d5c7f 6122
7ce7d5de
PB
6123void set_base_cpu(void)
6124{
6125 base_cpu = sched_getcpu();
6126 if (base_cpu < 0)
6127 err(-ENODEV, "No valid cpus found");
6128
6129 if (debug > 1)
b7d8c148 6130 fprintf(outf, "base_cpu = %d\n", base_cpu);
7ce7d5de
PB
6131}
6132
103a8fea
LB
6133void turbostat_init()
6134{
7ce7d5de
PB
6135 setup_all_buffers();
6136 set_base_cpu();
103a8fea 6137 check_dev_msr();
98481e79 6138 check_permissions();
fcd17211 6139 process_cpuid();
2af4f9b8 6140 linux_perf_init();
103a8fea 6141
96e47158 6142 if (!quiet)
7f5c258e
LB
6143 for_all_cpus(print_hwp, ODD_COUNTERS);
6144
96e47158 6145 if (!quiet)
889facbe
LB
6146 for_all_cpus(print_epb, ODD_COUNTERS);
6147
96e47158 6148 if (!quiet)
3a9a941d
LB
6149 for_all_cpus(print_perf_limit, ODD_COUNTERS);
6150
96e47158 6151 if (!quiet)
889facbe
LB
6152 for_all_cpus(print_rapl, ODD_COUNTERS);
6153
6154 for_all_cpus(set_temperature_target, ODD_COUNTERS);
6155
7ab5ff49
ZR
6156 for_all_cpus(get_cpu_type, ODD_COUNTERS);
6157 for_all_cpus(get_cpu_type, EVEN_COUNTERS);
6158
96e47158 6159 if (!quiet)
889facbe 6160 for_all_cpus(print_thermal, ODD_COUNTERS);
5a63426e 6161
96e47158 6162 if (!quiet && do_irtl_snb)
5a63426e 6163 print_irtl();
164d7a96
LB
6164
6165 if (DO_BIC(BIC_IPC))
6166 (void)get_instr_count_fd(base_cpu);
103a8fea
LB
6167}
6168
6169int fork_it(char **argv)
6170{
103a8fea 6171 pid_t child_pid;
d91bb17c 6172 int status;
d15cf7c1 6173
218f0e8d 6174 snapshot_proc_sysfs_files();
d91bb17c 6175 status = for_all_cpus(get_counters, EVEN_COUNTERS);
4c2122d4 6176 first_counter_read = 0;
d91bb17c
LB
6177 if (status)
6178 exit(status);
c98d5d94
LB
6179 /* clear affinity side-effect of get_counters() */
6180 sched_setaffinity(0, cpu_present_setsize, cpu_present_set);
103a8fea
LB
6181 gettimeofday(&tv_even, (struct timezone *)NULL);
6182
6183 child_pid = fork();
6184 if (!child_pid) {
6185 /* child */
6186 execvp(argv[0], argv);
0815a3d0 6187 err(errno, "exec %s", argv[0]);
103a8fea 6188 } else {
103a8fea
LB
6189
6190 /* parent */
b2c95d90
JT
6191 if (child_pid == -1)
6192 err(1, "fork");
103a8fea
LB
6193
6194 signal(SIGINT, SIG_IGN);
6195 signal(SIGQUIT, SIG_IGN);
b2c95d90
JT
6196 if (waitpid(child_pid, &status, 0) == -1)
6197 err(status, "waitpid");
2a954966
DA
6198
6199 if (WIFEXITED(status))
6200 status = WEXITSTATUS(status);
103a8fea 6201 }
c98d5d94
LB
6202 /*
6203 * n.b. fork_it() does not check for errors from for_all_cpus()
6204 * because re-starting is problematic when forking
6205 */
218f0e8d 6206 snapshot_proc_sysfs_files();
c98d5d94 6207 for_all_cpus(get_counters, ODD_COUNTERS);
103a8fea 6208 gettimeofday(&tv_odd, (struct timezone *)NULL);
103a8fea 6209 timersub(&tv_odd, &tv_even, &tv_delta);
ba3dec99
LB
6210 if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS))
6211 fprintf(outf, "%s: Counter reset detected\n", progname);
6212 else {
6213 compute_average(EVEN_COUNTERS);
6214 format_all_counters(EVEN_COUNTERS);
6215 }
103a8fea 6216
1b439f01 6217 fprintf(outf, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec / 1000000.0);
b7d8c148
LB
6218
6219 flush_output_stderr();
103a8fea 6220
d91bb17c 6221 return status;
103a8fea
LB
6222}
6223
3b4d5c7f
AS
6224int get_and_dump_counters(void)
6225{
6226 int status;
6227
218f0e8d 6228 snapshot_proc_sysfs_files();
3b4d5c7f
AS
6229 status = for_all_cpus(get_counters, ODD_COUNTERS);
6230 if (status)
6231 return status;
6232
6233 status = for_all_cpus(dump_counters, ODD_COUNTERS);
6234 if (status)
6235 return status;
6236
b7d8c148 6237 flush_output_stdout();
3b4d5c7f
AS
6238
6239 return status;
6240}
6241
1b439f01
LB
6242void print_version()
6243{
de7839ee 6244 fprintf(outf, "turbostat version 2023.03.17 - Len Brown <lenb@kernel.org>\n");
d8af6f5f
LB
6245}
6246
03331233
CY
6247#define COMMAND_LINE_SIZE 2048
6248
6249void print_bootcmd(void)
6250{
6251 char bootcmd[COMMAND_LINE_SIZE];
6252 FILE *fp;
6253 int ret;
6254
6255 memset(bootcmd, 0, COMMAND_LINE_SIZE);
6256 fp = fopen("/proc/cmdline", "r");
6257 if (!fp)
6258 return;
6259
6260 ret = fread(bootcmd, sizeof(char), COMMAND_LINE_SIZE - 1, fp);
6261 if (ret) {
6262 bootcmd[ret] = '\0';
6263 /* the last character is already '\n' */
6264 fprintf(outf, "Kernel command line: %s", bootcmd);
6265 }
6266
6267 fclose(fp);
6268}
6269
495c7654 6270int add_counter(unsigned int msr_num, char *path, char *name,
1b439f01
LB
6271 unsigned int width, enum counter_scope scope,
6272 enum counter_type type, enum counter_format format, int flags)
388e9c81
LB
6273{
6274 struct msr_counter *msrp;
6275
6276 msrp = calloc(1, sizeof(struct msr_counter));
6277 if (msrp == NULL) {
6278 perror("calloc");
6279 exit(1);
6280 }
6281
6282 msrp->msr_num = msr_num;
d8d005ba 6283 strncpy(msrp->name, name, NAME_BYTES - 1);
495c7654 6284 if (path)
d8d005ba 6285 strncpy(msrp->path, path, PATH_BYTES - 1);
388e9c81
LB
6286 msrp->width = width;
6287 msrp->type = type;
6288 msrp->format = format;
41618e63 6289 msrp->flags = flags;
388e9c81
LB
6290
6291 switch (scope) {
6292
6293 case SCOPE_CPU:
388e9c81
LB
6294 msrp->next = sys.tp;
6295 sys.tp = msrp;
678a3bd1 6296 sys.added_thread_counters++;
0748eaf0 6297 if (sys.added_thread_counters > MAX_ADDED_THREAD_COUNTERS) {
1b439f01 6298 fprintf(stderr, "exceeded max %d added thread counters\n", MAX_ADDED_COUNTERS);
678a3bd1
LB
6299 exit(-1);
6300 }
388e9c81
LB
6301 break;
6302
6303 case SCOPE_CORE:
388e9c81
LB
6304 msrp->next = sys.cp;
6305 sys.cp = msrp;
678a3bd1
LB
6306 sys.added_core_counters++;
6307 if (sys.added_core_counters > MAX_ADDED_COUNTERS) {
1b439f01 6308 fprintf(stderr, "exceeded max %d added core counters\n", MAX_ADDED_COUNTERS);
678a3bd1
LB
6309 exit(-1);
6310 }
388e9c81
LB
6311 break;
6312
6313 case SCOPE_PACKAGE:
388e9c81
LB
6314 msrp->next = sys.pp;
6315 sys.pp = msrp;
678a3bd1
LB
6316 sys.added_package_counters++;
6317 if (sys.added_package_counters > MAX_ADDED_COUNTERS) {
1b439f01 6318 fprintf(stderr, "exceeded max %d added package counters\n", MAX_ADDED_COUNTERS);
678a3bd1
LB
6319 exit(-1);
6320 }
388e9c81
LB
6321 break;
6322 }
6323
6324 return 0;
6325}
6326
6327void parse_add_command(char *add_command)
6328{
6329 int msr_num = 0;
495c7654 6330 char *path = NULL;
0f47c08d 6331 char name_buffer[NAME_BYTES] = "";
388e9c81
LB
6332 int width = 64;
6333 int fail = 0;
6334 enum counter_scope scope = SCOPE_CPU;
6335 enum counter_type type = COUNTER_CYCLES;
6336 enum counter_format format = FORMAT_DELTA;
6337
6338 while (add_command) {
6339
6340 if (sscanf(add_command, "msr0x%x", &msr_num) == 1)
6341 goto next;
6342
6343 if (sscanf(add_command, "msr%d", &msr_num) == 1)
6344 goto next;
6345
495c7654
LB
6346 if (*add_command == '/') {
6347 path = add_command;
6348 goto next;
6349 }
6350
388e9c81
LB
6351 if (sscanf(add_command, "u%d", &width) == 1) {
6352 if ((width == 32) || (width == 64))
6353 goto next;
6354 width = 64;
6355 }
6356 if (!strncmp(add_command, "cpu", strlen("cpu"))) {
6357 scope = SCOPE_CPU;
6358 goto next;
6359 }
6360 if (!strncmp(add_command, "core", strlen("core"))) {
6361 scope = SCOPE_CORE;
6362 goto next;
6363 }
6364 if (!strncmp(add_command, "package", strlen("package"))) {
6365 scope = SCOPE_PACKAGE;
6366 goto next;
6367 }
6368 if (!strncmp(add_command, "cycles", strlen("cycles"))) {
6369 type = COUNTER_CYCLES;
6370 goto next;
6371 }
6372 if (!strncmp(add_command, "seconds", strlen("seconds"))) {
6373 type = COUNTER_SECONDS;
6374 goto next;
6375 }
41618e63
LB
6376 if (!strncmp(add_command, "usec", strlen("usec"))) {
6377 type = COUNTER_USEC;
6378 goto next;
6379 }
388e9c81
LB
6380 if (!strncmp(add_command, "raw", strlen("raw"))) {
6381 format = FORMAT_RAW;
6382 goto next;
6383 }
6384 if (!strncmp(add_command, "delta", strlen("delta"))) {
6385 format = FORMAT_DELTA;
6386 goto next;
6387 }
6388 if (!strncmp(add_command, "percent", strlen("percent"))) {
6389 format = FORMAT_PERCENT;
6390 goto next;
6391 }
6392
6393 if (sscanf(add_command, "%18s,%*s", name_buffer) == 1) { /* 18 < NAME_BYTES */
6394 char *eos;
6395
6396 eos = strchr(name_buffer, ',');
6397 if (eos)
6398 *eos = '\0';
6399 goto next;
6400 }
6401
6402next:
6403 add_command = strchr(add_command, ',');
495c7654
LB
6404 if (add_command) {
6405 *add_command = '\0';
388e9c81 6406 add_command++;
495c7654 6407 }
388e9c81
LB
6408
6409 }
495c7654
LB
6410 if ((msr_num == 0) && (path == NULL)) {
6411 fprintf(stderr, "--add: (msrDDD | msr0xXXX | /path_to_counter ) required\n");
388e9c81
LB
6412 fail++;
6413 }
6414
6415 /* generate default column header */
6416 if (*name_buffer == '\0') {
5f3aea57
LB
6417 if (width == 32)
6418 sprintf(name_buffer, "M0x%x%s", msr_num, format == FORMAT_PERCENT ? "%" : "");
6419 else
6420 sprintf(name_buffer, "M0X%x%s", msr_num, format == FORMAT_PERCENT ? "%" : "");
388e9c81
LB
6421 }
6422
41618e63 6423 if (add_counter(msr_num, path, name_buffer, width, scope, type, format, 0))
388e9c81
LB
6424 fail++;
6425
6426 if (fail) {
6427 help();
6428 exit(1);
6429 }
6430}
41618e63 6431
0fc521bc
ZLCH
6432int is_deferred_add(char *name)
6433{
6434 int i;
6435
6436 for (i = 0; i < deferred_add_index; ++i)
6437 if (!strcmp(name, deferred_add_names[i]))
6438 return 1;
6439 return 0;
6440}
6441
dd778a5e
LB
6442int is_deferred_skip(char *name)
6443{
6444 int i;
6445
6446 for (i = 0; i < deferred_skip_index; ++i)
6447 if (!strcmp(name, deferred_skip_names[i]))
6448 return 1;
6449 return 0;
6450}
6451
41618e63
LB
6452void probe_sysfs(void)
6453{
6454 char path[64];
6455 char name_buf[16];
6456 FILE *input;
6457 int state;
6458 char *sp;
6459
0748eaf0 6460 for (state = 10; state >= 0; --state) {
41618e63 6461
1b439f01 6462 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", base_cpu, state);
41618e63
LB
6463 input = fopen(path, "r");
6464 if (input == NULL)
6465 continue;
8173c336
BH
6466 if (!fgets(name_buf, sizeof(name_buf), input))
6467 err(1, "%s: failed to read file", path);
41618e63 6468
1b439f01 6469 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
41618e63
LB
6470 sp = strchr(name_buf, '-');
6471 if (!sp)
6472 sp = strchrnul(name_buf, '\n');
6473 *sp = '%';
6474 *(sp + 1) = '\0';
6475
fecb3bc8
DA
6476 remove_underbar(name_buf);
6477
41618e63
LB
6478 fclose(input);
6479
6480 sprintf(path, "cpuidle/state%d/time", state);
6481
0fc521bc
ZLCH
6482 if (!DO_BIC(BIC_sysfs) && !is_deferred_add(name_buf))
6483 continue;
6484
dd778a5e
LB
6485 if (is_deferred_skip(name_buf))
6486 continue;
6487
1b439f01 6488 add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_USEC, FORMAT_PERCENT, SYSFS_PERCPU);
41618e63
LB
6489 }
6490
0748eaf0 6491 for (state = 10; state >= 0; --state) {
41618e63 6492
1b439f01 6493 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", base_cpu, state);
41618e63
LB
6494 input = fopen(path, "r");
6495 if (input == NULL)
6496 continue;
8173c336
BH
6497 if (!fgets(name_buf, sizeof(name_buf), input))
6498 err(1, "%s: failed to read file", path);
1b439f01 6499 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
41618e63
LB
6500 sp = strchr(name_buf, '-');
6501 if (!sp)
6502 sp = strchrnul(name_buf, '\n');
6503 *sp = '\0';
6504 fclose(input);
fecb3bc8
DA
6505
6506 remove_underbar(name_buf);
41618e63
LB
6507
6508 sprintf(path, "cpuidle/state%d/usage", state);
6509
0fc521bc
ZLCH
6510 if (!DO_BIC(BIC_sysfs) && !is_deferred_add(name_buf))
6511 continue;
6512
dd778a5e
LB
6513 if (is_deferred_skip(name_buf))
6514 continue;
6515
1b439f01 6516 add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS, FORMAT_DELTA, SYSFS_PERCPU);
41618e63
LB
6517 }
6518
6519}
6520
1ef7d21a
LB
6521/*
6522 * parse cpuset with following syntax
6523 * 1,2,4..6,8-10 and set bits in cpu_subset
6524 */
6525void parse_cpu_command(char *optarg)
6526{
6527 unsigned int start, end;
6528 char *next;
6529
4e4e1e7c
LB
6530 if (!strcmp(optarg, "core")) {
6531 if (cpu_subset)
6532 goto error;
6533 show_core_only++;
6534 return;
6535 }
6536 if (!strcmp(optarg, "package")) {
6537 if (cpu_subset)
6538 goto error;
6539 show_pkg_only++;
6540 return;
6541 }
6542 if (show_core_only || show_pkg_only)
6543 goto error;
6544
1ef7d21a
LB
6545 cpu_subset = CPU_ALLOC(CPU_SUBSET_MAXCPUS);
6546 if (cpu_subset == NULL)
6547 err(3, "CPU_ALLOC");
6548 cpu_subset_size = CPU_ALLOC_SIZE(CPU_SUBSET_MAXCPUS);
6549
6550 CPU_ZERO_S(cpu_subset_size, cpu_subset);
6551
6552 next = optarg;
6553
6554 while (next && *next) {
6555
6556 if (*next == '-') /* no negative cpu numbers */
6557 goto error;
6558
6559 start = strtoul(next, &next, 10);
6560
6561 if (start >= CPU_SUBSET_MAXCPUS)
6562 goto error;
6563 CPU_SET_S(start, cpu_subset_size, cpu_subset);
6564
6565 if (*next == '\0')
6566 break;
6567
6568 if (*next == ',') {
6569 next += 1;
6570 continue;
6571 }
6572
6573 if (*next == '-') {
6574 next += 1; /* start range */
6575 } else if (*next == '.') {
6576 next += 1;
6577 if (*next == '.')
6578 next += 1; /* start range */
6579 else
6580 goto error;
6581 }
6582
6583 end = strtoul(next, &next, 10);
6584 if (end <= start)
6585 goto error;
6586
6587 while (++start <= end) {
6588 if (start >= CPU_SUBSET_MAXCPUS)
6589 goto error;
6590 CPU_SET_S(start, cpu_subset_size, cpu_subset);
6591 }
6592
6593 if (*next == ',')
6594 next += 1;
6595 else if (*next != '\0')
6596 goto error;
6597 }
6598
6599 return;
6600
6601error:
4e4e1e7c
LB
6602 fprintf(stderr, "\"--cpu %s\" malformed\n", optarg);
6603 help();
1ef7d21a
LB
6604 exit(-1);
6605}
6606
103a8fea
LB
6607void cmdline(int argc, char **argv)
6608{
6609 int opt;
d8af6f5f
LB
6610 int option_index = 0;
6611 static struct option long_options[] = {
1b439f01
LB
6612 { "add", required_argument, 0, 'a' },
6613 { "cpu", required_argument, 0, 'c' },
6614 { "Dump", no_argument, 0, 'D' },
6615 { "debug", no_argument, 0, 'd' }, /* internal, not documented */
6616 { "enable", required_argument, 0, 'e' },
6617 { "interval", required_argument, 0, 'i' },
6618 { "IPC", no_argument, 0, 'I' },
6619 { "num_iterations", required_argument, 0, 'n' },
c7e399f8 6620 { "header_iterations", required_argument, 0, 'N' },
1b439f01
LB
6621 { "help", no_argument, 0, 'h' },
6622 { "hide", required_argument, 0, 'H' }, // meh, -h taken by --help
6623 { "Joules", no_argument, 0, 'J' },
6624 { "list", no_argument, 0, 'l' },
6625 { "out", required_argument, 0, 'o' },
6626 { "quiet", no_argument, 0, 'q' },
6627 { "show", required_argument, 0, 's' },
6628 { "Summary", no_argument, 0, 'S' },
6629 { "TCC", required_argument, 0, 'T' },
6630 { "version", no_argument, 0, 'v' },
6631 { 0, 0, 0, 0 }
d8af6f5f 6632 };
103a8fea
LB
6633
6634 progname = argv[0];
6635
1b439f01 6636 while ((opt = getopt_long_only(argc, argv, "+C:c:Dde:hi:Jn:o:qST:v", long_options, &option_index)) != -1) {
103a8fea 6637 switch (opt) {
388e9c81
LB
6638 case 'a':
6639 parse_add_command(optarg);
6640 break;
1ef7d21a
LB
6641 case 'c':
6642 parse_cpu_command(optarg);
6643 break;
d8af6f5f 6644 case 'D':
3b4d5c7f
AS
6645 dump_only++;
6646 break;
3f44a5c6
LB
6647 case 'e':
6648 /* --enable specified counter */
4c2122d4 6649 bic_enabled = bic_enabled | bic_lookup(optarg, SHOW_LIST);
3f44a5c6 6650 break;
d8af6f5f
LB
6651 case 'd':
6652 debug++;
3f44a5c6 6653 ENABLE_BIC(BIC_DISABLED_BY_DEFAULT);
103a8fea 6654 break;
812db3f7 6655 case 'H':
3f44a5c6
LB
6656 /*
6657 * --hide: do not show those specified
6658 * multiple invocations simply clear more bits in enabled mask
6659 */
6660 bic_enabled &= ~bic_lookup(optarg, HIDE_LIST);
812db3f7 6661 break;
d8af6f5f
LB
6662 case 'h':
6663 default:
6664 help();
6665 exit(1);
103a8fea 6666 case 'i':
2a0609c0
LB
6667 {
6668 double interval = strtod(optarg, NULL);
6669
6670 if (interval < 0.001) {
1b439f01 6671 fprintf(outf, "interval %f seconds is too small\n", interval);
2a0609c0
LB
6672 exit(2);
6673 }
6674
47936f94 6675 interval_tv.tv_sec = interval_ts.tv_sec = interval;
b9ad8ee0 6676 interval_tv.tv_usec = (interval - interval_tv.tv_sec) * 1000000;
47936f94 6677 interval_ts.tv_nsec = (interval - interval_ts.tv_sec) * 1000000000;
2a0609c0 6678 }
103a8fea 6679 break;
d8af6f5f
LB
6680 case 'J':
6681 rapl_joules++;
8e180f3c 6682 break;
c8ade361 6683 case 'l':
3f44a5c6 6684 ENABLE_BIC(BIC_DISABLED_BY_DEFAULT);
c8ade361
LB
6685 list_header_only++;
6686 quiet++;
6687 break;
b7d8c148
LB
6688 case 'o':
6689 outf = fopen_or_die(optarg, "w");
6690 break;
96e47158
LB
6691 case 'q':
6692 quiet = 1;
6693 break;
023fe0ac
CY
6694 case 'n':
6695 num_iterations = strtod(optarg, NULL);
6696
6697 if (num_iterations <= 0) {
1b439f01 6698 fprintf(outf, "iterations %d should be positive number\n", num_iterations);
023fe0ac
CY
6699 exit(2);
6700 }
6701 break;
c7e399f8
ZLCH
6702 case 'N':
6703 header_iterations = strtod(optarg, NULL);
6704
6705 if (header_iterations <= 0) {
164d7a96 6706 fprintf(outf, "iterations %d should be positive number\n", header_iterations);
c7e399f8 6707 exit(2);
023fe0ac
CY
6708 }
6709 break;
812db3f7 6710 case 's':
3f44a5c6
LB
6711 /*
6712 * --show: show only those specified
6713 * The 1st invocation will clear and replace the enabled mask
6714 * subsequent invocations can add to it.
6715 */
6716 if (shown == 0)
6717 bic_enabled = bic_lookup(optarg, SHOW_LIST);
6718 else
6719 bic_enabled |= bic_lookup(optarg, SHOW_LIST);
6720 shown = 1;
812db3f7 6721 break;
d8af6f5f
LB
6722 case 'S':
6723 summary_only++;
889facbe
LB
6724 break;
6725 case 'T':
55279aef 6726 tj_max_override = atoi(optarg);
889facbe 6727 break;
d8af6f5f
LB
6728 case 'v':
6729 print_version();
6730 exit(0);
5c56be9a 6731 break;
103a8fea
LB
6732 }
6733 }
6734}
6735
6736int main(int argc, char **argv)
6737{
b7d8c148 6738 outf = stderr;
103a8fea
LB
6739 cmdline(argc, argv);
6740
03331233 6741 if (!quiet) {
d8af6f5f 6742 print_version();
03331233
CY
6743 print_bootcmd();
6744 }
103a8fea 6745
41618e63
LB
6746 probe_sysfs();
6747
103a8fea
LB
6748 turbostat_init();
6749
6799ba84
DM
6750 msr_sum_record();
6751
3b4d5c7f
AS
6752 /* dump counters and exit */
6753 if (dump_only)
6754 return get_and_dump_counters();
6755
c8ade361
LB
6756 /* list header and exit */
6757 if (list_header_only) {
6758 print_header(",");
6759 flush_output_stdout();
6760 return 0;
6761 }
6762
103a8fea
LB
6763 /*
6764 * if any params left, it must be a command to fork
6765 */
6766 if (argc - optind)
6767 return fork_it(argv + optind);
6768 else
6769 turbostat_loop();
6770
6771 return 0;
6772}