Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * turbostat -- show CPU frequency and C-state residency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * on modern Intel and AMD processors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Copyright (c) 2013 Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * Len Brown <len.brown@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #define _GNU_SOURCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include MSRHEADER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include INTEL_FAMILY_HEADER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <stdarg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <sys/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <sys/select.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <sys/resource.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <sys/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <getopt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <dirent.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <cpuid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <sys/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <math.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) char *proc_stat = "/proc/stat";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) FILE *outf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) int *fd_percpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) struct timeval interval_tv = {5, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) struct timespec interval_ts = {5, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) unsigned int num_iterations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) unsigned int debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) unsigned int quiet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) unsigned int shown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) unsigned int sums_need_wide_columns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) unsigned int rapl_joules;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) unsigned int summary_only;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) unsigned int list_header_only;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) unsigned int dump_only;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) unsigned int do_snb_cstates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) unsigned int do_knl_cstates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) unsigned int do_slm_cstates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) unsigned int use_c1_residency_msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) unsigned int has_aperf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) unsigned int has_epb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) unsigned int do_irtl_snb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) unsigned int do_irtl_hsw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) unsigned int units = 1000000;	/* MHz etc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) unsigned int genuine_intel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) unsigned int authentic_amd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) unsigned int hygon_genuine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) unsigned int max_level, max_extended_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) unsigned int has_invariant_tsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) unsigned int do_nhm_platform_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) unsigned int no_MSR_MISC_PWR_MGMT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) unsigned int aperf_mperf_multiplier = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) double bclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) double base_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) unsigned int has_base_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) double tsc_tweak = 1.0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) unsigned int show_pkg_only;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) unsigned int show_core_only;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) char *output_buffer, *outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) unsigned int do_rapl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) unsigned int do_dts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) unsigned int do_ptm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) unsigned long long  gfx_cur_rc6_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) unsigned long long cpuidle_cur_cpu_lpi_us;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) unsigned long long cpuidle_cur_sys_lpi_us;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) unsigned int gfx_cur_mhz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) unsigned int gfx_act_mhz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) unsigned int tcc_activation_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) unsigned int tcc_activation_temp_override;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) double rapl_power_units, rapl_time_units;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) double rapl_dram_energy_units, rapl_energy_units;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) double rapl_joule_counter_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) unsigned int do_core_perf_limit_reasons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) unsigned int has_automatic_cstate_conversion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) unsigned int do_gfx_perf_limit_reasons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) unsigned int do_ring_perf_limit_reasons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) unsigned int crystal_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) unsigned long long tsc_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) int base_cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) double discover_bclk(unsigned int family, unsigned int model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) unsigned int has_hwp;	/* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 			/* IA32_HWP_REQUEST, IA32_HWP_STATUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) unsigned int has_hwp_notify;		/* IA32_HWP_INTERRUPT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) unsigned int has_hwp_activity_window;	/* IA32_HWP_REQUEST[bits 41:32] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) unsigned int has_hwp_epp;		/* IA32_HWP_REQUEST[bits 31:24] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) unsigned int has_hwp_pkg;		/* IA32_HWP_REQUEST_PKG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) unsigned int has_misc_feature_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) unsigned int first_counter_read = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) int ignore_stdin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) #define RAPL_PKG		(1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 					/* 0x610 MSR_PKG_POWER_LIMIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 					/* 0x611 MSR_PKG_ENERGY_STATUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) #define RAPL_PKG_PERF_STATUS	(1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 					/* 0x613 MSR_PKG_PERF_STATUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) #define RAPL_PKG_POWER_INFO	(1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 					/* 0x614 MSR_PKG_POWER_INFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) #define RAPL_DRAM		(1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 					/* 0x618 MSR_DRAM_POWER_LIMIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 					/* 0x619 MSR_DRAM_ENERGY_STATUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) #define RAPL_DRAM_PERF_STATUS	(1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 					/* 0x61b MSR_DRAM_PERF_STATUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) #define RAPL_DRAM_POWER_INFO	(1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 					/* 0x61c MSR_DRAM_POWER_INFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) #define RAPL_CORES_POWER_LIMIT	(1 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 					/* 0x638 MSR_PP0_POWER_LIMIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) #define RAPL_CORE_POLICY	(1 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 					/* 0x63a MSR_PP0_POLICY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) #define RAPL_GFX		(1 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 					/* 0x640 MSR_PP1_POWER_LIMIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 					/* 0x641 MSR_PP1_ENERGY_STATUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 					/* 0x642 MSR_PP1_POLICY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) #define RAPL_CORES_ENERGY_STATUS	(1 << 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 					/* 0x639 MSR_PP0_ENERGY_STATUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) #define RAPL_PER_CORE_ENERGY	(1 << 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 					/* Indicates cores energy collection is per-core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 					 * not per-package. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) #define RAPL_AMD_F17H		(1 << 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 					/* 0xc0010299 MSR_RAPL_PWR_UNIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 					/* 0xc001029a MSR_CORE_ENERGY_STAT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 					/* 0xc001029b MSR_PKG_ENERGY_STAT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) #define RAPL_CORES (RAPL_CORES_ENERGY_STATUS | RAPL_CORES_POWER_LIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) #define	TJMAX_DEFAULT	100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) /* MSRs that are not yet in the kernel-provided header. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) #define MSR_RAPL_PWR_UNIT	0xc0010299
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) #define MSR_CORE_ENERGY_STAT	0xc001029a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) #define MSR_PKG_ENERGY_STAT	0xc001029b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) #define MAX(a, b) ((a) > (b) ? (a) : (b))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152)  * buffer size used by sscanf() for added column names
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153)  * Usually truncated to 7 characters, but also handles 18 columns for raw 64-bit counters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) #define	NAME_BYTES 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) #define PATH_BYTES 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) int backwards_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) char *progname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) #define CPU_SUBSET_MAXCPUS	1024	/* need to use before probe... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) cpu_set_t *cpu_present_set, *cpu_affinity_set, *cpu_subset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) size_t cpu_present_setsize, cpu_affinity_setsize, cpu_subset_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) #define MAX_ADDED_COUNTERS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) #define MAX_ADDED_THREAD_COUNTERS 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) #define BITMASK_SIZE 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) struct thread_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	struct timeval tv_begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	struct timeval tv_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	struct timeval tv_delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	unsigned long long tsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	unsigned long long aperf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	unsigned long long mperf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	unsigned long long c1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	unsigned long long  irq_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	unsigned int smi_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	unsigned int cpu_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	unsigned int apic_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	unsigned int x2apic_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	unsigned int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) #define CPU_IS_FIRST_THREAD_IN_CORE	0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) #define CPU_IS_FIRST_CORE_IN_PACKAGE	0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	unsigned long long counter[MAX_ADDED_THREAD_COUNTERS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) } *thread_even, *thread_odd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) struct core_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	unsigned long long c3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	unsigned long long c6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	unsigned long long c7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	unsigned long long mc6_us;	/* duplicate as per-core for now, even though per module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	unsigned int core_temp_c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	unsigned int core_energy;	/* MSR_CORE_ENERGY_STAT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	unsigned int core_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	unsigned long long counter[MAX_ADDED_COUNTERS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) } *core_even, *core_odd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) struct pkg_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	unsigned long long pc2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	unsigned long long pc3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	unsigned long long pc6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	unsigned long long pc7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	unsigned long long pc8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	unsigned long long pc9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	unsigned long long pc10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	unsigned long long cpu_lpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	unsigned long long sys_lpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	unsigned long long pkg_wtd_core_c0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	unsigned long long pkg_any_core_c0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	unsigned long long pkg_any_gfxe_c0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	unsigned long long pkg_both_core_gfxe_c0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	long long gfx_rc6_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	unsigned int gfx_mhz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	unsigned int gfx_act_mhz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	unsigned int package_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	unsigned long long energy_pkg;	/* MSR_PKG_ENERGY_STATUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	unsigned long long energy_dram;	/* MSR_DRAM_ENERGY_STATUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	unsigned long long energy_cores;	/* MSR_PP0_ENERGY_STATUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	unsigned long long energy_gfx;	/* MSR_PP1_ENERGY_STATUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	unsigned long long rapl_pkg_perf_status;	/* MSR_PKG_PERF_STATUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	unsigned long long rapl_dram_perf_status;	/* MSR_DRAM_PERF_STATUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	unsigned int pkg_temp_c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	unsigned long long counter[MAX_ADDED_COUNTERS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) } *package_even, *package_odd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) #define ODD_COUNTERS thread_odd, core_odd, package_odd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) #define EVEN_COUNTERS thread_even, core_even, package_even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) #define GET_THREAD(thread_base, thread_no, core_no, node_no, pkg_no)	      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	((thread_base) +						      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	 ((pkg_no) *							      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	  topo.nodes_per_pkg * topo.cores_per_node * topo.threads_per_core) + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	 ((node_no) * topo.cores_per_node * topo.threads_per_core) +	      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	 ((core_no) * topo.threads_per_core) +				      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	 (thread_no))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) #define GET_CORE(core_base, core_no, node_no, pkg_no)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	((core_base) +							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	 ((pkg_no) *  topo.nodes_per_pkg * topo.cores_per_node) +	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	 ((node_no) * topo.cores_per_node) +				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	 (core_no))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) #define GET_PKG(pkg_base, pkg_no) (pkg_base + pkg_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) enum counter_scope {SCOPE_CPU, SCOPE_CORE, SCOPE_PACKAGE};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) enum counter_type {COUNTER_ITEMS, COUNTER_CYCLES, COUNTER_SECONDS, COUNTER_USEC};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) enum counter_format {FORMAT_RAW, FORMAT_DELTA, FORMAT_PERCENT};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) struct msr_counter {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	unsigned int msr_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	char name[NAME_BYTES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	char path[PATH_BYTES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	unsigned int width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	enum counter_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	enum counter_format format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	struct msr_counter *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	unsigned int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) #define	FLAGS_HIDE	(1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) #define	FLAGS_SHOW	(1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) #define	SYSFS_PERCPU	(1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265)  * The accumulated sum of MSR is defined as a monotonic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266)  * increasing MSR, it will be accumulated periodically,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267)  * despite its register's bit width.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	IDX_PKG_ENERGY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	IDX_DRAM_ENERGY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	IDX_PP0_ENERGY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	IDX_PP1_ENERGY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	IDX_PKG_PERF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	IDX_DRAM_PERF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	IDX_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) int get_msr_sum(int cpu, off_t offset, unsigned long long *msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) struct msr_sum_array {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	/* get_msr_sum() = sum + (get_msr() - last) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 		/*The accumulated MSR value is updated by the timer*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 		unsigned long long sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 		/*The MSR footprint recorded in last timer*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 		unsigned long long last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	} entries[IDX_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) /* The percpu MSR sum array.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) struct msr_sum_array *per_cpu_msr_sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) off_t idx_to_offset(int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	off_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	switch (idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	case IDX_PKG_ENERGY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 		if (do_rapl & RAPL_AMD_F17H)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 			offset = MSR_PKG_ENERGY_STAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 			offset = MSR_PKG_ENERGY_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	case IDX_DRAM_ENERGY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 		offset = MSR_DRAM_ENERGY_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	case IDX_PP0_ENERGY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		offset = MSR_PP0_ENERGY_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	case IDX_PP1_ENERGY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 		offset = MSR_PP1_ENERGY_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	case IDX_PKG_PERF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 		offset = MSR_PKG_PERF_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	case IDX_DRAM_PERF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		offset = MSR_DRAM_PERF_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 		offset = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	return offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) int offset_to_idx(off_t offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	switch (offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	case MSR_PKG_ENERGY_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	case MSR_PKG_ENERGY_STAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 		idx = IDX_PKG_ENERGY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	case MSR_DRAM_ENERGY_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 		idx = IDX_DRAM_ENERGY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	case MSR_PP0_ENERGY_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 		idx = IDX_PP0_ENERGY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	case MSR_PP1_ENERGY_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 		idx = IDX_PP1_ENERGY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	case MSR_PKG_PERF_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		idx = IDX_PKG_PERF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	case MSR_DRAM_PERF_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 		idx = IDX_DRAM_PERF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 		idx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	return idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) int idx_valid(int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	switch (idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	case IDX_PKG_ENERGY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 		return do_rapl & (RAPL_PKG | RAPL_AMD_F17H);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	case IDX_DRAM_ENERGY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 		return do_rapl & RAPL_DRAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	case IDX_PP0_ENERGY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 		return do_rapl & RAPL_CORES_ENERGY_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	case IDX_PP1_ENERGY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		return do_rapl & RAPL_GFX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	case IDX_PKG_PERF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		return do_rapl & RAPL_PKG_PERF_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	case IDX_DRAM_PERF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 		return do_rapl & RAPL_DRAM_PERF_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) struct sys_counters {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	unsigned int added_thread_counters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	unsigned int added_core_counters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	unsigned int added_package_counters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	struct msr_counter *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	struct msr_counter *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	struct msr_counter *pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) } sys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) struct system_summary {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	struct thread_data threads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	struct core_data cores;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	struct pkg_data packages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) } average;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) struct cpu_topology {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	int physical_package_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	int die_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	int logical_cpu_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	int physical_node_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	int logical_node_id;	/* 0-based count within the package */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	int physical_core_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	int thread_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	cpu_set_t *put_ids; /* Processing Unit/Thread IDs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) } *cpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) struct topo_params {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	int num_packages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	int num_die;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	int num_cpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	int num_cores;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	int max_cpu_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	int max_node_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	int nodes_per_pkg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	int cores_per_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	int threads_per_core;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) } topo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) struct timeval tv_even, tv_odd, tv_delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) int *irq_column_2_cpu;	/* /proc/interrupts column numbers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) int *irqs_per_cpu;		/* indexed by cpu_num */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) void setup_all_buffers(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) char *sys_lpi_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) char *sys_lpi_file_sysfs = "/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) char *sys_lpi_file_debugfs = "/sys/kernel/debug/pmc_core/slp_s0_residency_usec";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) int cpu_is_not_present(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429)  * run func(thread, core, package) in topology order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430)  * skip non-present cpus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) int for_all_cpus(int (func)(struct thread_data *, struct core_data *, struct pkg_data *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	int retval, pkg_no, core_no, thread_no, node_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		for (node_no = 0; node_no < topo.nodes_per_pkg; node_no++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 			for (core_no = 0; core_no < topo.cores_per_node; ++core_no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 				for (thread_no = 0; thread_no <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 					topo.threads_per_core; ++thread_no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 					struct thread_data *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 					struct core_data *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 					struct pkg_data *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 					t = GET_THREAD(thread_base, thread_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 						       core_no, node_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 						       pkg_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 					if (cpu_is_not_present(t->cpu_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 						continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 					c = GET_CORE(core_base, core_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 						     node_no, pkg_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 					p = GET_PKG(pkg_base, pkg_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 					retval = func(t, c, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 					if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 						return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) int cpu_migrate(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	CPU_SET_S(cpu, cpu_affinity_setsize, cpu_affinity_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	if (sched_setaffinity(0, cpu_affinity_setsize, cpu_affinity_set) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) int get_msr_fd(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	char pathname[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	fd = fd_percpu[cpu];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	if (fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	sprintf(pathname, "/dev/cpu/%d/msr", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	fd = open(pathname, O_RDONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	if (fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 		err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, or run as root", pathname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	fd_percpu[cpu] = fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) int get_msr(int cpu, off_t offset, unsigned long long *msr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	ssize_t retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	retval = pread(get_msr_fd(cpu), msr, sizeof(*msr), offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	if (retval != sizeof *msr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 		err(-1, "cpu%d: msr offset 0x%llx read failed", cpu, (unsigned long long)offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510)  * This list matches the column headers, except
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511)  * 1. built-in only, the sysfs counters are not here -- we learn of those at run-time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512)  * 2. Core and CPU are moved to the end, we can't have strings that contain them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513)  *    matching on them for --show and --hide.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) struct msr_counter bic[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	{ 0x0, "usec" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	{ 0x0, "Time_Of_Day_Seconds" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	{ 0x0, "Package" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	{ 0x0, "Node" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	{ 0x0, "Avg_MHz" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	{ 0x0, "Busy%" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	{ 0x0, "Bzy_MHz" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	{ 0x0, "TSC_MHz" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	{ 0x0, "IRQ" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	{ 0x0, "SMI", "", 32, 0, FORMAT_DELTA, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	{ 0x0, "sysfs" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	{ 0x0, "CPU%c1" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	{ 0x0, "CPU%c3" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	{ 0x0, "CPU%c6" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	{ 0x0, "CPU%c7" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	{ 0x0, "ThreadC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	{ 0x0, "CoreTmp" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	{ 0x0, "CoreCnt" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	{ 0x0, "PkgTmp" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	{ 0x0, "GFX%rc6" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	{ 0x0, "GFXMHz" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	{ 0x0, "Pkg%pc2" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	{ 0x0, "Pkg%pc3" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	{ 0x0, "Pkg%pc6" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	{ 0x0, "Pkg%pc7" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	{ 0x0, "Pkg%pc8" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	{ 0x0, "Pkg%pc9" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	{ 0x0, "Pk%pc10" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	{ 0x0, "CPU%LPI" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	{ 0x0, "SYS%LPI" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	{ 0x0, "PkgWatt" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	{ 0x0, "CorWatt" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	{ 0x0, "GFXWatt" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	{ 0x0, "PkgCnt" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	{ 0x0, "RAMWatt" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	{ 0x0, "PKG_%" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	{ 0x0, "RAM_%" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	{ 0x0, "Pkg_J" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	{ 0x0, "Cor_J" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	{ 0x0, "GFX_J" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	{ 0x0, "RAM_J" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	{ 0x0, "Mod%c6" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	{ 0x0, "Totl%C0" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	{ 0x0, "Any%C0" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	{ 0x0, "GFX%C0" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	{ 0x0, "CPUGFX%" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	{ 0x0, "Core" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	{ 0x0, "CPU" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	{ 0x0, "APIC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	{ 0x0, "X2APIC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	{ 0x0, "Die" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	{ 0x0, "GFXAMHz" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) #define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) #define	BIC_USEC	(1ULL << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) #define	BIC_TOD		(1ULL << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) #define	BIC_Package	(1ULL << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) #define	BIC_Node	(1ULL << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) #define	BIC_Avg_MHz	(1ULL << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) #define	BIC_Busy	(1ULL << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) #define	BIC_Bzy_MHz	(1ULL << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) #define	BIC_TSC_MHz	(1ULL << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) #define	BIC_IRQ		(1ULL << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) #define	BIC_SMI		(1ULL << 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) #define	BIC_sysfs	(1ULL << 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) #define	BIC_CPU_c1	(1ULL << 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) #define	BIC_CPU_c3	(1ULL << 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) #define	BIC_CPU_c6	(1ULL << 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) #define	BIC_CPU_c7	(1ULL << 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) #define	BIC_ThreadC	(1ULL << 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) #define	BIC_CoreTmp	(1ULL << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) #define	BIC_CoreCnt	(1ULL << 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) #define	BIC_PkgTmp	(1ULL << 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) #define	BIC_GFX_rc6	(1ULL << 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) #define	BIC_GFXMHz	(1ULL << 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) #define	BIC_Pkgpc2	(1ULL << 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) #define	BIC_Pkgpc3	(1ULL << 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) #define	BIC_Pkgpc6	(1ULL << 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) #define	BIC_Pkgpc7	(1ULL << 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) #define	BIC_Pkgpc8	(1ULL << 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) #define	BIC_Pkgpc9	(1ULL << 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) #define	BIC_Pkgpc10	(1ULL << 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) #define BIC_CPU_LPI	(1ULL << 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) #define BIC_SYS_LPI	(1ULL << 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) #define	BIC_PkgWatt	(1ULL << 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) #define	BIC_CorWatt	(1ULL << 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) #define	BIC_GFXWatt	(1ULL << 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) #define	BIC_PkgCnt	(1ULL << 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) #define	BIC_RAMWatt	(1ULL << 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) #define	BIC_PKG__	(1ULL << 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) #define	BIC_RAM__	(1ULL << 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) #define	BIC_Pkg_J	(1ULL << 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) #define	BIC_Cor_J	(1ULL << 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) #define	BIC_GFX_J	(1ULL << 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) #define	BIC_RAM_J	(1ULL << 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) #define	BIC_Mod_c6	(1ULL << 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) #define	BIC_Totl_c0	(1ULL << 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) #define	BIC_Any_c0	(1ULL << 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) #define	BIC_GFX_c0	(1ULL << 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) #define	BIC_CPUGFX	(1ULL << 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) #define	BIC_Core	(1ULL << 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) #define	BIC_CPU		(1ULL << 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) #define	BIC_APIC	(1ULL << 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) #define	BIC_X2APIC	(1ULL << 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) #define	BIC_Die		(1ULL << 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) #define	BIC_GFXACTMHz	(1ULL << 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) #define BIC_DISABLED_BY_DEFAULT	(BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) unsigned long long bic_enabled = (0xFFFFFFFFFFFFFFFFULL & ~BIC_DISABLED_BY_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs | BIC_APIC | BIC_X2APIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) #define DO_BIC(COUNTER_NAME) (bic_enabled & bic_present & COUNTER_NAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) #define DO_BIC_READ(COUNTER_NAME) (bic_present & COUNTER_NAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) #define ENABLE_BIC(COUNTER_NAME) (bic_enabled |= COUNTER_NAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) #define BIC_PRESENT(COUNTER_BIT) (bic_present |= COUNTER_BIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) #define BIC_NOT_PRESENT(COUNTER_BIT) (bic_present &= ~COUNTER_BIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) #define MAX_DEFERRED 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) char *deferred_skip_names[MAX_DEFERRED];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) int deferred_skip_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641)  * HIDE_LIST - hide this list of counters, show the rest [default]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642)  * SHOW_LIST - show this list of counters, hide the rest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) enum show_hide_mode { SHOW_LIST, HIDE_LIST } global_show_hide_mode = HIDE_LIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) void help(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	fprintf(outf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	"Usage: turbostat [OPTIONS][(--interval seconds) | COMMAND ...]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	"\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	"Turbostat forks the specified COMMAND and prints statistics\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	"when COMMAND completes.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	"If no COMMAND is specified, turbostat wakes every 5-seconds\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	"to print statistics, until interrupted.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	"  -a, --add	add a counter\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	"		  eg. --add msr0x10,u64,cpu,delta,MY_TSC\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	"  -c, --cpu	cpu-set	limit output to summary plus cpu-set:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	"		  {core | package | j,k,l..m,n-p }\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	"  -d, --debug	displays usec, Time_Of_Day_Seconds and more debugging\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	"  -D, --Dump	displays the raw counter values\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	"  -e, --enable	[all | column]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	"		shows all or the specified disabled column\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	"  -H, --hide [column|column,column,...]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	"		hide the specified column(s)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	"  -i, --interval sec.subsec\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	"		Override default 5-second measurement interval\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	"  -J, --Joules	displays energy in Joules instead of Watts\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	"  -l, --list	list column headers only\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	"  -n, --num_iterations num\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	"		number of the measurement iterations\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	"  -o, --out file\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	"		create or truncate \"file\" for all output\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	"  -q, --quiet	skip decoding system configuration header\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	"  -s, --show [column|column,column,...]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	"		show only the specified column(s)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	"  -S, --Summary\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	"		limits output to 1-line system summary per interval\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	"  -T, --TCC temperature\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	"		sets the Thermal Control Circuit temperature in\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	"		  degrees Celsius\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	"  -h, --help	print this help message\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	"  -v, --version	print version information\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	"\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	"For more help, run \"man turbostat\"\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688)  * bic_lookup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689)  * for all the strings in comma separate name_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690)  * set the approprate bit in return value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) unsigned long long bic_lookup(char *name_list, enum show_hide_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	unsigned long long retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	while (name_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		char *comma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 		comma = strchr(name_list, ',');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 		if (comma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 			*comma = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 		if (!strcmp(name_list, "all"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 			return ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 		for (i = 0; i < MAX_BIC; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 			if (!strcmp(name_list, bic[i].name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 				retval |= (1ULL << i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 		if (i == MAX_BIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 			if (mode == SHOW_LIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 				fprintf(stderr, "Invalid counter name: %s\n", name_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 				exit(-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 			deferred_skip_names[deferred_skip_index++] = name_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 			if (debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 				fprintf(stderr, "deferred \"%s\"\n", name_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 			if (deferred_skip_index >= MAX_DEFERRED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 				fprintf(stderr, "More than max %d un-recognized --skip options '%s'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 					MAX_DEFERRED, name_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 				help();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 				exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		name_list = comma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		if (name_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 			name_list++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) void print_header(char *delim)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	struct msr_counter *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	int printed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	if (DO_BIC(BIC_USEC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 		outp += sprintf(outp, "%susec", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	if (DO_BIC(BIC_TOD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 		outp += sprintf(outp, "%sTime_Of_Day_Seconds", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	if (DO_BIC(BIC_Package))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 		outp += sprintf(outp, "%sPackage", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	if (DO_BIC(BIC_Die))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		outp += sprintf(outp, "%sDie", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	if (DO_BIC(BIC_Node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		outp += sprintf(outp, "%sNode", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	if (DO_BIC(BIC_Core))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		outp += sprintf(outp, "%sCore", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	if (DO_BIC(BIC_CPU))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		outp += sprintf(outp, "%sCPU", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	if (DO_BIC(BIC_APIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		outp += sprintf(outp, "%sAPIC", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	if (DO_BIC(BIC_X2APIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		outp += sprintf(outp, "%sX2APIC", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	if (DO_BIC(BIC_Avg_MHz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		outp += sprintf(outp, "%sAvg_MHz", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	if (DO_BIC(BIC_Busy))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 		outp += sprintf(outp, "%sBusy%%", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	if (DO_BIC(BIC_Bzy_MHz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		outp += sprintf(outp, "%sBzy_MHz", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	if (DO_BIC(BIC_TSC_MHz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		outp += sprintf(outp, "%sTSC_MHz", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	if (DO_BIC(BIC_IRQ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		if (sums_need_wide_columns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 			outp += sprintf(outp, "%s     IRQ", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 			outp += sprintf(outp, "%sIRQ", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	if (DO_BIC(BIC_SMI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 		outp += sprintf(outp, "%sSMI", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	for (mp = sys.tp; mp; mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		if (mp->format == FORMAT_RAW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 			if (mp->width == 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 				outp += sprintf(outp, "%s%18.18s", (printed++ ? delim : ""), mp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 				outp += sprintf(outp, "%s%10.10s", (printed++ ? delim : ""), mp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 			if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 				outp += sprintf(outp, "%s%8s", (printed++ ? delim : ""), mp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 				outp += sprintf(outp, "%s%s", (printed++ ? delim : ""), mp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	if (DO_BIC(BIC_CPU_c1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		outp += sprintf(outp, "%sCPU%%c1", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	if (DO_BIC(BIC_CPU_c3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		outp += sprintf(outp, "%sCPU%%c3", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	if (DO_BIC(BIC_CPU_c6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 		outp += sprintf(outp, "%sCPU%%c6", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	if (DO_BIC(BIC_CPU_c7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		outp += sprintf(outp, "%sCPU%%c7", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	if (DO_BIC(BIC_Mod_c6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 		outp += sprintf(outp, "%sMod%%c6", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	if (DO_BIC(BIC_CoreTmp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 		outp += sprintf(outp, "%sCoreTmp", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	if (do_rapl && !rapl_joules) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		if (DO_BIC(BIC_CorWatt) && (do_rapl & RAPL_PER_CORE_ENERGY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 			outp += sprintf(outp, "%sCorWatt", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	} else if (do_rapl && rapl_joules) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 		if (DO_BIC(BIC_Cor_J) && (do_rapl & RAPL_PER_CORE_ENERGY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 			outp += sprintf(outp, "%sCor_J", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	for (mp = sys.cp; mp; mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		if (mp->format == FORMAT_RAW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 			if (mp->width == 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 				outp += sprintf(outp, "%s%18.18s", delim, mp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 				outp += sprintf(outp, "%s%10.10s", delim, mp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 			if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 				outp += sprintf(outp, "%s%8s", delim, mp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 				outp += sprintf(outp, "%s%s", delim, mp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	if (DO_BIC(BIC_PkgTmp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		outp += sprintf(outp, "%sPkgTmp", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	if (DO_BIC(BIC_GFX_rc6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 		outp += sprintf(outp, "%sGFX%%rc6", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	if (DO_BIC(BIC_GFXMHz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		outp += sprintf(outp, "%sGFXMHz", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	if (DO_BIC(BIC_GFXACTMHz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 		outp += sprintf(outp, "%sGFXAMHz", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	if (DO_BIC(BIC_Totl_c0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 		outp += sprintf(outp, "%sTotl%%C0", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	if (DO_BIC(BIC_Any_c0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		outp += sprintf(outp, "%sAny%%C0", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	if (DO_BIC(BIC_GFX_c0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 		outp += sprintf(outp, "%sGFX%%C0", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	if (DO_BIC(BIC_CPUGFX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		outp += sprintf(outp, "%sCPUGFX%%", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	if (DO_BIC(BIC_Pkgpc2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		outp += sprintf(outp, "%sPkg%%pc2", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	if (DO_BIC(BIC_Pkgpc3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 		outp += sprintf(outp, "%sPkg%%pc3", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	if (DO_BIC(BIC_Pkgpc6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		outp += sprintf(outp, "%sPkg%%pc6", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	if (DO_BIC(BIC_Pkgpc7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		outp += sprintf(outp, "%sPkg%%pc7", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	if (DO_BIC(BIC_Pkgpc8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		outp += sprintf(outp, "%sPkg%%pc8", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	if (DO_BIC(BIC_Pkgpc9))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 		outp += sprintf(outp, "%sPkg%%pc9", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	if (DO_BIC(BIC_Pkgpc10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 		outp += sprintf(outp, "%sPk%%pc10", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	if (DO_BIC(BIC_CPU_LPI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		outp += sprintf(outp, "%sCPU%%LPI", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	if (DO_BIC(BIC_SYS_LPI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		outp += sprintf(outp, "%sSYS%%LPI", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	if (do_rapl && !rapl_joules) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 		if (DO_BIC(BIC_PkgWatt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 			outp += sprintf(outp, "%sPkgWatt", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		if (DO_BIC(BIC_CorWatt) && !(do_rapl & RAPL_PER_CORE_ENERGY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 			outp += sprintf(outp, "%sCorWatt", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 		if (DO_BIC(BIC_GFXWatt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 			outp += sprintf(outp, "%sGFXWatt", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 		if (DO_BIC(BIC_RAMWatt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 			outp += sprintf(outp, "%sRAMWatt", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		if (DO_BIC(BIC_PKG__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 			outp += sprintf(outp, "%sPKG_%%", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		if (DO_BIC(BIC_RAM__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 			outp += sprintf(outp, "%sRAM_%%", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	} else if (do_rapl && rapl_joules) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		if (DO_BIC(BIC_Pkg_J))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 			outp += sprintf(outp, "%sPkg_J", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		if (DO_BIC(BIC_Cor_J) && !(do_rapl & RAPL_PER_CORE_ENERGY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 			outp += sprintf(outp, "%sCor_J", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 		if (DO_BIC(BIC_GFX_J))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 			outp += sprintf(outp, "%sGFX_J", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		if (DO_BIC(BIC_RAM_J))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 			outp += sprintf(outp, "%sRAM_J", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 		if (DO_BIC(BIC_PKG__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 			outp += sprintf(outp, "%sPKG_%%", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 		if (DO_BIC(BIC_RAM__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 			outp += sprintf(outp, "%sRAM_%%", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	for (mp = sys.pp; mp; mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 		if (mp->format == FORMAT_RAW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 			if (mp->width == 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 				outp += sprintf(outp, "%s%18.18s", delim, mp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 				outp += sprintf(outp, "%s%10.10s", delim, mp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 			if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 				outp += sprintf(outp, "%s%8s", delim, mp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 				outp += sprintf(outp, "%s%s", delim, mp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	outp += sprintf(outp, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) int dump_counters(struct thread_data *t, struct core_data *c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	struct pkg_data *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	struct msr_counter *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	outp += sprintf(outp, "t %p, c %p, p %p\n", t, c, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	if (t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		outp += sprintf(outp, "CPU: %d flags 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 			t->cpu_id, t->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		outp += sprintf(outp, "TSC: %016llX\n", t->tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		outp += sprintf(outp, "aperf: %016llX\n", t->aperf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		outp += sprintf(outp, "mperf: %016llX\n", t->mperf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 		outp += sprintf(outp, "c1: %016llX\n", t->c1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		if (DO_BIC(BIC_IRQ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 			outp += sprintf(outp, "IRQ: %lld\n", t->irq_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		if (DO_BIC(BIC_SMI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 			outp += sprintf(outp, "SMI: %d\n", t->smi_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 		for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 			outp += sprintf(outp, "tADDED [%d] msr0x%x: %08llX\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 				i, mp->msr_num, t->counter[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	if (c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		outp += sprintf(outp, "core: %d\n", c->core_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 		outp += sprintf(outp, "c3: %016llX\n", c->c3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 		outp += sprintf(outp, "c6: %016llX\n", c->c6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		outp += sprintf(outp, "c7: %016llX\n", c->c7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 		outp += sprintf(outp, "DTS: %dC\n", c->core_temp_c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		outp += sprintf(outp, "Joules: %0X\n", c->core_energy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 		for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 			outp += sprintf(outp, "cADDED [%d] msr0x%x: %08llX\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 				i, mp->msr_num, c->counter[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 		outp += sprintf(outp, "mc6_us: %016llX\n", c->mc6_us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		outp += sprintf(outp, "package: %d\n", p->package_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 		outp += sprintf(outp, "Weighted cores: %016llX\n", p->pkg_wtd_core_c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 		outp += sprintf(outp, "Any cores: %016llX\n", p->pkg_any_core_c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		outp += sprintf(outp, "Any GFX: %016llX\n", p->pkg_any_gfxe_c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		outp += sprintf(outp, "CPU + GFX: %016llX\n", p->pkg_both_core_gfxe_c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		outp += sprintf(outp, "pc2: %016llX\n", p->pc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		if (DO_BIC(BIC_Pkgpc3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 			outp += sprintf(outp, "pc3: %016llX\n", p->pc3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 		if (DO_BIC(BIC_Pkgpc6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 			outp += sprintf(outp, "pc6: %016llX\n", p->pc6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		if (DO_BIC(BIC_Pkgpc7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 			outp += sprintf(outp, "pc7: %016llX\n", p->pc7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		outp += sprintf(outp, "pc8: %016llX\n", p->pc8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		outp += sprintf(outp, "pc9: %016llX\n", p->pc9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 		outp += sprintf(outp, "pc10: %016llX\n", p->pc10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 		outp += sprintf(outp, "cpu_lpi: %016llX\n", p->cpu_lpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		outp += sprintf(outp, "sys_lpi: %016llX\n", p->sys_lpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 		outp += sprintf(outp, "Joules PKG: %0llX\n", p->energy_pkg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 		outp += sprintf(outp, "Joules COR: %0llX\n", p->energy_cores);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 		outp += sprintf(outp, "Joules GFX: %0llX\n", p->energy_gfx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 		outp += sprintf(outp, "Joules RAM: %0llX\n", p->energy_dram);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		outp += sprintf(outp, "Throttle PKG: %0llX\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 			p->rapl_pkg_perf_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		outp += sprintf(outp, "Throttle RAM: %0llX\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 			p->rapl_dram_perf_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		outp += sprintf(outp, "PTM: %dC\n", p->pkg_temp_c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 			outp += sprintf(outp, "pADDED [%d] msr0x%x: %08llX\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 				i, mp->msr_num, p->counter[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	outp += sprintf(outp, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)  * column formatting convention & formats
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) int format_counters(struct thread_data *t, struct core_data *c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	struct pkg_data *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	double interval_float, tsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	char *fmt8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	struct msr_counter *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	char *delim = "\t";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	int printed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	 /* if showing only 1st thread in core and this isn't one, bail out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	if (show_core_only && !(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	 /* if showing only 1st thread in pkg and this isn't one, bail out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	if (show_pkg_only && !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	/*if not summary line and --cpu is used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	if ((t != &average.threads) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		(cpu_subset && !CPU_ISSET_S(t->cpu_id, cpu_subset_size, cpu_subset)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	if (DO_BIC(BIC_USEC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		/* on each row, print how many usec each timestamp took to gather */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 		struct timeval tv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		timersub(&t->tv_end, &t->tv_begin, &tv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		outp += sprintf(outp, "%5ld\t", tv.tv_sec * 1000000 + tv.tv_usec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	/* Time_Of_Day_Seconds: on each row, print sec.usec last timestamp taken */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	if (DO_BIC(BIC_TOD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		outp += sprintf(outp, "%10ld.%06ld\t", t->tv_end.tv_sec, t->tv_end.tv_usec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	interval_float = t->tv_delta.tv_sec + t->tv_delta.tv_usec/1000000.0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	tsc = t->tsc * tsc_tweak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	/* topo columns, print blanks on 1st (average) line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	if (t == &average.threads) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 		if (DO_BIC(BIC_Package))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 			outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		if (DO_BIC(BIC_Die))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 			outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		if (DO_BIC(BIC_Node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 			outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 		if (DO_BIC(BIC_Core))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 			outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 		if (DO_BIC(BIC_CPU))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 			outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 		if (DO_BIC(BIC_APIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 			outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 		if (DO_BIC(BIC_X2APIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 			outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 		if (DO_BIC(BIC_Package)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 			if (p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 				outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->package_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 				outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		if (DO_BIC(BIC_Die)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 			if (c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 				outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), cpus[t->cpu_id].die_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 				outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		if (DO_BIC(BIC_Node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 			if (t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 				outp += sprintf(outp, "%s%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 						(printed++ ? delim : ""),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 					      cpus[t->cpu_id].physical_node_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 				outp += sprintf(outp, "%s-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 						(printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		if (DO_BIC(BIC_Core)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 			if (c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 				outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), c->core_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 				outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		if (DO_BIC(BIC_CPU))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 			outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->cpu_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 		if (DO_BIC(BIC_APIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 			outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->apic_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 		if (DO_BIC(BIC_X2APIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 			outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->x2apic_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	if (DO_BIC(BIC_Avg_MHz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 		outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 			1.0 / units * t->aperf / interval_float);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	if (DO_BIC(BIC_Busy))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * t->mperf/tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	if (DO_BIC(BIC_Bzy_MHz)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 		if (has_base_hz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 			outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), base_hz / units * t->aperf / t->mperf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 			outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 				tsc / units * t->aperf / t->mperf / interval_float);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	if (DO_BIC(BIC_TSC_MHz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 		outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), 1.0 * t->tsc/units/interval_float);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	/* IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	if (DO_BIC(BIC_IRQ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 		if (sums_need_wide_columns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 			outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), t->irq_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 			outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), t->irq_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	/* SMI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	if (DO_BIC(BIC_SMI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 		outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->smi_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	/* Added counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 		if (mp->format == FORMAT_RAW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 			if (mp->width == 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 				outp += sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int) t->counter[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 				outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), t->counter[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 		} else if (mp->format == FORMAT_DELTA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 			if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 				outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), t->counter[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 				outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), t->counter[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 		} else if (mp->format == FORMAT_PERCENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 			if (mp->type == COUNTER_USEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 				outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), t->counter[i]/interval_float/10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 				outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * t->counter[i]/tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	/* C1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	if (DO_BIC(BIC_CPU_c1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * t->c1/tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	/* print per-core data only for 1st thread in core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	if (DO_BIC(BIC_CPU_c3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c3/tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	if (DO_BIC(BIC_CPU_c6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c6/tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	if (DO_BIC(BIC_CPU_c7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c7/tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	/* Mod%c6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	if (DO_BIC(BIC_Mod_c6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->mc6_us / tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	if (DO_BIC(BIC_CoreTmp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 		outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), c->core_temp_c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 		if (mp->format == FORMAT_RAW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 			if (mp->width == 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 				outp += sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int) c->counter[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 				outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), c->counter[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 		} else if (mp->format == FORMAT_DELTA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 			if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 				outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), c->counter[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 				outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), c->counter[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 		} else if (mp->format == FORMAT_PERCENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 			outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->counter[i]/tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	fmt8 = "%s%.2f";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	if (DO_BIC(BIC_CorWatt) && (do_rapl & RAPL_PER_CORE_ENERGY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), c->core_energy * rapl_energy_units / interval_float);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	if (DO_BIC(BIC_Cor_J) && (do_rapl & RAPL_PER_CORE_ENERGY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), c->core_energy * rapl_energy_units);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	/* print per-package data only for 1st core in package */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	/* PkgTmp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	if (DO_BIC(BIC_PkgTmp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 		outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->pkg_temp_c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	/* GFXrc6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	if (DO_BIC(BIC_GFX_rc6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 		if (p->gfx_rc6_ms == -1) {	/* detect GFX counter reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 			outp += sprintf(outp, "%s**.**", (printed++ ? delim : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 			outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 				p->gfx_rc6_ms / 10.0 / interval_float);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	/* GFXMHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	if (DO_BIC(BIC_GFXMHz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 		outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->gfx_mhz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	/* GFXACTMHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	if (DO_BIC(BIC_GFXACTMHz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 		outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->gfx_act_mhz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	/* Totl%C0, Any%C0 GFX%C0 CPUGFX% */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	if (DO_BIC(BIC_Totl_c0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_wtd_core_c0/tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	if (DO_BIC(BIC_Any_c0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_any_core_c0/tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	if (DO_BIC(BIC_GFX_c0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_any_gfxe_c0/tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	if (DO_BIC(BIC_CPUGFX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_both_core_gfxe_c0/tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	if (DO_BIC(BIC_Pkgpc2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc2/tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	if (DO_BIC(BIC_Pkgpc3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc3/tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	if (DO_BIC(BIC_Pkgpc6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc6/tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	if (DO_BIC(BIC_Pkgpc7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc7/tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	if (DO_BIC(BIC_Pkgpc8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc8/tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	if (DO_BIC(BIC_Pkgpc9))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc9/tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	if (DO_BIC(BIC_Pkgpc10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc10/tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	if (DO_BIC(BIC_CPU_LPI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->cpu_lpi / 1000000.0 / interval_float);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	if (DO_BIC(BIC_SYS_LPI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->sys_lpi / 1000000.0 / interval_float);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	if (DO_BIC(BIC_PkgWatt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units / interval_float);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	if (DO_BIC(BIC_CorWatt) && !(do_rapl & RAPL_PER_CORE_ENERGY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units / interval_float);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	if (DO_BIC(BIC_GFXWatt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units / interval_float);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	if (DO_BIC(BIC_RAMWatt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_dram * rapl_dram_energy_units / interval_float);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	if (DO_BIC(BIC_Pkg_J))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	if (DO_BIC(BIC_Cor_J) && !(do_rapl & RAPL_PER_CORE_ENERGY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 	if (DO_BIC(BIC_GFX_J))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	if (DO_BIC(BIC_RAM_J))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_dram * rapl_dram_energy_units);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	if (DO_BIC(BIC_PKG__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 	if (DO_BIC(BIC_RAM__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 		if (mp->format == FORMAT_RAW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 			if (mp->width == 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 				outp += sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int) p->counter[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 				outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), p->counter[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 		} else if (mp->format == FORMAT_DELTA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 			if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 				outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), p->counter[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 				outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), p->counter[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 		} else if (mp->format == FORMAT_PERCENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 			outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->counter[i]/tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	if (*(outp - 1) != '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 		outp += sprintf(outp, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) void flush_output_stdout(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	FILE *filep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	if (outf == stderr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 		filep = stdout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 		filep = outf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	fputs(output_buffer, filep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	fflush(filep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 	outp = output_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) void flush_output_stderr(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 	fputs(output_buffer, outf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	fflush(outf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 	outp = output_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	static int printed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	if (!printed || !summary_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 		print_header("\t");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	format_counters(&average.threads, &average.cores, &average.packages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	printed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	if (summary_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	for_all_cpus(format_counters, t, c, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) #define DELTA_WRAP32(new, old)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	old = ((((unsigned long long)new << 32) - ((unsigned long long)old << 32)) >> 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) delta_package(struct pkg_data *new, struct pkg_data *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 	struct msr_counter *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	if (DO_BIC(BIC_Totl_c0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 		old->pkg_wtd_core_c0 = new->pkg_wtd_core_c0 - old->pkg_wtd_core_c0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	if (DO_BIC(BIC_Any_c0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 		old->pkg_any_core_c0 = new->pkg_any_core_c0 - old->pkg_any_core_c0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	if (DO_BIC(BIC_GFX_c0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 		old->pkg_any_gfxe_c0 = new->pkg_any_gfxe_c0 - old->pkg_any_gfxe_c0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 	if (DO_BIC(BIC_CPUGFX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 		old->pkg_both_core_gfxe_c0 = new->pkg_both_core_gfxe_c0 - old->pkg_both_core_gfxe_c0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	old->pc2 = new->pc2 - old->pc2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	if (DO_BIC(BIC_Pkgpc3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 		old->pc3 = new->pc3 - old->pc3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	if (DO_BIC(BIC_Pkgpc6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 		old->pc6 = new->pc6 - old->pc6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	if (DO_BIC(BIC_Pkgpc7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 		old->pc7 = new->pc7 - old->pc7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	old->pc8 = new->pc8 - old->pc8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	old->pc9 = new->pc9 - old->pc9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	old->pc10 = new->pc10 - old->pc10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	old->cpu_lpi = new->cpu_lpi - old->cpu_lpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	old->sys_lpi = new->sys_lpi - old->sys_lpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	old->pkg_temp_c = new->pkg_temp_c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	/* flag an error when rc6 counter resets/wraps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	if (old->gfx_rc6_ms >  new->gfx_rc6_ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 		old->gfx_rc6_ms = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 		old->gfx_rc6_ms = new->gfx_rc6_ms - old->gfx_rc6_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	old->gfx_mhz = new->gfx_mhz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	old->gfx_act_mhz = new->gfx_act_mhz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	old->energy_pkg = new->energy_pkg - old->energy_pkg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	old->energy_cores = new->energy_cores - old->energy_cores;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	old->energy_gfx = new->energy_gfx - old->energy_gfx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 	old->energy_dram = new->energy_dram - old->energy_dram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 	old->rapl_pkg_perf_status = new->rapl_pkg_perf_status - old->rapl_pkg_perf_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 	old->rapl_dram_perf_status = new->rapl_dram_perf_status - old->rapl_dram_perf_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 		if (mp->format == FORMAT_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 			old->counter[i] = new->counter[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 			old->counter[i] = new->counter[i] - old->counter[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) delta_core(struct core_data *new, struct core_data *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	struct msr_counter *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	old->c3 = new->c3 - old->c3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	old->c6 = new->c6 - old->c6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	old->c7 = new->c7 - old->c7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	old->core_temp_c = new->core_temp_c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	old->mc6_us = new->mc6_us - old->mc6_us;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 	DELTA_WRAP32(new->core_energy, old->core_energy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 		if (mp->format == FORMAT_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 			old->counter[i] = new->counter[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 			old->counter[i] = new->counter[i] - old->counter[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) int soft_c1_residency_display(int bic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	if (!DO_BIC(BIC_CPU_c1) || use_c1_residency_msr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	return DO_BIC_READ(bic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)  * old = new - old
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) delta_thread(struct thread_data *new, struct thread_data *old,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	struct core_data *core_delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	struct msr_counter *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	/* we run cpuid just the 1st time, copy the results */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	if (DO_BIC(BIC_APIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 		new->apic_id = old->apic_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	if (DO_BIC(BIC_X2APIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 		new->x2apic_id = old->x2apic_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	 * the timestamps from start of measurement interval are in "old"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 	 * the timestamp from end of measurement interval are in "new"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 	 * over-write old w/ new so we can print end of interval values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	timersub(&new->tv_begin, &old->tv_begin, &old->tv_delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	old->tv_begin = new->tv_begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	old->tv_end = new->tv_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 	old->tsc = new->tsc - old->tsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 	/* check for TSC < 1 Mcycles over interval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 	if (old->tsc < (1000 * 1000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 		errx(-3, "Insanely slow TSC rate, TSC stops in idle?\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 		     "You can disable all c-states by booting with \"idle=poll\"\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 		     "or just the deep ones with \"processor.max_cstate=1\"");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 	old->c1 = new->c1 - old->c1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	    soft_c1_residency_display(BIC_Avg_MHz)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 		if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 			old->aperf = new->aperf - old->aperf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 			old->mperf = new->mperf - old->mperf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	if (use_c1_residency_msr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 		 * Some models have a dedicated C1 residency MSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 		 * which should be more accurate than the derivation below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 		 * As counter collection is not atomic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 		 * it is possible for mperf's non-halted cycles + idle states
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 		 * to exceed TSC's all cycles: show c1 = 0% in that case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 		if ((old->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > (old->tsc * tsc_tweak))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 			old->c1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 			/* normal case, derive c1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 			old->c1 = (old->tsc * tsc_tweak) - old->mperf - core_delta->c3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 				- core_delta->c6 - core_delta->c7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 	if (old->mperf == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 		if (debug > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 			fprintf(outf, "cpu%d MPERF 0!\n", old->cpu_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 		old->mperf = 1;	/* divide by 0 protection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 	if (DO_BIC(BIC_IRQ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 		old->irq_count = new->irq_count - old->irq_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 	if (DO_BIC(BIC_SMI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 		old->smi_count = new->smi_count - old->smi_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 		if (mp->format == FORMAT_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 			old->counter[i] = new->counter[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 			old->counter[i] = new->counter[i] - old->counter[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) int delta_cpu(struct thread_data *t, struct core_data *c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 	struct pkg_data *p, struct thread_data *t2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 	struct core_data *c2, struct pkg_data *p2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	/* calculate core delta only for 1st thread in core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 	if (t->flags & CPU_IS_FIRST_THREAD_IN_CORE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 		delta_core(c, c2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 	/* always calculate thread delta */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 	retval = delta_thread(t, t2, c2);	/* c2 is core delta */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 		return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 	/* calculate package delta only for 1st core in package */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	if (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 		retval = delta_package(p, p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 	struct msr_counter  *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 	t->tv_begin.tv_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 	t->tv_begin.tv_usec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	t->tv_end.tv_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 	t->tv_end.tv_usec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	t->tv_delta.tv_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	t->tv_delta.tv_usec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 	t->tsc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	t->aperf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 	t->mperf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 	t->c1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 	t->irq_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	t->smi_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 	/* tells format_counters to dump all fields from this set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 	c->c3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 	c->c6 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 	c->c7 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 	c->mc6_us = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	c->core_temp_c = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 	c->core_energy = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	p->pkg_wtd_core_c0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	p->pkg_any_core_c0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 	p->pkg_any_gfxe_c0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 	p->pkg_both_core_gfxe_c0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	p->pc2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 	if (DO_BIC(BIC_Pkgpc3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 		p->pc3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 	if (DO_BIC(BIC_Pkgpc6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 		p->pc6 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 	if (DO_BIC(BIC_Pkgpc7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 		p->pc7 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	p->pc8 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	p->pc9 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	p->pc10 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	p->cpu_lpi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 	p->sys_lpi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	p->energy_pkg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 	p->energy_dram = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 	p->energy_cores = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 	p->energy_gfx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 	p->rapl_pkg_perf_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	p->rapl_dram_perf_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	p->pkg_temp_c = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	p->gfx_rc6_ms = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 	p->gfx_mhz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 	p->gfx_act_mhz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	for (i = 0, mp = sys.tp; mp; i++, mp = mp->next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 		t->counter[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	for (i = 0, mp = sys.cp; mp; i++, mp = mp->next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 		c->counter[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	for (i = 0, mp = sys.pp; mp; i++, mp = mp->next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 		p->counter[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) int sum_counters(struct thread_data *t, struct core_data *c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 	struct pkg_data *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 	struct msr_counter *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	/* copy un-changing apic_id's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	if (DO_BIC(BIC_APIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 		average.threads.apic_id = t->apic_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	if (DO_BIC(BIC_X2APIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 		average.threads.x2apic_id = t->x2apic_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	/* remember first tv_begin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 	if (average.threads.tv_begin.tv_sec == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 		average.threads.tv_begin = t->tv_begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	/* remember last tv_end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 	average.threads.tv_end = t->tv_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	average.threads.tsc += t->tsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	average.threads.aperf += t->aperf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	average.threads.mperf += t->mperf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 	average.threads.c1 += t->c1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 	average.threads.irq_count += t->irq_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 	average.threads.smi_count += t->smi_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 	for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 		if (mp->format == FORMAT_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 		average.threads.counter[i] += t->counter[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 	/* sum per-core values only for 1st thread in core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 	if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 	average.cores.c3 += c->c3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 	average.cores.c6 += c->c6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	average.cores.c7 += c->c7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	average.cores.mc6_us += c->mc6_us;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 	average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 	average.cores.core_energy += c->core_energy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 		if (mp->format == FORMAT_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 		average.cores.counter[i] += c->counter[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 	/* sum per-pkg values only for 1st core in pkg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 	if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 	if (DO_BIC(BIC_Totl_c0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 		average.packages.pkg_wtd_core_c0 += p->pkg_wtd_core_c0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 	if (DO_BIC(BIC_Any_c0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 		average.packages.pkg_any_core_c0 += p->pkg_any_core_c0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 	if (DO_BIC(BIC_GFX_c0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 		average.packages.pkg_any_gfxe_c0 += p->pkg_any_gfxe_c0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	if (DO_BIC(BIC_CPUGFX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 		average.packages.pkg_both_core_gfxe_c0 += p->pkg_both_core_gfxe_c0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 	average.packages.pc2 += p->pc2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 	if (DO_BIC(BIC_Pkgpc3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 		average.packages.pc3 += p->pc3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	if (DO_BIC(BIC_Pkgpc6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 		average.packages.pc6 += p->pc6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 	if (DO_BIC(BIC_Pkgpc7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 		average.packages.pc7 += p->pc7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	average.packages.pc8 += p->pc8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	average.packages.pc9 += p->pc9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 	average.packages.pc10 += p->pc10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	average.packages.cpu_lpi = p->cpu_lpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 	average.packages.sys_lpi = p->sys_lpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 	average.packages.energy_pkg += p->energy_pkg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 	average.packages.energy_dram += p->energy_dram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 	average.packages.energy_cores += p->energy_cores;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 	average.packages.energy_gfx += p->energy_gfx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	average.packages.gfx_rc6_ms = p->gfx_rc6_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 	average.packages.gfx_mhz = p->gfx_mhz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	average.packages.gfx_act_mhz = p->gfx_act_mhz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 	average.packages.pkg_temp_c = MAX(average.packages.pkg_temp_c, p->pkg_temp_c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 	average.packages.rapl_pkg_perf_status += p->rapl_pkg_perf_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 	average.packages.rapl_dram_perf_status += p->rapl_dram_perf_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 	for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 		if (mp->format == FORMAT_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 		average.packages.counter[i] += p->counter[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)  * sum the counters for all cpus in the system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696)  * compute the weighted average
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) void compute_average(struct thread_data *t, struct core_data *c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 	struct pkg_data *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 	struct msr_counter *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 	clear_counters(&average.threads, &average.cores, &average.packages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 	for_all_cpus(sum_counters, t, c, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 	/* Use the global time delta for the average. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 	average.threads.tv_delta = tv_delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 	average.threads.tsc /= topo.num_cpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 	average.threads.aperf /= topo.num_cpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 	average.threads.mperf /= topo.num_cpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 	average.threads.c1 /= topo.num_cpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	if (average.threads.irq_count > 9999999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 		sums_need_wide_columns = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 	average.cores.c3 /= topo.num_cores;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 	average.cores.c6 /= topo.num_cores;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 	average.cores.c7 /= topo.num_cores;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 	average.cores.mc6_us /= topo.num_cores;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 	if (DO_BIC(BIC_Totl_c0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 		average.packages.pkg_wtd_core_c0 /= topo.num_packages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 	if (DO_BIC(BIC_Any_c0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 		average.packages.pkg_any_core_c0 /= topo.num_packages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 	if (DO_BIC(BIC_GFX_c0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 		average.packages.pkg_any_gfxe_c0 /= topo.num_packages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	if (DO_BIC(BIC_CPUGFX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 		average.packages.pkg_both_core_gfxe_c0 /= topo.num_packages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 	average.packages.pc2 /= topo.num_packages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 	if (DO_BIC(BIC_Pkgpc3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 		average.packages.pc3 /= topo.num_packages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 	if (DO_BIC(BIC_Pkgpc6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 		average.packages.pc6 /= topo.num_packages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 	if (DO_BIC(BIC_Pkgpc7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 		average.packages.pc7 /= topo.num_packages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 	average.packages.pc8 /= topo.num_packages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	average.packages.pc9 /= topo.num_packages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 	average.packages.pc10 /= topo.num_packages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 	for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		if (mp->format == FORMAT_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 		if (mp->type == COUNTER_ITEMS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 			if (average.threads.counter[i] > 9999999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 				sums_need_wide_columns = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 		average.threads.counter[i] /= topo.num_cpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 	for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 		if (mp->format == FORMAT_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 		if (mp->type == COUNTER_ITEMS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 			if (average.cores.counter[i] > 9999999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 				sums_need_wide_columns = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 		average.cores.counter[i] /= topo.num_cores;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 	for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 		if (mp->format == FORMAT_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 		if (mp->type == COUNTER_ITEMS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 			if (average.packages.counter[i] > 9999999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 				sums_need_wide_columns = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 		average.packages.counter[i] /= topo.num_packages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) static unsigned long long rdtsc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 	unsigned int low, high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 	asm volatile("rdtsc" : "=a" (low), "=d" (high));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 	return low | ((unsigned long long)high) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)  * Open a file, and exit on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) FILE *fopen_or_die(const char *path, const char *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 	FILE *filep = fopen(path, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 	if (!filep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 		err(1, "%s: open failed", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 	return filep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)  * snapshot_sysfs_counter()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)  * return snapshot of given counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) unsigned long long snapshot_sysfs_counter(char *path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 	FILE *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 	unsigned long long counter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 	fp = fopen_or_die(path, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	retval = fscanf(fp, "%lld", &counter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 	if (retval != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 		err(1, "snapshot_sysfs_counter(%s)", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	fclose(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 	return counter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) int get_mp(int cpu, struct msr_counter *mp, unsigned long long *counterp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 	if (mp->msr_num != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 		if (get_msr(cpu, mp->msr_num, counterp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 		char path[128 + PATH_BYTES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 		if (mp->flags & SYSFS_PERCPU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 			sprintf(path, "/sys/devices/system/cpu/cpu%d/%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 				 cpu, mp->path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 			*counterp = snapshot_sysfs_counter(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 			*counterp = snapshot_sysfs_counter(mp->path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) void get_apic_id(struct thread_data *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 	unsigned int eax, ebx, ecx, edx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 	if (DO_BIC(BIC_APIC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 		eax = ebx = ecx = edx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 		__cpuid(1, eax, ebx, ecx, edx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 		t->apic_id = (ebx >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 	if (!DO_BIC(BIC_X2APIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 	if (authentic_amd || hygon_genuine) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 		unsigned int topology_extensions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 		if (max_extended_level < 0x8000001e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 		eax = ebx = ecx = edx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 		__cpuid(0x80000001, eax, ebx, ecx, edx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 			topology_extensions = ecx & (1 << 22);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 		if (topology_extensions == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 		eax = ebx = ecx = edx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 		__cpuid(0x8000001e, eax, ebx, ecx, edx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 		t->x2apic_id = eax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 	if (max_level < 0xb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 	ecx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 	__cpuid(0xb, eax, ebx, ecx, edx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 	t->x2apic_id = edx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 	if (debug && (t->apic_id != (t->x2apic_id & 0xff)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 		fprintf(outf, "cpu%d: BIOS BUG: apic 0x%x x2apic 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 				t->cpu_id, t->apic_id, t->x2apic_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)  * get_counters(...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)  * migrate to cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890)  * acquire and record local counters for that cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 	int cpu = t->cpu_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 	int aperf_mperf_retry_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 	struct msr_counter *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 	if (cpu_migrate(cpu)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 		fprintf(outf, "get_counters: Could not migrate to CPU %d\n", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 	gettimeofday(&t->tv_begin, (struct timezone *)NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 	if (first_counter_read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 		get_apic_id(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 	t->tsc = rdtsc();	/* we are running on local CPU of interest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 	if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 	    soft_c1_residency_display(BIC_Avg_MHz)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 		unsigned long long tsc_before, tsc_between, tsc_after, aperf_time, mperf_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 		 * The TSC, APERF and MPERF must be read together for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 		 * APERF/MPERF and MPERF/TSC to give accurate results.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 		 * Unfortunately, APERF and MPERF are read by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 		 * individual system call, so delays may occur
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 		 * between them.  If the time to read them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 		 * varies by a large amount, we re-read them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 		 * This initial dummy APERF read has been seen to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 		 * reduce jitter in the subsequent reads.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 		if (get_msr(cpu, MSR_IA32_APERF, &t->aperf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 			return -3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 		t->tsc = rdtsc();	/* re-read close to APERF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 		tsc_before = t->tsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 		if (get_msr(cpu, MSR_IA32_APERF, &t->aperf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 			return -3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 		tsc_between = rdtsc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 		if (get_msr(cpu, MSR_IA32_MPERF, &t->mperf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 			return -4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 		tsc_after = rdtsc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 		aperf_time = tsc_between - tsc_before;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 		mperf_time = tsc_after - tsc_between;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 		 * If the system call latency to read APERF and MPERF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 		 * differ by more than 2x, then try again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 		if ((aperf_time > (2 * mperf_time)) || (mperf_time > (2 * aperf_time))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 			aperf_mperf_retry_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 			if (aperf_mperf_retry_count < 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 				goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 				warnx("cpu%d jitter %lld %lld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 					cpu, aperf_time, mperf_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 		aperf_mperf_retry_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 		t->aperf = t->aperf * aperf_mperf_multiplier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 		t->mperf = t->mperf * aperf_mperf_multiplier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 	if (DO_BIC(BIC_IRQ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 		t->irq_count = irqs_per_cpu[cpu];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 	if (DO_BIC(BIC_SMI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 		if (get_msr(cpu, MSR_SMI_COUNT, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 			return -5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 		t->smi_count = msr & 0xFFFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 	if (DO_BIC(BIC_CPU_c1) && use_c1_residency_msr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 		if (get_msr(cpu, MSR_CORE_C1_RES, &t->c1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 			return -6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 	for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 		if (get_mp(cpu, mp, &t->counter[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 			return -10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 	/* collect core counters only for 1st thread in core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 	if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 	if (DO_BIC(BIC_CPU_c3) || soft_c1_residency_display(BIC_CPU_c3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 		if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 			return -6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 	if ((DO_BIC(BIC_CPU_c6) || soft_c1_residency_display(BIC_CPU_c6)) && !do_knl_cstates) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 		if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 			return -7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 	} else if (do_knl_cstates || soft_c1_residency_display(BIC_CPU_c6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 		if (get_msr(cpu, MSR_KNL_CORE_C6_RESIDENCY, &c->c6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 			return -7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 	if (DO_BIC(BIC_CPU_c7) || soft_c1_residency_display(BIC_CPU_c7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 		if (get_msr(cpu, MSR_CORE_C7_RESIDENCY, &c->c7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 			return -8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 	if (DO_BIC(BIC_Mod_c6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 		if (get_msr(cpu, MSR_MODULE_C6_RES_MS, &c->mc6_us))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 			return -8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 	if (DO_BIC(BIC_CoreTmp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 		if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 			return -9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 		c->core_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 	if (do_rapl & RAPL_AMD_F17H) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 		if (get_msr(cpu, MSR_CORE_ENERGY_STAT, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 			return -14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 		c->core_energy = msr & 0xFFFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 	for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 		if (get_mp(cpu, mp, &c->counter[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 			return -10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 	/* collect package counters only for 1st core in package */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 	if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 	if (DO_BIC(BIC_Totl_c0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 		if (get_msr(cpu, MSR_PKG_WEIGHTED_CORE_C0_RES, &p->pkg_wtd_core_c0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 			return -10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 	if (DO_BIC(BIC_Any_c0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 		if (get_msr(cpu, MSR_PKG_ANY_CORE_C0_RES, &p->pkg_any_core_c0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 			return -11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 	if (DO_BIC(BIC_GFX_c0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 		if (get_msr(cpu, MSR_PKG_ANY_GFXE_C0_RES, &p->pkg_any_gfxe_c0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 			return -12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 	if (DO_BIC(BIC_CPUGFX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 		if (get_msr(cpu, MSR_PKG_BOTH_CORE_GFXE_C0_RES, &p->pkg_both_core_gfxe_c0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 			return -13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 	if (DO_BIC(BIC_Pkgpc3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 		if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 			return -9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 	if (DO_BIC(BIC_Pkgpc6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 		if (do_slm_cstates) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 			if (get_msr(cpu, MSR_ATOM_PKG_C6_RESIDENCY, &p->pc6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 				return -10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 			if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 				return -10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 	if (DO_BIC(BIC_Pkgpc2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 		if (get_msr(cpu, MSR_PKG_C2_RESIDENCY, &p->pc2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 			return -11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 	if (DO_BIC(BIC_Pkgpc7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 		if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 			return -12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 	if (DO_BIC(BIC_Pkgpc8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 		if (get_msr(cpu, MSR_PKG_C8_RESIDENCY, &p->pc8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 			return -13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 	if (DO_BIC(BIC_Pkgpc9))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 		if (get_msr(cpu, MSR_PKG_C9_RESIDENCY, &p->pc9))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 			return -13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 	if (DO_BIC(BIC_Pkgpc10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 		if (get_msr(cpu, MSR_PKG_C10_RESIDENCY, &p->pc10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 			return -13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 	if (DO_BIC(BIC_CPU_LPI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 		p->cpu_lpi = cpuidle_cur_cpu_lpi_us;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 	if (DO_BIC(BIC_SYS_LPI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 		p->sys_lpi = cpuidle_cur_sys_lpi_us;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 	if (do_rapl & RAPL_PKG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 		if (get_msr_sum(cpu, MSR_PKG_ENERGY_STATUS, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 			return -13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 		p->energy_pkg = msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 	if (do_rapl & RAPL_CORES_ENERGY_STATUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 		if (get_msr_sum(cpu, MSR_PP0_ENERGY_STATUS, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 			return -14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 		p->energy_cores = msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 	if (do_rapl & RAPL_DRAM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 		if (get_msr_sum(cpu, MSR_DRAM_ENERGY_STATUS, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 			return -15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 		p->energy_dram = msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 	if (do_rapl & RAPL_GFX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 		if (get_msr_sum(cpu, MSR_PP1_ENERGY_STATUS, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 			return -16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 		p->energy_gfx = msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 	if (do_rapl & RAPL_PKG_PERF_STATUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 		if (get_msr_sum(cpu, MSR_PKG_PERF_STATUS, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 			return -16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 		p->rapl_pkg_perf_status = msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 	if (do_rapl & RAPL_DRAM_PERF_STATUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 		if (get_msr_sum(cpu, MSR_DRAM_PERF_STATUS, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 			return -16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 		p->rapl_dram_perf_status = msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 	if (do_rapl & RAPL_AMD_F17H) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 		if (get_msr_sum(cpu, MSR_PKG_ENERGY_STAT, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 			return -13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 		p->energy_pkg = msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 	if (DO_BIC(BIC_PkgTmp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 		if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 			return -17;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 		p->pkg_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 	if (DO_BIC(BIC_GFX_rc6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 		p->gfx_rc6_ms = gfx_cur_rc6_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 	if (DO_BIC(BIC_GFXMHz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 		p->gfx_mhz = gfx_cur_mhz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 	if (DO_BIC(BIC_GFXACTMHz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 		p->gfx_act_mhz = gfx_act_mhz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 	for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 		if (get_mp(cpu, mp, &p->counter[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 			return -10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 	gettimeofday(&t->tv_end, (struct timezone *)NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143)  * MSR_PKG_CST_CONFIG_CONTROL decoding for pkg_cstate_limit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144)  * If you change the values, note they are used both in comparisons
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145)  * (>= PCL__7) and to index pkg_cstate_limit_strings[].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) #define PCLUKN 0 /* Unknown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) #define PCLRSV 1 /* Reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) #define PCL__0 2 /* PC0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) #define PCL__1 3 /* PC1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) #define PCL__2 4 /* PC2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) #define PCL__3 5 /* PC3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) #define PCL__4 6 /* PC4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) #define PCL__6 7 /* PC6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) #define PCL_6N 8 /* PC6 No Retention */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) #define PCL_6R 9 /* PC6 Retention */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) #define PCL__7 10 /* PC7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) #define PCL_7S 11 /* PC7 Shrink */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) #define PCL__8 12 /* PC8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) #define PCL__9 13 /* PC9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) #define PCL_10 14 /* PC10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) #define PCLUNL 15 /* Unlimited */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) int pkg_cstate_limit = PCLUKN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) char *pkg_cstate_limit_strings[] = { "reserved", "unknown", "pc0", "pc1", "pc2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 	"pc3", "pc4", "pc6", "pc6n", "pc6r", "pc7", "pc7s", "pc8", "pc9", "pc10", "unlimited"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) int nhm_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCL__3, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) int snb_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCL__7, PCL_7S, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) int hsw_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL__3, PCL__6, PCL__7, PCL_7S, PCL__8, PCL__9, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) int slv_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) int amt_pkg_cstate_limits[16] = {PCLUNL, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) int phi_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) int glm_pkg_cstate_limits[16] = {PCLUNL, PCL__1, PCL__3, PCL__6, PCL__7, PCL_7S, PCL__8, PCL__9, PCL_10, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) int skx_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) calculate_tsc_tweak()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 	tsc_tweak = base_hz / tsc_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) dump_nhm_platform_info(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 	unsigned int ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 	get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 	fprintf(outf, "cpu%d: MSR_PLATFORM_INFO: 0x%08llx\n", base_cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 	ratio = (msr >> 40) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 	fprintf(outf, "%d * %.1f = %.1f MHz max efficiency frequency\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 		ratio, bclk, ratio * bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 	ratio = (msr >> 8) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 	fprintf(outf, "%d * %.1f = %.1f MHz base frequency\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 		ratio, bclk, ratio * bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 	get_msr(base_cpu, MSR_IA32_POWER_CTL, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 	fprintf(outf, "cpu%d: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 		base_cpu, msr, msr & 0x2 ? "EN" : "DIS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) dump_hsw_turbo_ratio_limits(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 	unsigned int ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 	get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT2, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 	fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT2: 0x%08llx\n", base_cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 	ratio = (msr >> 8) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 18 active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 			ratio, bclk, ratio * bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) 	ratio = (msr >> 0) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 17 active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 			ratio, bclk, ratio * bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) dump_ivt_turbo_ratio_limits(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 	unsigned int ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 	get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 	fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 	ratio = (msr >> 56) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 16 active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 			ratio, bclk, ratio * bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 	ratio = (msr >> 48) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 15 active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 			ratio, bclk, ratio * bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 	ratio = (msr >> 40) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 14 active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 			ratio, bclk, ratio * bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 	ratio = (msr >> 32) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 13 active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 			ratio, bclk, ratio * bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 	ratio = (msr >> 24) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 12 active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 			ratio, bclk, ratio * bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 	ratio = (msr >> 16) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 11 active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 			ratio, bclk, ratio * bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 	ratio = (msr >> 8) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 10 active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 			ratio, bclk, ratio * bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 	ratio = (msr >> 0) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 9 active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 			ratio, bclk, ratio * bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) int has_turbo_ratio_group_limits(int family, int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 	case INTEL_FAM6_ATOM_GOLDMONT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 	case INTEL_FAM6_SKYLAKE_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 	case INTEL_FAM6_ATOM_GOLDMONT_D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 	case INTEL_FAM6_ATOM_TREMONT_D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) dump_turbo_ratio_limits(int family, int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 	unsigned long long msr, core_counts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 	unsigned int ratio, group_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 	get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 	fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", base_cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 	if (has_turbo_ratio_group_limits(family, model)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 		get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &core_counts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 		fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, core_counts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 		core_counts = 0x0807060504030201;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 	ratio = (msr >> 56) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 	group_size = (core_counts >> 56) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 			ratio, bclk, ratio * bclk, group_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 	ratio = (msr >> 48) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 	group_size = (core_counts >> 48) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 			ratio, bclk, ratio * bclk, group_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 	ratio = (msr >> 40) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 	group_size = (core_counts >> 40) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 			ratio, bclk, ratio * bclk, group_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 	ratio = (msr >> 32) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 	group_size = (core_counts >> 32) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 			ratio, bclk, ratio * bclk, group_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 	ratio = (msr >> 24) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 	group_size = (core_counts >> 24) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 			ratio, bclk, ratio * bclk, group_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 	ratio = (msr >> 16) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 	group_size = (core_counts >> 16) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 			ratio, bclk, ratio * bclk, group_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 	ratio = (msr >> 8) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 	group_size = (core_counts >> 8) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 			ratio, bclk, ratio * bclk, group_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 	ratio = (msr >> 0) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 	group_size = (core_counts >> 0) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 			ratio, bclk, ratio * bclk, group_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) dump_atom_turbo_ratio_limits(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 	unsigned int ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 	get_msr(base_cpu, MSR_ATOM_CORE_RATIOS, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 	fprintf(outf, "cpu%d: MSR_ATOM_CORE_RATIOS: 0x%08llx\n", base_cpu, msr & 0xFFFFFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 	ratio = (msr >> 0) & 0x3F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 		fprintf(outf, "%d * %.1f = %.1f MHz minimum operating frequency\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 			ratio, bclk, ratio * bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 	ratio = (msr >> 8) & 0x3F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 		fprintf(outf, "%d * %.1f = %.1f MHz low frequency mode (LFM)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 			ratio, bclk, ratio * bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 	ratio = (msr >> 16) & 0x3F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 		fprintf(outf, "%d * %.1f = %.1f MHz base frequency\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 			ratio, bclk, ratio * bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 	get_msr(base_cpu, MSR_ATOM_CORE_TURBO_RATIOS, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 	fprintf(outf, "cpu%d: MSR_ATOM_CORE_TURBO_RATIOS: 0x%08llx\n", base_cpu, msr & 0xFFFFFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 	ratio = (msr >> 24) & 0x3F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 4 active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 			ratio, bclk, ratio * bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 	ratio = (msr >> 16) & 0x3F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 3 active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 			ratio, bclk, ratio * bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 	ratio = (msr >> 8) & 0x3F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 2 active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 			ratio, bclk, ratio * bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 	ratio = (msr >> 0) & 0x3F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 	if (ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 1 active core\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 			ratio, bclk, ratio * bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) dump_knl_turbo_ratio_limits(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 	const unsigned int buckets_no = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 	int delta_cores, delta_ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 	int i, b_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 	unsigned int cores[buckets_no];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 	unsigned int ratio[buckets_no];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 	get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 	fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 		base_cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 	/**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 	 * Turbo encoding in KNL is as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 	 * [0] -- Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 	 * [7:1] -- Base value of number of active cores of bucket 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 	 * [15:8] -- Base value of freq ratio of bucket 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 	 * [20:16] -- +ve delta of number of active cores of bucket 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 	 * i.e. active cores of bucket 2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 	 * active cores of bucket 1 + delta
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 	 * [23:21] -- Negative delta of freq ratio of bucket 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 	 * i.e. freq ratio of bucket 2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 	 * freq ratio of bucket 1 - delta
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 	 * [28:24]-- +ve delta of number of active cores of bucket 3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 	 * [31:29]-- -ve delta of freq ratio of bucket 3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 	 * [36:32]-- +ve delta of number of active cores of bucket 4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 	 * [39:37]-- -ve delta of freq ratio of bucket 4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 	 * [44:40]-- +ve delta of number of active cores of bucket 5.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 	 * [47:45]-- -ve delta of freq ratio of bucket 5.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 	 * [52:48]-- +ve delta of number of active cores of bucket 6.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 	 * [55:53]-- -ve delta of freq ratio of bucket 6.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 	 * [60:56]-- +ve delta of number of active cores of bucket 7.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 	 * [63:61]-- -ve delta of freq ratio of bucket 7.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 	b_nr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 	cores[b_nr] = (msr & 0xFF) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 	ratio[b_nr] = (msr >> 8) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 	for (i = 16; i < 64; i += 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 		delta_cores = (msr >> i) & 0x1F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 		delta_ratio = (msr >> (i + 5)) & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 		cores[b_nr + 1] = cores[b_nr] + delta_cores;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 		ratio[b_nr + 1] = ratio[b_nr] - delta_ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 		b_nr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 	for (i = buckets_no - 1; i >= 0; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 		if (i > 0 ? ratio[i] != ratio[i - 1] : 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 			fprintf(outf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 				"%d * %.1f = %.1f MHz max turbo %d active cores\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 				ratio[i], bclk, ratio[i] * bclk, cores[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) dump_nhm_cst_cfg(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 	get_msr(base_cpu, MSR_PKG_CST_CONFIG_CONTROL, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 	fprintf(outf, "cpu%d: MSR_PKG_CST_CONFIG_CONTROL: 0x%08llx", base_cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 	fprintf(outf, " (%s%s%s%s%slocked, pkg-cstate-limit=%d (%s)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 		(msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 		(msr & SNB_C1_AUTO_UNDEMOTE) ? "UNdemote-C1, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 		(msr & NHM_C3_AUTO_DEMOTE) ? "demote-C3, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 		(msr & NHM_C1_AUTO_DEMOTE) ? "demote-C1, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 		(msr & (1 << 15)) ? "" : "UN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 		(unsigned int)msr & 0xF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 		pkg_cstate_limit_strings[pkg_cstate_limit]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) #define AUTOMATIC_CSTATE_CONVERSION		(1UL << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 	if (has_automatic_cstate_conversion) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 		fprintf(outf, ", automatic c-state conversion=%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 			(msr & AUTOMATIC_CSTATE_CONVERSION) ? "on" : "off");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 	fprintf(outf, ")\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) dump_config_tdp(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 	get_msr(base_cpu, MSR_CONFIG_TDP_NOMINAL, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 	fprintf(outf, "cpu%d: MSR_CONFIG_TDP_NOMINAL: 0x%08llx", base_cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 	fprintf(outf, " (base_ratio=%d)\n", (unsigned int)msr & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 	get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_1, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 	fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_1: 0x%08llx (", base_cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 	if (msr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 		fprintf(outf, "PKG_MIN_PWR_LVL1=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 		fprintf(outf, "PKG_MAX_PWR_LVL1=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 		fprintf(outf, "LVL1_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 		fprintf(outf, "PKG_TDP_LVL1=%d", (unsigned int)(msr) & 0x7FFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 	fprintf(outf, ")\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 	get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_2, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 	fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_2: 0x%08llx (", base_cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 	if (msr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 		fprintf(outf, "PKG_MIN_PWR_LVL2=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 		fprintf(outf, "PKG_MAX_PWR_LVL2=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 		fprintf(outf, "LVL2_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 		fprintf(outf, "PKG_TDP_LVL2=%d", (unsigned int)(msr) & 0x7FFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 	fprintf(outf, ")\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 	get_msr(base_cpu, MSR_CONFIG_TDP_CONTROL, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 	fprintf(outf, "cpu%d: MSR_CONFIG_TDP_CONTROL: 0x%08llx (", base_cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 	if ((msr) & 0x3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 		fprintf(outf, "TDP_LEVEL=%d ", (unsigned int)(msr) & 0x3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 	fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 	fprintf(outf, ")\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 	get_msr(base_cpu, MSR_TURBO_ACTIVATION_RATIO, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 	fprintf(outf, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 	fprintf(outf, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 	fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 	fprintf(outf, ")\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) unsigned int irtl_time_units[] = {1, 32, 1024, 32768, 1048576, 33554432, 0, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) void print_irtl(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 	get_msr(base_cpu, MSR_PKGC3_IRTL, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 	fprintf(outf, "cpu%d: MSR_PKGC3_IRTL: 0x%08llx (", base_cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 	fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 		(msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 	get_msr(base_cpu, MSR_PKGC6_IRTL, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 	fprintf(outf, "cpu%d: MSR_PKGC6_IRTL: 0x%08llx (", base_cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 	fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 		(msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 	get_msr(base_cpu, MSR_PKGC7_IRTL, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 	fprintf(outf, "cpu%d: MSR_PKGC7_IRTL: 0x%08llx (", base_cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 	fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 		(msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 	if (!do_irtl_hsw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 	get_msr(base_cpu, MSR_PKGC8_IRTL, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 	fprintf(outf, "cpu%d: MSR_PKGC8_IRTL: 0x%08llx (", base_cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 	fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 		(msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 	get_msr(base_cpu, MSR_PKGC9_IRTL, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 	fprintf(outf, "cpu%d: MSR_PKGC9_IRTL: 0x%08llx (", base_cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 	fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 		(msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 	get_msr(base_cpu, MSR_PKGC10_IRTL, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 	fprintf(outf, "cpu%d: MSR_PKGC10_IRTL: 0x%08llx (", base_cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 	fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 		(msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) void free_fd_percpu(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 	for (i = 0; i < topo.max_cpu_num + 1; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 		if (fd_percpu[i] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 			close(fd_percpu[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 	free(fd_percpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) void free_all_buffers(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 	CPU_FREE(cpu_present_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 	cpu_present_set = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 	cpu_present_setsize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 	CPU_FREE(cpu_affinity_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 	cpu_affinity_set = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 	cpu_affinity_setsize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 	free(thread_even);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 	free(core_even);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 	free(package_even);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 	thread_even = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 	core_even = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 	package_even = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 	free(thread_odd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 	free(core_odd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 	free(package_odd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 	thread_odd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 	core_odd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 	package_odd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 	free(output_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 	output_buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 	outp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 	free_fd_percpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 	free(irq_column_2_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 	free(irqs_per_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 	for (i = 0; i <= topo.max_cpu_num; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 		if (cpus[i].put_ids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 			CPU_FREE(cpus[i].put_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 	free(cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642)  * Parse a file containing a single int.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643)  * Return 0 if file can not be opened
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644)  * Exit if file can be opened, but can not be parsed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) int parse_int_file(const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 	va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 	char path[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 	FILE *filep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 	int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 	va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 	vsnprintf(path, sizeof(path), fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 	va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 	filep = fopen(path, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 	if (!filep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 	if (fscanf(filep, "%d", &value) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 		err(1, "%s: failed to parse number from file", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 	fclose(filep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 	return value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666)  * cpu_is_first_core_in_package(cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667)  * return 1 if given CPU is 1st core in package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) int cpu_is_first_core_in_package(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 	return cpu == parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_siblings_list", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) int get_physical_package_id(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 	return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) int get_die_id(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 	return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/die_id", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) int get_core_id(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 	return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) void set_node_data(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 	int pkg, node, lnode, cpu, cpux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 	int cpu_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 	/* initialize logical_node_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 	for (cpu = 0; cpu <= topo.max_cpu_num; ++cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 		cpus[cpu].logical_node_id = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 	cpu_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 	for (pkg = 0; pkg < topo.num_packages; pkg++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 		lnode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 		for (cpu = 0; cpu <= topo.max_cpu_num; ++cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 			if (cpus[cpu].physical_package_id != pkg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 			/* find a cpu with an unset logical_node_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 			if (cpus[cpu].logical_node_id != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 			cpus[cpu].logical_node_id = lnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 			node = cpus[cpu].physical_node_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 			cpu_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 			 * find all matching cpus on this pkg and set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 			 * the logical_node_id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 			for (cpux = cpu; cpux <= topo.max_cpu_num; cpux++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 				if ((cpus[cpux].physical_package_id == pkg) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 				   (cpus[cpux].physical_node_id == node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) 					cpus[cpux].logical_node_id = lnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 					cpu_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 			lnode++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 			if (lnode > topo.nodes_per_pkg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 				topo.nodes_per_pkg = lnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 		if (cpu_count >= topo.max_cpu_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) int get_physical_node_id(struct cpu_topology *thiscpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 	char path[80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 	FILE *filep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 	int cpu = thiscpu->logical_cpu_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 	for (i = 0; i <= topo.max_cpu_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 		sprintf(path, "/sys/devices/system/cpu/cpu%d/node%i/cpulist",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 			cpu, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 		filep = fopen(path, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 		if (!filep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 		fclose(filep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 		return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) int get_thread_siblings(struct cpu_topology *thiscpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 	char path[80], character;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 	FILE *filep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 	unsigned long map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 	int so, shift, sib_core;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 	int cpu = thiscpu->logical_cpu_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 	int offset = topo.max_cpu_num + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 	size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 	int thread_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 	thiscpu->put_ids = CPU_ALLOC((topo.max_cpu_num + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 	if (thiscpu->thread_id < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 		thiscpu->thread_id = thread_id++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 	if (!thiscpu->put_ids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 	size = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 	CPU_ZERO_S(size, thiscpu->put_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 	sprintf(path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 		"/sys/devices/system/cpu/cpu%d/topology/thread_siblings", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 	filep = fopen(path, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 	if (!filep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 		warnx("%s: open failed", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 		offset -= BITMASK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 		if (fscanf(filep, "%lx%c", &map, &character) != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 			err(1, "%s: failed to parse file", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 		for (shift = 0; shift < BITMASK_SIZE; shift++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 			if ((map >> shift) & 0x1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 				so = shift + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 				sib_core = get_core_id(so);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 				if (sib_core == thiscpu->physical_core_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 					CPU_SET_S(so, size, thiscpu->put_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 					if ((so != cpu) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 					    (cpus[so].thread_id < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 						cpus[so].thread_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 								    thread_id++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 	} while (!strncmp(&character, ",", 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 	fclose(filep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 	return CPU_COUNT_S(size, thiscpu->put_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801)  * run func(thread, core, package) in topology order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802)  * skip non-present cpus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) int for_all_cpus_2(int (func)(struct thread_data *, struct core_data *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 	struct pkg_data *, struct thread_data *, struct core_data *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 	struct pkg_data *), struct thread_data *thread_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 	struct core_data *core_base, struct pkg_data *pkg_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 	struct thread_data *thread_base2, struct core_data *core_base2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 	struct pkg_data *pkg_base2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 	int retval, pkg_no, node_no, core_no, thread_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 	for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 		for (node_no = 0; node_no < topo.nodes_per_pkg; ++node_no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 			for (core_no = 0; core_no < topo.cores_per_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 			     ++core_no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 				for (thread_no = 0; thread_no <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 					topo.threads_per_core; ++thread_no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 					struct thread_data *t, *t2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 					struct core_data *c, *c2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 					struct pkg_data *p, *p2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 					t = GET_THREAD(thread_base, thread_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 						       core_no, node_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 						       pkg_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 					if (cpu_is_not_present(t->cpu_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 						continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 					t2 = GET_THREAD(thread_base2, thread_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 							core_no, node_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 							pkg_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 					c = GET_CORE(core_base, core_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 						     node_no, pkg_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 					c2 = GET_CORE(core_base2, core_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 						      node_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 						      pkg_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 					p = GET_PKG(pkg_base, pkg_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 					p2 = GET_PKG(pkg_base2, pkg_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 					retval = func(t, c, p, t2, c2, p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 					if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 						return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855)  * run func(cpu) on every cpu in /proc/stat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856)  * return max_cpu number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) int for_all_proc_cpus(int (func)(int))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 	FILE *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 	int cpu_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 	fp = fopen_or_die(proc_stat, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 	retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 	if (retval != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 		err(1, "%s: failed to parse format", proc_stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 		retval = fscanf(fp, "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n", &cpu_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 		if (retval != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 		retval = func(cpu_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 		if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 			fclose(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 			return(retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 	fclose(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) void re_initialize(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 	free_all_buffers();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 	setup_all_buffers();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 	fprintf(outf, "turbostat: re-initialized with num_cpus %d\n", topo.num_cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) void set_max_cpu_num(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 	FILE *filep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 	int base_cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 	unsigned long dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 	char pathname[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 	base_cpu = sched_getcpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 	if (base_cpu < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 		err(1, "cannot find calling cpu ID");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 	sprintf(pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 		"/sys/devices/system/cpu/cpu%d/topology/thread_siblings",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 		base_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 	filep = fopen_or_die(pathname, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 	topo.max_cpu_num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 	while (fscanf(filep, "%lx,", &dummy) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 		topo.max_cpu_num += BITMASK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 	fclose(filep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 	topo.max_cpu_num--; /* 0 based */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915)  * count_cpus()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916)  * remember the last one seen, it will be the max
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) int count_cpus(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 	topo.num_cpus++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) int mark_cpu_present(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 	CPU_SET_S(cpu, cpu_present_setsize, cpu_present_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) int init_thread_id(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 	cpus[cpu].thread_id = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936)  * snapshot_proc_interrupts()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938)  * read and record summary of /proc/interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940)  * return 1 if config change requires a restart, else return 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) int snapshot_proc_interrupts(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 	static FILE *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 	int column, retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) 	if (fp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 		fp = fopen_or_die("/proc/interrupts", "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 		rewind(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 	/* read 1st line of /proc/interrupts to get cpu* name for each column */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 	for (column = 0; column < topo.num_cpus; ++column) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 		int cpu_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 		retval = fscanf(fp, " CPU%d", &cpu_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 		if (retval != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 		if (cpu_number > topo.max_cpu_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) 			warn("/proc/interrupts: cpu%d: > %d", cpu_number, topo.max_cpu_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 		irq_column_2_cpu[column] = cpu_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 		irqs_per_cpu[cpu_number] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) 	/* read /proc/interrupt count lines and sum up irqs per cpu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 		int column;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) 		char buf[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 		retval = fscanf(fp, " %s:", buf);	/* flush irq# "N:" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 		if (retval != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 		/* read the count per cpu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 		for (column = 0; column < topo.num_cpus; ++column) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 			int cpu_number, irq_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) 			retval = fscanf(fp, " %d", &irq_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 			if (retval != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 			cpu_number = irq_column_2_cpu[column];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 			irqs_per_cpu[cpu_number] += irq_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 		while (getc(fp) != '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 			;	/* flush interrupt description */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999)  * snapshot_gfx_rc6_ms()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001)  * record snapshot of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002)  * /sys/class/drm/card0/power/rc6_residency_ms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004)  * return 1 if config change requires a restart, else return 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) int snapshot_gfx_rc6_ms(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 	FILE *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 	fp = fopen_or_die("/sys/class/drm/card0/power/rc6_residency_ms", "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 	retval = fscanf(fp, "%lld", &gfx_cur_rc6_ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 	if (retval != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 		err(1, "GFX rc6");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 	fclose(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022)  * snapshot_gfx_mhz()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024)  * record snapshot of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025)  * /sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027)  * return 1 if config change requires a restart, else return 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) int snapshot_gfx_mhz(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 	static FILE *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 	if (fp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 		fp = fopen_or_die("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 		rewind(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 		fflush(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 	retval = fscanf(fp, "%d", &gfx_cur_mhz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) 	if (retval != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 		err(1, "GFX MHz");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049)  * snapshot_gfx_cur_mhz()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051)  * record snapshot of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052)  * /sys/class/graphics/fb0/device/drm/card0/gt_act_freq_mhz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054)  * return 1 if config change requires a restart, else return 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) int snapshot_gfx_act_mhz(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 	static FILE *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 	if (fp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 		fp = fopen_or_die("/sys/class/graphics/fb0/device/drm/card0/gt_act_freq_mhz", "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 		rewind(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 		fflush(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 	retval = fscanf(fp, "%d", &gfx_act_mhz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 	if (retval != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) 		err(1, "GFX ACT MHz");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076)  * snapshot_cpu_lpi()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078)  * record snapshot of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079)  * /sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) int snapshot_cpu_lpi_us(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) 	FILE *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) 	fp = fopen_or_die("/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us", "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 	retval = fscanf(fp, "%lld", &cpuidle_cur_cpu_lpi_us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 	if (retval != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 		fprintf(stderr, "Disabling Low Power Idle CPU output\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 		BIC_NOT_PRESENT(BIC_CPU_LPI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 		fclose(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 	fclose(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101)  * snapshot_sys_lpi()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103)  * record snapshot of sys_lpi_file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) int snapshot_sys_lpi_us(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 	FILE *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 	fp = fopen_or_die(sys_lpi_file, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 	retval = fscanf(fp, "%lld", &cpuidle_cur_sys_lpi_us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 	if (retval != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 		fprintf(stderr, "Disabling Low Power Idle System output\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 		BIC_NOT_PRESENT(BIC_SYS_LPI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 		fclose(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 	fclose(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124)  * snapshot /proc and /sys files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126)  * return 1 if configuration restart needed, else return 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) int snapshot_proc_sysfs_files(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) 	if (DO_BIC(BIC_IRQ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) 		if (snapshot_proc_interrupts())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 	if (DO_BIC(BIC_GFX_rc6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 		snapshot_gfx_rc6_ms();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) 	if (DO_BIC(BIC_GFXMHz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 		snapshot_gfx_mhz();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 	if (DO_BIC(BIC_GFXACTMHz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 		snapshot_gfx_act_mhz();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 	if (DO_BIC(BIC_CPU_LPI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 		snapshot_cpu_lpi_us();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 	if (DO_BIC(BIC_SYS_LPI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 		snapshot_sys_lpi_us();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) int exit_requested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) static void signal_handler (int signal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 	switch (signal) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 	case SIGINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 		exit_requested = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 		if (debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) 			fprintf(stderr, " SIGINT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) 	case SIGUSR1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) 		if (debug > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) 			fprintf(stderr, "SIGUSR1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) void setup_signal_handler(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) 	struct sigaction sa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) 	memset(&sa, 0, sizeof(sa));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) 	sa.sa_handler = &signal_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 	if (sigaction(SIGINT, &sa, NULL) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 		err(1, "sigaction SIGINT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) 	if (sigaction(SIGUSR1, &sa, NULL) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 		err(1, "sigaction SIGUSR1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) void do_sleep(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 	struct timeval tout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 	struct timespec rest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) 	fd_set readfds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 	FD_ZERO(&readfds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) 	FD_SET(0, &readfds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) 	if (ignore_stdin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) 		nanosleep(&interval_ts, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 	tout = interval_tv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) 	retval = select(1, &readfds, NULL, NULL, &tout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) 	if (retval == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) 		switch (getc(stdin)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 		case 'q':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) 			exit_requested = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) 		case EOF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) 			 * 'stdin' is a pipe closed on the other end. There
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) 			 * won't be any further input.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 			ignore_stdin = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 			/* Sleep the rest of the time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 			rest.tv_sec = (tout.tv_sec + tout.tv_usec / 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 			rest.tv_nsec = (tout.tv_usec % 1000000) * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 			nanosleep(&rest, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) int get_msr_sum(int cpu, off_t offset, unsigned long long *msr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) 	int ret, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) 	unsigned long long msr_cur, msr_last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) 	if (!per_cpu_msr_sum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) 	idx = offset_to_idx(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) 	if (idx < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 		return idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) 	/* get_msr_sum() = sum + (get_msr() - last) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) 	ret = get_msr(cpu, offset, &msr_cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) 	msr_last = per_cpu_msr_sum[cpu].entries[idx].last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 	DELTA_WRAP32(msr_cur, msr_last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) 	*msr = msr_last + per_cpu_msr_sum[cpu].entries[idx].sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) timer_t timerid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) /* Timer callback, update the sum of MSRs periodically. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) static int update_msr_sum(struct thread_data *t, struct core_data *c, struct pkg_data *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) 	int cpu = t->cpu_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) 	for (i = IDX_PKG_ENERGY; i < IDX_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) 		unsigned long long msr_cur, msr_last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 		off_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) 		if (!idx_valid(i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 		offset = idx_to_offset(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) 		if (offset < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) 		ret = get_msr(cpu, offset, &msr_cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) 			fprintf(outf, "Can not update msr(0x%llx)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) 				(unsigned long long)offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) 		msr_last = per_cpu_msr_sum[cpu].entries[i].last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) 		per_cpu_msr_sum[cpu].entries[i].last = msr_cur & 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) 		DELTA_WRAP32(msr_cur, msr_last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) 		per_cpu_msr_sum[cpu].entries[i].sum += msr_last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) msr_record_handler(union sigval v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) 	for_all_cpus(update_msr_sum, EVEN_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) void msr_sum_record(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) 	struct itimerspec its;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 	struct sigevent sev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) 	per_cpu_msr_sum = calloc(topo.max_cpu_num + 1, sizeof(struct msr_sum_array));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) 	if (!per_cpu_msr_sum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) 		fprintf(outf, "Can not allocate memory for long time MSR.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 	 * Signal handler might be restricted, so use thread notifier instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 	memset(&sev, 0, sizeof(struct sigevent));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) 	sev.sigev_notify = SIGEV_THREAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) 	sev.sigev_notify_function = msr_record_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) 	sev.sigev_value.sival_ptr = &timerid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) 	if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 		fprintf(outf, "Can not create timer.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 		goto release_msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) 	its.it_value.tv_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) 	its.it_value.tv_nsec = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) 	 * A wraparound time has been calculated early.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 	 * Some sources state that the peak power for a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) 	 * microprocessor is usually 1.5 times the TDP rating,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) 	 * use 2 * TDP for safety.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) 	its.it_interval.tv_sec = rapl_joule_counter_range / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 	its.it_interval.tv_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) 	if (timer_settime(timerid, 0, &its, NULL) == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) 		fprintf(outf, "Can not set timer.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) 		goto release_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321)  release_timer:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) 	timer_delete(timerid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323)  release_msr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) 	free(per_cpu_msr_sum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) void turbostat_loop()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) 	int restarted = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) 	int done_iters = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) 	setup_signal_handler();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) restart:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) 	restarted++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) 	snapshot_proc_sysfs_files();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) 	retval = for_all_cpus(get_counters, EVEN_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) 	first_counter_read = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) 	if (retval < -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) 		exit(retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) 	} else if (retval == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) 		if (restarted > 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) 			exit(retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) 		re_initialize();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) 		goto restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) 	restarted = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) 	done_iters = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) 	gettimeofday(&tv_even, (struct timezone *)NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) 		if (for_all_proc_cpus(cpu_is_not_present)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) 			re_initialize();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) 			goto restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) 		do_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) 		if (snapshot_proc_sysfs_files())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) 			goto restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) 		retval = for_all_cpus(get_counters, ODD_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) 		if (retval < -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) 			exit(retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) 		} else if (retval == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) 			re_initialize();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) 			goto restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) 		gettimeofday(&tv_odd, (struct timezone *)NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) 		timersub(&tv_odd, &tv_even, &tv_delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) 		if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) 			re_initialize();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) 			goto restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) 		compute_average(EVEN_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) 		format_all_counters(EVEN_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) 		flush_output_stdout();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) 		if (exit_requested)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) 		if (num_iterations && ++done_iters >= num_iterations)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) 		do_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) 		if (snapshot_proc_sysfs_files())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) 			goto restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) 		retval = for_all_cpus(get_counters, EVEN_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) 		if (retval < -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) 			exit(retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) 		} else if (retval == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) 			re_initialize();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) 			goto restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) 		gettimeofday(&tv_even, (struct timezone *)NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) 		timersub(&tv_even, &tv_odd, &tv_delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) 		if (for_all_cpus_2(delta_cpu, EVEN_COUNTERS, ODD_COUNTERS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) 			re_initialize();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) 			goto restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) 		compute_average(ODD_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) 		format_all_counters(ODD_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) 		flush_output_stdout();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) 		if (exit_requested)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) 		if (num_iterations && ++done_iters >= num_iterations)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) void check_dev_msr()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) 	struct stat sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) 	char pathname[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) 	sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) 	if (stat(pathname, &sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415)  		if (system("/sbin/modprobe msr > /dev/null 2>&1"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) 			err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420)  * check for CAP_SYS_RAWIO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421)  * return 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422)  * return 1 on fail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) int check_for_cap_sys_rawio(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) 	cap_t caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) 	cap_flag_value_t cap_flag_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) 	caps = cap_get_proc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) 	if (caps == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) 		err(-6, "cap_get_proc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) 	if (cap_get_flag(caps, CAP_SYS_RAWIO, CAP_EFFECTIVE, &cap_flag_value))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) 		err(-6, "cap_get\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) 	if (cap_flag_value != CAP_SET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) 		warnx("capget(CAP_SYS_RAWIO) failed,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) 			" try \"# setcap cap_sys_rawio=ep %s\"", progname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) 	if (cap_free(caps) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) 		err(-6, "cap_free\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) void check_permissions(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) 	int do_exit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) 	char pathname[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) 	/* check for CAP_SYS_RAWIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) 	do_exit += check_for_cap_sys_rawio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) 	/* test file permissions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) 	sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) 	if (euidaccess(pathname, R_OK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) 		do_exit++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) 		warn("/dev/cpu/0/msr open failed, try chown or chmod +r /dev/cpu/*/msr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) 	/* if all else fails, thell them to be root */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) 	if (do_exit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) 		if (getuid() != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) 			warnx("... or simply run as root");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) 	if (do_exit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) 		exit(-6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472)  * NHM adds support for additional MSRs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474)  * MSR_SMI_COUNT                   0x00000034
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476)  * MSR_PLATFORM_INFO               0x000000ce
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477)  * MSR_PKG_CST_CONFIG_CONTROL     0x000000e2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479)  * MSR_MISC_PWR_MGMT               0x000001aa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481)  * MSR_PKG_C3_RESIDENCY            0x000003f8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482)  * MSR_PKG_C6_RESIDENCY            0x000003f9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483)  * MSR_CORE_C3_RESIDENCY           0x000003fc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484)  * MSR_CORE_C6_RESIDENCY           0x000003fd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486)  * Side effect:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487)  * sets global pkg_cstate_limit to decode MSR_PKG_CST_CONFIG_CONTROL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488)  * sets has_misc_feature_control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) int probe_nhm_msrs(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) 	unsigned int base_ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) 	int *pkg_cstate_limits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) 	if (family != 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) 	bclk = discover_bclk(family, model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) 	case INTEL_FAM6_NEHALEM:	/* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) 	case INTEL_FAM6_NEHALEM_EX:	/* Nehalem-EX Xeon - Beckton */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) 		pkg_cstate_limits = nhm_pkg_cstate_limits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) 	case INTEL_FAM6_SANDYBRIDGE:	/* SNB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) 	case INTEL_FAM6_SANDYBRIDGE_X:	/* SNB Xeon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) 	case INTEL_FAM6_IVYBRIDGE:	/* IVB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) 	case INTEL_FAM6_IVYBRIDGE_X:	/* IVB Xeon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) 		pkg_cstate_limits = snb_pkg_cstate_limits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) 		has_misc_feature_control = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) 	case INTEL_FAM6_HASWELL:	/* HSW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) 	case INTEL_FAM6_HASWELL_G:	/* HSW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) 	case INTEL_FAM6_HASWELL_X:	/* HSX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) 	case INTEL_FAM6_HASWELL_L:	/* HSW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) 	case INTEL_FAM6_BROADWELL:	/* BDW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) 	case INTEL_FAM6_BROADWELL_G:	/* BDW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) 	case INTEL_FAM6_BROADWELL_X:	/* BDX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) 	case INTEL_FAM6_SKYLAKE_L:	/* SKL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) 	case INTEL_FAM6_CANNONLAKE_L:	/* CNL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) 		pkg_cstate_limits = hsw_pkg_cstate_limits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) 		has_misc_feature_control = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) 	case INTEL_FAM6_SKYLAKE_X:	/* SKX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) 		pkg_cstate_limits = skx_pkg_cstate_limits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) 		has_misc_feature_control = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) 	case INTEL_FAM6_ATOM_SILVERMONT:	/* BYT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) 		no_MSR_MISC_PWR_MGMT = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) 	case INTEL_FAM6_ATOM_SILVERMONT_D:	/* AVN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) 		pkg_cstate_limits = slv_pkg_cstate_limits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) 	case INTEL_FAM6_ATOM_AIRMONT:	/* AMT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) 		pkg_cstate_limits = amt_pkg_cstate_limits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) 		no_MSR_MISC_PWR_MGMT = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) 	case INTEL_FAM6_XEON_PHI_KNL:	/* PHI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) 		pkg_cstate_limits = phi_pkg_cstate_limits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) 	case INTEL_FAM6_ATOM_GOLDMONT:	/* BXT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) 	case INTEL_FAM6_ATOM_GOLDMONT_PLUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) 	case INTEL_FAM6_ATOM_GOLDMONT_D:	/* DNV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) 	case INTEL_FAM6_ATOM_TREMONT:	/* EHL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) 	case INTEL_FAM6_ATOM_TREMONT_D: /* JVL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) 		pkg_cstate_limits = glm_pkg_cstate_limits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) 	get_msr(base_cpu, MSR_PKG_CST_CONFIG_CONTROL, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) 	pkg_cstate_limit = pkg_cstate_limits[msr & 0xF];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) 	get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) 	base_ratio = (msr >> 8) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) 	base_hz = base_ratio * bclk * 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) 	has_base_hz = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565)  * SLV client has support for unique MSRs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567)  * MSR_CC6_DEMOTION_POLICY_CONFIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568)  * MSR_MC6_DEMOTION_POLICY_CONFIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) int has_slv_msrs(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) 	case INTEL_FAM6_ATOM_SILVERMONT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) 	case INTEL_FAM6_ATOM_SILVERMONT_MID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) 	case INTEL_FAM6_ATOM_AIRMONT_MID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) int is_dnv(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) 	case INTEL_FAM6_ATOM_GOLDMONT_D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) int is_bdx(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) 	case INTEL_FAM6_BROADWELL_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) int is_skx(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) 	case INTEL_FAM6_SKYLAKE_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) int is_ehl(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) 	case INTEL_FAM6_ATOM_TREMONT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) int is_jvl(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) 	case INTEL_FAM6_ATOM_TREMONT_D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) int has_turbo_ratio_limit(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) 	if (has_slv_msrs(family, model))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) 	/* Nehalem compatible, but do not include turbo-ratio limit support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) 	case INTEL_FAM6_NEHALEM_EX:	/* Nehalem-EX Xeon - Beckton */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) 	case INTEL_FAM6_XEON_PHI_KNL:	/* PHI - Knights Landing (different MSR definition) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) int has_atom_turbo_ratio_limit(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) 	if (has_slv_msrs(family, model))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) 	if (family != 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) 	case INTEL_FAM6_IVYBRIDGE_X:	/* IVB Xeon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) 	case INTEL_FAM6_HASWELL_X:	/* HSW Xeon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) int has_hsw_turbo_ratio_limit(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) 	if (family != 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) 	case INTEL_FAM6_HASWELL_X:	/* HSW Xeon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) int has_knl_turbo_ratio_limit(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) 	if (family != 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) 	case INTEL_FAM6_XEON_PHI_KNL:	/* Knights Landing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) int has_glm_turbo_ratio_limit(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) 	if (family != 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) 	case INTEL_FAM6_ATOM_GOLDMONT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) 	case INTEL_FAM6_SKYLAKE_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) int has_config_tdp(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) 	if (family != 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) 	case INTEL_FAM6_IVYBRIDGE:	/* IVB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) 	case INTEL_FAM6_HASWELL:	/* HSW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) 	case INTEL_FAM6_HASWELL_X:	/* HSX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) 	case INTEL_FAM6_HASWELL_L:	/* HSW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) 	case INTEL_FAM6_HASWELL_G:	/* HSW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) 	case INTEL_FAM6_BROADWELL:	/* BDW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) 	case INTEL_FAM6_BROADWELL_G:	/* BDW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) 	case INTEL_FAM6_BROADWELL_X:	/* BDX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) 	case INTEL_FAM6_SKYLAKE_L:	/* SKL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) 	case INTEL_FAM6_CANNONLAKE_L:	/* CNL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) 	case INTEL_FAM6_SKYLAKE_X:	/* SKX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) 	case INTEL_FAM6_XEON_PHI_KNL:	/* Knights Landing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) remove_underbar(char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) 	char *to = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) 	while (*s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) 		if (*s != '_')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) 			*to++ = *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) 		s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) 	*to = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) dump_cstate_pstate_config_info(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) 	if (!do_nhm_platform_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) 	dump_nhm_platform_info();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) 	if (has_hsw_turbo_ratio_limit(family, model))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) 		dump_hsw_turbo_ratio_limits();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) 	if (has_ivt_turbo_ratio_limit(family, model))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) 		dump_ivt_turbo_ratio_limits();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) 	if (has_turbo_ratio_limit(family, model))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) 		dump_turbo_ratio_limits(family, model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) 	if (has_atom_turbo_ratio_limit(family, model))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) 		dump_atom_turbo_ratio_limits();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) 	if (has_knl_turbo_ratio_limit(family, model))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) 		dump_knl_turbo_ratio_limits();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) 	if (has_config_tdp(family, model))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) 		dump_config_tdp();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) 	dump_nhm_cst_cfg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) static void dump_sysfs_file(char *path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) 	FILE *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) 	char cpuidle_buf[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) 	input = fopen(path, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) 	if (input == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) 		if (debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) 			fprintf(outf, "NSFOD %s\n", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) 	if (!fgets(cpuidle_buf, sizeof(cpuidle_buf), input))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) 		err(1, "%s: failed to read file", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) 	fclose(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) 	fprintf(outf, "%s: %s", strrchr(path, '/') + 1, cpuidle_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) dump_sysfs_cstate_config(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) 	char path[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) 	char name_buf[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) 	char desc[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) 	FILE *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) 	int state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) 	char *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) 	if (access("/sys/devices/system/cpu/cpuidle", R_OK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) 		fprintf(outf, "cpuidle not loaded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) 	dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) 	dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_governor");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) 	dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_governor_ro");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) 	for (state = 0; state < 10; ++state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) 		sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) 			base_cpu, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) 		input = fopen(path, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) 		if (input == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) 		if (!fgets(name_buf, sizeof(name_buf), input))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) 			err(1, "%s: failed to read file", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) 		 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) 		sp = strchr(name_buf, '-');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) 		if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) 			sp = strchrnul(name_buf, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) 		*sp = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) 		fclose(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) 		remove_underbar(name_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) 		sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/desc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) 			base_cpu, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) 		input = fopen(path, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) 		if (input == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) 		if (!fgets(desc, sizeof(desc), input))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) 			err(1, "%s: failed to read file", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) 		fprintf(outf, "cpu%d: %s: %s", base_cpu, name_buf, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) 		fclose(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) dump_sysfs_pstate_config(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) 	char path[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) 	char driver_buf[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) 	char governor_buf[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) 	FILE *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) 	int turbo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) 	sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_driver",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) 			base_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) 	input = fopen(path, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) 	if (input == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) 		fprintf(outf, "NSFOD %s\n", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) 	if (!fgets(driver_buf, sizeof(driver_buf), input))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) 		err(1, "%s: failed to read file", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) 	fclose(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) 	sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) 			base_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) 	input = fopen(path, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) 	if (input == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) 		fprintf(outf, "NSFOD %s\n", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) 	if (!fgets(governor_buf, sizeof(governor_buf), input))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) 		err(1, "%s: failed to read file", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) 	fclose(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) 	fprintf(outf, "cpu%d: cpufreq driver: %s", base_cpu, driver_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) 	fprintf(outf, "cpu%d: cpufreq governor: %s", base_cpu, governor_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) 	sprintf(path, "/sys/devices/system/cpu/cpufreq/boost");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) 	input = fopen(path, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) 	if (input != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) 		if (fscanf(input, "%d", &turbo) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) 			err(1, "%s: failed to parse number from file", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) 		fprintf(outf, "cpufreq boost: %d\n", turbo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) 		fclose(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) 	sprintf(path, "/sys/devices/system/cpu/intel_pstate/no_turbo");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) 	input = fopen(path, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) 	if (input != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) 		if (fscanf(input, "%d", &turbo) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) 			err(1, "%s: failed to parse number from file", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) 		fprintf(outf, "cpufreq intel_pstate no_turbo: %d\n", turbo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) 		fclose(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920)  * print_epb()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921)  * Decode the ENERGY_PERF_BIAS MSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) 	char *epb_string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) 	int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) 	if (!has_epb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) 	cpu = t->cpu_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) 	/* EPB is per-package */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) 	if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) 	if (cpu_migrate(cpu)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) 		fprintf(outf, "print_epb: Could not migrate to CPU %d\n", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) 	if (get_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) 	switch (msr & 0xF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) 	case ENERGY_PERF_BIAS_PERFORMANCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) 		epb_string = "performance";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) 	case ENERGY_PERF_BIAS_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) 		epb_string = "balanced";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) 	case ENERGY_PERF_BIAS_POWERSAVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) 		epb_string = "powersave";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) 		epb_string = "custom";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) 	fprintf(outf, "cpu%d: MSR_IA32_ENERGY_PERF_BIAS: 0x%08llx (%s)\n", cpu, msr, epb_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965)  * print_hwp()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966)  * Decode the MSR_HWP_CAPABILITIES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) 	int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) 	if (!has_hwp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) 	cpu = t->cpu_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) 	/* MSR_HWP_CAPABILITIES is per-package */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) 	if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) 	if (cpu_migrate(cpu)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) 		fprintf(outf, "print_hwp: Could not migrate to CPU %d\n", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) 	if (get_msr(cpu, MSR_PM_ENABLE, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) 	fprintf(outf, "cpu%d: MSR_PM_ENABLE: 0x%08llx (%sHWP)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) 		cpu, msr, (msr & (1 << 0)) ? "" : "No-");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) 	/* MSR_PM_ENABLE[1] == 1 if HWP is enabled and MSRs visible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) 	if ((msr & (1 << 0)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) 	if (get_msr(cpu, MSR_HWP_CAPABILITIES, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) 	fprintf(outf, "cpu%d: MSR_HWP_CAPABILITIES: 0x%08llx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) 			"(high %d guar %d eff %d low %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) 			cpu, msr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) 			(unsigned int)HWP_HIGHEST_PERF(msr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) 			(unsigned int)HWP_GUARANTEED_PERF(msr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) 			(unsigned int)HWP_MOSTEFFICIENT_PERF(msr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) 			(unsigned int)HWP_LOWEST_PERF(msr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) 	if (get_msr(cpu, MSR_HWP_REQUEST, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) 	fprintf(outf, "cpu%d: MSR_HWP_REQUEST: 0x%08llx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) 			"(min %d max %d des %d epp 0x%x window 0x%x pkg 0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) 			cpu, msr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) 			(unsigned int)(((msr) >> 0) & 0xff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) 			(unsigned int)(((msr) >> 8) & 0xff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) 			(unsigned int)(((msr) >> 16) & 0xff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) 			(unsigned int)(((msr) >> 24) & 0xff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) 			(unsigned int)(((msr) >> 32) & 0xff3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) 			(unsigned int)(((msr) >> 42) & 0x1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) 	if (has_hwp_pkg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) 		if (get_msr(cpu, MSR_HWP_REQUEST_PKG, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) 		fprintf(outf, "cpu%d: MSR_HWP_REQUEST_PKG: 0x%08llx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) 			"(min %d max %d des %d epp 0x%x window 0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) 			cpu, msr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) 			(unsigned int)(((msr) >> 0) & 0xff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) 			(unsigned int)(((msr) >> 8) & 0xff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) 			(unsigned int)(((msr) >> 16) & 0xff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) 			(unsigned int)(((msr) >> 24) & 0xff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) 			(unsigned int)(((msr) >> 32) & 0xff3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) 	if (has_hwp_notify) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) 		if (get_msr(cpu, MSR_HWP_INTERRUPT, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) 		fprintf(outf, "cpu%d: MSR_HWP_INTERRUPT: 0x%08llx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) 			"(%s_Guaranteed_Perf_Change, %s_Excursion_Min)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) 			cpu, msr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) 			((msr) & 0x1) ? "EN" : "Dis",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) 			((msr) & 0x2) ? "EN" : "Dis");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) 	if (get_msr(cpu, MSR_HWP_STATUS, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) 	fprintf(outf, "cpu%d: MSR_HWP_STATUS: 0x%08llx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) 			"(%sGuaranteed_Perf_Change, %sExcursion_Min)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) 			cpu, msr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) 			((msr) & 0x1) ? "" : "No-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) 			((msr) & 0x2) ? "" : "No-");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057)  * print_perf_limit()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) 	int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) 	cpu = t->cpu_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) 	/* per-package */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) 	if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) 	if (cpu_migrate(cpu)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) 		fprintf(outf, "print_perf_limit: Could not migrate to CPU %d\n", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) 	if (do_core_perf_limit_reasons) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) 		get_msr(cpu, MSR_CORE_PERF_LIMIT_REASONS, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) 		fprintf(outf, "cpu%d: MSR_CORE_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) 		fprintf(outf, " (Active: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) 			(msr & 1 << 15) ? "bit15, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) 			(msr & 1 << 14) ? "bit14, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) 			(msr & 1 << 13) ? "Transitions, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) 			(msr & 1 << 12) ? "MultiCoreTurbo, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) 			(msr & 1 << 11) ? "PkgPwrL2, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) 			(msr & 1 << 10) ? "PkgPwrL1, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) 			(msr & 1 << 9) ? "CorePwr, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) 			(msr & 1 << 8) ? "Amps, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) 			(msr & 1 << 6) ? "VR-Therm, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) 			(msr & 1 << 5) ? "Auto-HWP, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) 			(msr & 1 << 4) ? "Graphics, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) 			(msr & 1 << 2) ? "bit2, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) 			(msr & 1 << 1) ? "ThermStatus, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) 			(msr & 1 << 0) ? "PROCHOT, " : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) 		fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) 			(msr & 1 << 31) ? "bit31, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) 			(msr & 1 << 30) ? "bit30, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) 			(msr & 1 << 29) ? "Transitions, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) 			(msr & 1 << 28) ? "MultiCoreTurbo, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) 			(msr & 1 << 27) ? "PkgPwrL2, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) 			(msr & 1 << 26) ? "PkgPwrL1, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) 			(msr & 1 << 25) ? "CorePwr, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) 			(msr & 1 << 24) ? "Amps, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) 			(msr & 1 << 22) ? "VR-Therm, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) 			(msr & 1 << 21) ? "Auto-HWP, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) 			(msr & 1 << 20) ? "Graphics, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) 			(msr & 1 << 18) ? "bit18, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) 			(msr & 1 << 17) ? "ThermStatus, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) 			(msr & 1 << 16) ? "PROCHOT, " : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) 	if (do_gfx_perf_limit_reasons) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) 		get_msr(cpu, MSR_GFX_PERF_LIMIT_REASONS, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) 		fprintf(outf, "cpu%d: MSR_GFX_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) 		fprintf(outf, " (Active: %s%s%s%s%s%s%s%s)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) 			(msr & 1 << 0) ? "PROCHOT, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) 			(msr & 1 << 1) ? "ThermStatus, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) 			(msr & 1 << 4) ? "Graphics, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) 			(msr & 1 << 6) ? "VR-Therm, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) 			(msr & 1 << 8) ? "Amps, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) 			(msr & 1 << 9) ? "GFXPwr, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) 			(msr & 1 << 10) ? "PkgPwrL1, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) 			(msr & 1 << 11) ? "PkgPwrL2, " : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) 		fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) 			(msr & 1 << 16) ? "PROCHOT, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) 			(msr & 1 << 17) ? "ThermStatus, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) 			(msr & 1 << 20) ? "Graphics, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) 			(msr & 1 << 22) ? "VR-Therm, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) 			(msr & 1 << 24) ? "Amps, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) 			(msr & 1 << 25) ? "GFXPwr, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) 			(msr & 1 << 26) ? "PkgPwrL1, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) 			(msr & 1 << 27) ? "PkgPwrL2, " : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) 	if (do_ring_perf_limit_reasons) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) 		get_msr(cpu, MSR_RING_PERF_LIMIT_REASONS, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) 		fprintf(outf, "cpu%d: MSR_RING_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) 		fprintf(outf, " (Active: %s%s%s%s%s%s)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) 			(msr & 1 << 0) ? "PROCHOT, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) 			(msr & 1 << 1) ? "ThermStatus, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) 			(msr & 1 << 6) ? "VR-Therm, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) 			(msr & 1 << 8) ? "Amps, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) 			(msr & 1 << 10) ? "PkgPwrL1, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) 			(msr & 1 << 11) ? "PkgPwrL2, " : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) 		fprintf(outf, " (Logged: %s%s%s%s%s%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) 			(msr & 1 << 16) ? "PROCHOT, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) 			(msr & 1 << 17) ? "ThermStatus, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) 			(msr & 1 << 22) ? "VR-Therm, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) 			(msr & 1 << 24) ? "Amps, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) 			(msr & 1 << 26) ? "PkgPwrL1, " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) 			(msr & 1 << 27) ? "PkgPwrL2, " : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) #define	RAPL_POWER_GRANULARITY	0x7FFF	/* 15 bit power granularity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) #define	RAPL_TIME_GRANULARITY	0x3F /* 6 bit time granularity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) double get_tdp_intel(unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) 	if (do_rapl & RAPL_PKG_POWER_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) 		if (!get_msr(base_cpu, MSR_PKG_POWER_INFO, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) 			return ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) 	case INTEL_FAM6_ATOM_SILVERMONT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) 	case INTEL_FAM6_ATOM_SILVERMONT_D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) 		return 30.0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) 		return 135.0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) double get_tdp_amd(unsigned int family)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) 	/* This is the max stock TDP of HEDT/Server Fam17h+ chips */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) 	return 280.0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180)  * rapl_dram_energy_units_probe()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181)  * Energy units are either hard-coded, or come from RAPL Energy Unit MSR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) static double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) rapl_dram_energy_units_probe(int  model, double rapl_energy_units)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) 	/* only called for genuine_intel, family 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) 	case INTEL_FAM6_HASWELL_X:	/* HSX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) 	case INTEL_FAM6_BROADWELL_X:	/* BDX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) 	case INTEL_FAM6_XEON_PHI_KNL:	/* KNL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) 		return (rapl_dram_energy_units = 15.3 / 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) 		return (rapl_energy_units);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) void rapl_probe_intel(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) 	unsigned int time_unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) 	double tdp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) 	if (family != 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) 	case INTEL_FAM6_SANDYBRIDGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) 	case INTEL_FAM6_IVYBRIDGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) 	case INTEL_FAM6_HASWELL:	/* HSW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) 	case INTEL_FAM6_HASWELL_L:	/* HSW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) 	case INTEL_FAM6_HASWELL_G:	/* HSW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) 	case INTEL_FAM6_BROADWELL:	/* BDW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) 	case INTEL_FAM6_BROADWELL_G:	/* BDW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) 		do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) 		if (rapl_joules) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) 			BIC_PRESENT(BIC_Pkg_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) 			BIC_PRESENT(BIC_Cor_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) 			BIC_PRESENT(BIC_GFX_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) 			BIC_PRESENT(BIC_PkgWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) 			BIC_PRESENT(BIC_CorWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) 			BIC_PRESENT(BIC_GFXWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) 	case INTEL_FAM6_ATOM_GOLDMONT:	/* BXT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) 	case INTEL_FAM6_ATOM_GOLDMONT_PLUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) 		do_rapl = RAPL_PKG | RAPL_PKG_POWER_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) 		if (rapl_joules)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) 			BIC_PRESENT(BIC_Pkg_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) 			BIC_PRESENT(BIC_PkgWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) 	case INTEL_FAM6_ATOM_TREMONT:	/* EHL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) 		do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_GFX | RAPL_PKG_POWER_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) 		if (rapl_joules) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) 			BIC_PRESENT(BIC_Pkg_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) 			BIC_PRESENT(BIC_Cor_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) 			BIC_PRESENT(BIC_RAM_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) 			BIC_PRESENT(BIC_GFX_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) 			BIC_PRESENT(BIC_PkgWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) 			BIC_PRESENT(BIC_CorWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) 			BIC_PRESENT(BIC_RAMWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) 			BIC_PRESENT(BIC_GFXWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) 	case INTEL_FAM6_ATOM_TREMONT_D:	/* JVL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) 		do_rapl = RAPL_PKG | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) 		BIC_PRESENT(BIC_PKG__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) 		if (rapl_joules)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) 			BIC_PRESENT(BIC_Pkg_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) 			BIC_PRESENT(BIC_PkgWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) 	case INTEL_FAM6_SKYLAKE_L:	/* SKL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) 	case INTEL_FAM6_CANNONLAKE_L:	/* CNL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) 		do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_GFX | RAPL_PKG_POWER_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) 		BIC_PRESENT(BIC_PKG__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) 		BIC_PRESENT(BIC_RAM__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) 		if (rapl_joules) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) 			BIC_PRESENT(BIC_Pkg_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) 			BIC_PRESENT(BIC_Cor_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) 			BIC_PRESENT(BIC_RAM_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) 			BIC_PRESENT(BIC_GFX_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) 			BIC_PRESENT(BIC_PkgWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) 			BIC_PRESENT(BIC_CorWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) 			BIC_PRESENT(BIC_RAMWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) 			BIC_PRESENT(BIC_GFXWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) 	case INTEL_FAM6_HASWELL_X:	/* HSX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) 	case INTEL_FAM6_BROADWELL_X:	/* BDX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) 	case INTEL_FAM6_SKYLAKE_X:	/* SKX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) 	case INTEL_FAM6_XEON_PHI_KNL:	/* KNL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) 		do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) 		BIC_PRESENT(BIC_PKG__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) 		BIC_PRESENT(BIC_RAM__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) 		if (rapl_joules) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) 			BIC_PRESENT(BIC_Pkg_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) 			BIC_PRESENT(BIC_RAM_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) 			BIC_PRESENT(BIC_PkgWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) 			BIC_PRESENT(BIC_RAMWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) 	case INTEL_FAM6_SANDYBRIDGE_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) 	case INTEL_FAM6_IVYBRIDGE_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) 		do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_PKG_PERF_STATUS | RAPL_DRAM_PERF_STATUS | RAPL_PKG_POWER_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) 		BIC_PRESENT(BIC_PKG__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) 		BIC_PRESENT(BIC_RAM__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) 		if (rapl_joules) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) 			BIC_PRESENT(BIC_Pkg_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) 			BIC_PRESENT(BIC_Cor_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) 			BIC_PRESENT(BIC_RAM_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) 			BIC_PRESENT(BIC_PkgWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) 			BIC_PRESENT(BIC_CorWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) 			BIC_PRESENT(BIC_RAMWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) 	case INTEL_FAM6_ATOM_SILVERMONT:	/* BYT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) 	case INTEL_FAM6_ATOM_SILVERMONT_D:	/* AVN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) 		do_rapl = RAPL_PKG | RAPL_CORES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) 		if (rapl_joules) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) 			BIC_PRESENT(BIC_Pkg_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) 			BIC_PRESENT(BIC_Cor_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) 			BIC_PRESENT(BIC_PkgWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) 			BIC_PRESENT(BIC_CorWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) 	case INTEL_FAM6_ATOM_GOLDMONT_D:	/* DNV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) 		do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO | RAPL_CORES_ENERGY_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) 		BIC_PRESENT(BIC_PKG__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) 		BIC_PRESENT(BIC_RAM__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) 		if (rapl_joules) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) 			BIC_PRESENT(BIC_Pkg_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) 			BIC_PRESENT(BIC_Cor_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) 			BIC_PRESENT(BIC_RAM_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) 			BIC_PRESENT(BIC_PkgWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) 			BIC_PRESENT(BIC_CorWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) 			BIC_PRESENT(BIC_RAMWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) 	/* units on package 0, verify later other packages match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) 	if (get_msr(base_cpu, MSR_RAPL_POWER_UNIT, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) 	rapl_power_units = 1.0 / (1 << (msr & 0xF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) 	if (model == INTEL_FAM6_ATOM_SILVERMONT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) 		rapl_energy_units = 1.0 * (1 << (msr >> 8 & 0x1F)) / 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) 		rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) 	rapl_dram_energy_units = rapl_dram_energy_units_probe(model, rapl_energy_units);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) 	time_unit = msr >> 16 & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) 	if (time_unit == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) 		time_unit = 0xA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) 	rapl_time_units = 1.0 / (1 << (time_unit));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) 	tdp = get_tdp_intel(model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) 	rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) 	if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) 		fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) void rapl_probe_amd(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) 	unsigned int eax, ebx, ecx, edx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) 	unsigned int has_rapl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) 	double tdp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) 	if (max_extended_level >= 0x80000007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) 		__cpuid(0x80000007, eax, ebx, ecx, edx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) 		/* RAPL (Fam 17h+) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) 		has_rapl = edx & (1 << 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) 	if (!has_rapl || family < 0x17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) 	do_rapl = RAPL_AMD_F17H | RAPL_PER_CORE_ENERGY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) 	if (rapl_joules) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) 		BIC_PRESENT(BIC_Pkg_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) 		BIC_PRESENT(BIC_Cor_J);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) 		BIC_PRESENT(BIC_PkgWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) 		BIC_PRESENT(BIC_CorWatt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) 	if (get_msr(base_cpu, MSR_RAPL_PWR_UNIT, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) 	rapl_time_units = ldexp(1.0, -(msr >> 16 & 0xf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) 	rapl_energy_units = ldexp(1.0, -(msr >> 8 & 0x1f));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) 	rapl_power_units = ldexp(1.0, -(msr & 0xf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) 	tdp = get_tdp_amd(family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) 	rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) 	if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) 		fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397)  * rapl_probe()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399)  * sets do_rapl, rapl_power_units, rapl_energy_units, rapl_time_units
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) void rapl_probe(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) 	if (genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) 		rapl_probe_intel(family, model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) 	if (authentic_amd || hygon_genuine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) 		rapl_probe_amd(family, model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) void perf_limit_reasons_probe(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) 	if (family != 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) 	case INTEL_FAM6_HASWELL:	/* HSW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) 	case INTEL_FAM6_HASWELL_L:	/* HSW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) 	case INTEL_FAM6_HASWELL_G:	/* HSW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) 		do_gfx_perf_limit_reasons = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) 	case INTEL_FAM6_HASWELL_X:	/* HSX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) 		do_core_perf_limit_reasons = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) 		do_ring_perf_limit_reasons = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) void automatic_cstate_conversion_probe(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) 	if (is_skx(family, model) || is_bdx(family, model))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) 		has_automatic_cstate_conversion = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) 	unsigned int dts, dts2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) 	int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) 	if (!(do_dts || do_ptm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) 	cpu = t->cpu_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) 	/* DTS is per-core, no need to print for each thread */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) 	if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) 	if (cpu_migrate(cpu)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) 		fprintf(outf, "print_thermal: Could not migrate to CPU %d\n", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) 	if (do_ptm && (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) 		if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) 		dts = (msr >> 16) & 0x7F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) 		fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_STATUS: 0x%08llx (%d C)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) 			cpu, msr, tcc_activation_temp - dts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) 		if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) 		dts = (msr >> 16) & 0x7F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) 		dts2 = (msr >> 8) & 0x7F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) 		fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) 			cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) 	if (do_dts && debug) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) 		unsigned int resolution;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) 		if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) 		dts = (msr >> 16) & 0x7F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) 		resolution = (msr >> 27) & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) 		fprintf(outf, "cpu%d: MSR_IA32_THERM_STATUS: 0x%08llx (%d C +/- %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) 			cpu, msr, tcc_activation_temp - dts, resolution);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) 		if (get_msr(cpu, MSR_IA32_THERM_INTERRUPT, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) 		dts = (msr >> 16) & 0x7F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) 		dts2 = (msr >> 8) & 0x7F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) 		fprintf(outf, "cpu%d: MSR_IA32_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) 			cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) void print_power_limit_msr(int cpu, unsigned long long msr, char *label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) 	fprintf(outf, "cpu%d: %s: %sabled (%f Watts, %f sec, clamp %sabled)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) 		cpu, label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) 		((msr >> 15) & 1) ? "EN" : "DIS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) 		((msr >> 0) & 0x7FFF) * rapl_power_units,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) 		(1.0 + (((msr >> 22) & 0x3)/4.0)) * (1 << ((msr >> 17) & 0x1F)) * rapl_time_units,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) 		(((msr >> 16) & 1) ? "EN" : "DIS"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) 	const char *msr_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) 	int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) 	if (!do_rapl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) 	/* RAPL counters are per package, so print only for 1st thread/package */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) 	if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) 	cpu = t->cpu_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) 	if (cpu_migrate(cpu)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) 		fprintf(outf, "print_rapl: Could not migrate to CPU %d\n", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) 	if (do_rapl & RAPL_AMD_F17H) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) 		msr_name = "MSR_RAPL_PWR_UNIT";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) 		if (get_msr(cpu, MSR_RAPL_PWR_UNIT, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) 		msr_name = "MSR_RAPL_POWER_UNIT";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) 		if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) 	fprintf(outf, "cpu%d: %s: 0x%08llx (%f Watts, %f Joules, %f sec.)\n", cpu, msr_name, msr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) 		rapl_power_units, rapl_energy_units, rapl_time_units);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) 	if (do_rapl & RAPL_PKG_POWER_INFO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) 		if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544)                 	return -5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) 		fprintf(outf, "cpu%d: MSR_PKG_POWER_INFO: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) 			cpu, msr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) 			((msr >>  0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) 			((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) 			((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) 			((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) 	if (do_rapl & RAPL_PKG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) 		if (get_msr(cpu, MSR_PKG_POWER_LIMIT, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) 			return -9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) 		fprintf(outf, "cpu%d: MSR_PKG_POWER_LIMIT: 0x%08llx (%slocked)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) 			cpu, msr, (msr >> 63) & 1 ? "" : "UN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) 		print_power_limit_msr(cpu, msr, "PKG Limit #1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) 		fprintf(outf, "cpu%d: PKG Limit #2: %sabled (%f Watts, %f* sec, clamp %sabled)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) 			cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) 			((msr >> 47) & 1) ? "EN" : "DIS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) 			((msr >> 32) & 0x7FFF) * rapl_power_units,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) 			(1.0 + (((msr >> 54) & 0x3)/4.0)) * (1 << ((msr >> 49) & 0x1F)) * rapl_time_units,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) 			((msr >> 48) & 1) ? "EN" : "DIS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) 	if (do_rapl & RAPL_DRAM_POWER_INFO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) 		if (get_msr(cpu, MSR_DRAM_POWER_INFO, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574)                 	return -6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) 		fprintf(outf, "cpu%d: MSR_DRAM_POWER_INFO,: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) 			cpu, msr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) 			((msr >>  0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) 			((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) 			((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) 			((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) 	if (do_rapl & RAPL_DRAM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) 		if (get_msr(cpu, MSR_DRAM_POWER_LIMIT, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) 			return -9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) 		fprintf(outf, "cpu%d: MSR_DRAM_POWER_LIMIT: 0x%08llx (%slocked)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) 				cpu, msr, (msr >> 31) & 1 ? "" : "UN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) 		print_power_limit_msr(cpu, msr, "DRAM Limit");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) 	if (do_rapl & RAPL_CORE_POLICY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) 		if (get_msr(cpu, MSR_PP0_POLICY, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) 			return -7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) 		fprintf(outf, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) 	if (do_rapl & RAPL_CORES_POWER_LIMIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) 		if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) 			return -9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) 		fprintf(outf, "cpu%d: MSR_PP0_POWER_LIMIT: 0x%08llx (%slocked)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) 				cpu, msr, (msr >> 31) & 1 ? "" : "UN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) 		print_power_limit_msr(cpu, msr, "Cores Limit");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) 	if (do_rapl & RAPL_GFX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) 		if (get_msr(cpu, MSR_PP1_POLICY, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) 			return -8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) 		fprintf(outf, "cpu%d: MSR_PP1_POLICY: %lld\n", cpu, msr & 0xF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) 		if (get_msr(cpu, MSR_PP1_POWER_LIMIT, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) 			return -9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) 		fprintf(outf, "cpu%d: MSR_PP1_POWER_LIMIT: 0x%08llx (%slocked)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) 				cpu, msr, (msr >> 31) & 1 ? "" : "UN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) 		print_power_limit_msr(cpu, msr, "GFX Limit");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620)  * SNB adds support for additional MSRs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622)  * MSR_PKG_C7_RESIDENCY            0x000003fa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623)  * MSR_CORE_C7_RESIDENCY           0x000003fe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624)  * MSR_PKG_C2_RESIDENCY            0x0000060d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) int has_snb_msrs(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) 	case INTEL_FAM6_SANDYBRIDGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) 	case INTEL_FAM6_SANDYBRIDGE_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) 	case INTEL_FAM6_IVYBRIDGE:		/* IVB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) 	case INTEL_FAM6_IVYBRIDGE_X:		/* IVB Xeon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) 	case INTEL_FAM6_HASWELL:		/* HSW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) 	case INTEL_FAM6_HASWELL_X:		/* HSW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) 	case INTEL_FAM6_HASWELL_L:		/* HSW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) 	case INTEL_FAM6_HASWELL_G:		/* HSW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) 	case INTEL_FAM6_BROADWELL:		/* BDW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) 	case INTEL_FAM6_BROADWELL_G:		/* BDW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) 	case INTEL_FAM6_BROADWELL_X:		/* BDX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) 	case INTEL_FAM6_SKYLAKE_L:		/* SKL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) 	case INTEL_FAM6_CANNONLAKE_L:		/* CNL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) 	case INTEL_FAM6_SKYLAKE_X:		/* SKX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) 	case INTEL_FAM6_ATOM_GOLDMONT:		/* BXT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) 	case INTEL_FAM6_ATOM_GOLDMONT_PLUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) 	case INTEL_FAM6_ATOM_GOLDMONT_D:	/* DNV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) 	case INTEL_FAM6_ATOM_TREMONT:		/* EHL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) 	case INTEL_FAM6_ATOM_TREMONT_D:		/* JVL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658)  * HSW ULT added support for C8/C9/C10 MSRs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660)  * MSR_PKG_C8_RESIDENCY		0x00000630
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661)  * MSR_PKG_C9_RESIDENCY		0x00000631
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662)  * MSR_PKG_C10_RESIDENCY	0x00000632
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664)  * MSR_PKGC8_IRTL		0x00000633
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665)  * MSR_PKGC9_IRTL		0x00000634
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666)  * MSR_PKGC10_IRTL		0x00000635
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) int has_c8910_msrs(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) 	case INTEL_FAM6_HASWELL_L:	/* HSW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) 	case INTEL_FAM6_BROADWELL:	/* BDW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) 	case INTEL_FAM6_SKYLAKE_L:	/* SKL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) 	case INTEL_FAM6_CANNONLAKE_L:	/* CNL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) 	case INTEL_FAM6_ATOM_GOLDMONT:	/* BXT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) 	case INTEL_FAM6_ATOM_GOLDMONT_PLUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) 	case INTEL_FAM6_ATOM_TREMONT:	/* EHL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688)  * SKL adds support for additional MSRS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690)  * MSR_PKG_WEIGHTED_CORE_C0_RES    0x00000658
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691)  * MSR_PKG_ANY_CORE_C0_RES         0x00000659
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692)  * MSR_PKG_ANY_GFXE_C0_RES         0x0000065A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693)  * MSR_PKG_BOTH_CORE_GFXE_C0_RES   0x0000065B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) int has_skl_msrs(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) 	case INTEL_FAM6_SKYLAKE_L:	/* SKL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) 	case INTEL_FAM6_CANNONLAKE_L:	/* CNL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) int is_slm(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) 	case INTEL_FAM6_ATOM_SILVERMONT:	/* BYT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) 	case INTEL_FAM6_ATOM_SILVERMONT_D:	/* AVN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) int is_knl(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) 	case INTEL_FAM6_XEON_PHI_KNL:	/* KNL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) int is_cnl(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) 	switch (model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) 	case INTEL_FAM6_CANNONLAKE_L: /* CNL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) unsigned int get_aperf_mperf_multiplier(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) 	if (is_knl(family, model))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) 		return 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) #define SLM_BCLK_FREQS 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) double slm_freq_table[SLM_BCLK_FREQS] = { 83.3, 100.0, 133.3, 116.7, 80.0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) double slm_bclk(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) 	unsigned long long msr = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) 	double freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) 	if (get_msr(base_cpu, MSR_FSB_FREQ, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761) 		fprintf(outf, "SLM BCLK: unknown\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) 	i = msr & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) 	if (i >= SLM_BCLK_FREQS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) 		fprintf(outf, "SLM BCLK[%d] invalid\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) 		i = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) 	freq = slm_freq_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) 	if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) 		fprintf(outf, "SLM BCLK: %.1f Mhz\n", freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) 	return freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) double discover_bclk(unsigned int family, unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) 	if (has_snb_msrs(family, model) || is_knl(family, model))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) 		return 100.00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) 	else if (is_slm(family, model))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) 		return slm_bclk();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) 		return 133.33;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787)  * MSR_IA32_TEMPERATURE_TARGET indicates the temperature where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788)  * the Thermal Control Circuit (TCC) activates.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789)  * This is usually equal to tjMax.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791)  * Older processors do not have this MSR, so there we guess,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792)  * but also allow cmdline over-ride with -T.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794)  * Several MSR temperature values are in units of degrees-C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795)  * below this value, including the Digital Thermal Sensor (DTS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796)  * Package Thermal Management Sensor (PTM), and thermal event thresholds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) int set_temperature_target(struct thread_data *t, struct core_data *c, struct pkg_data *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) 	unsigned int target_c_local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) 	int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) 	/* tcc_activation_temp is used only for dts or ptm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) 	if (!(do_dts || do_ptm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) 	/* this is a per-package concept */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) 	if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) 	cpu = t->cpu_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) 	if (cpu_migrate(cpu)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) 		fprintf(outf, "Could not migrate to CPU %d\n", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) 	if (tcc_activation_temp_override != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) 		tcc_activation_temp = tcc_activation_temp_override;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) 		fprintf(outf, "cpu%d: Using cmdline TCC Target (%d C)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) 			cpu, tcc_activation_temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) 	/* Temperature Target MSR is Nehalem and newer only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) 	if (!do_nhm_platform_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) 		goto guess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) 	if (get_msr(base_cpu, MSR_IA32_TEMPERATURE_TARGET, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) 		goto guess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) 	target_c_local = (msr >> 16) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) 	if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) 		fprintf(outf, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) 			cpu, msr, target_c_local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) 	if (!target_c_local)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) 		goto guess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) 	tcc_activation_temp = target_c_local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) guess:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) 	tcc_activation_temp = TJMAX_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) 	fprintf(outf, "cpu%d: Guessing tjMax %d C, Please use -T to specify\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) 		cpu, tcc_activation_temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) void decode_feature_control_msr(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) 	if (!get_msr(base_cpu, MSR_IA32_FEAT_CTL, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) 		fprintf(outf, "cpu%d: MSR_IA32_FEATURE_CONTROL: 0x%08llx (%sLocked %s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) 			base_cpu, msr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) 			msr & FEAT_CTL_LOCKED ? "" : "UN-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) 			msr & (1 << 18) ? "SGX" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) void decode_misc_enable_msr(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) 	if (!genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) 	if (!get_msr(base_cpu, MSR_IA32_MISC_ENABLE, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) 		fprintf(outf, "cpu%d: MSR_IA32_MISC_ENABLE: 0x%08llx (%sTCC %sEIST %sMWAIT %sPREFETCH %sTURBO)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) 			base_cpu, msr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) 			msr & MSR_IA32_MISC_ENABLE_TM1 ? "" : "No-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) 			msr & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP ? "" : "No-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) 			msr & MSR_IA32_MISC_ENABLE_MWAIT ? "" : "No-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) 			msr & MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE ? "No-" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) 			msr & MSR_IA32_MISC_ENABLE_TURBO_DISABLE ? "No-" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) void decode_misc_feature_control(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) 	if (!has_misc_feature_control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) 	if (!get_msr(base_cpu, MSR_MISC_FEATURE_CONTROL, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) 		fprintf(outf, "cpu%d: MSR_MISC_FEATURE_CONTROL: 0x%08llx (%sL2-Prefetch %sL2-Prefetch-pair %sL1-Prefetch %sL1-IP-Prefetch)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) 			base_cpu, msr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) 			msr & (0 << 0) ? "No-" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) 			msr & (1 << 0) ? "No-" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) 			msr & (2 << 0) ? "No-" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) 			msr & (3 << 0) ? "No-" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897)  * Decode MSR_MISC_PWR_MGMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899)  * Decode the bits according to the Nehalem documentation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900)  * bit[0] seems to continue to have same meaning going forward
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901)  * bit[1] less so...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) void decode_misc_pwr_mgmt_msr(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) 	if (!do_nhm_platform_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) 	if (no_MSR_MISC_PWR_MGMT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) 	if (!get_msr(base_cpu, MSR_MISC_PWR_MGMT, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) 		fprintf(outf, "cpu%d: MSR_MISC_PWR_MGMT: 0x%08llx (%sable-EIST_Coordination %sable-EPB %sable-OOB)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) 			base_cpu, msr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) 			msr & (1 << 0) ? "DIS" : "EN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) 			msr & (1 << 1) ? "EN" : "DIS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) 			msr & (1 << 8) ? "EN" : "DIS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921)  * Decode MSR_CC6_DEMOTION_POLICY_CONFIG, MSR_MC6_DEMOTION_POLICY_CONFIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923)  * This MSRs are present on Silvermont processors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924)  * Intel Atom processor E3000 series (Baytrail), and friends.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) void decode_c6_demotion_policy_msr(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928) 	unsigned long long msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) 	if (!get_msr(base_cpu, MSR_CC6_DEMOTION_POLICY_CONFIG, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) 		fprintf(outf, "cpu%d: MSR_CC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-CC6-Demotion)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) 			base_cpu, msr, msr & (1 << 0) ? "EN" : "DIS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) 	if (!get_msr(base_cpu, MSR_MC6_DEMOTION_POLICY_CONFIG, &msr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) 		fprintf(outf, "cpu%d: MSR_MC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-MC6-Demotion)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) 			base_cpu, msr, msr & (1 << 0) ? "EN" : "DIS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940)  * When models are the same, for the purpose of turbostat, reuse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) unsigned int intel_model_duplicates(unsigned int model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) 	switch(model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) 	case INTEL_FAM6_NEHALEM_EP:	/* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) 	case INTEL_FAM6_NEHALEM:	/* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) 	case 0x1F:	/* Core i7 and i5 Processor - Nehalem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) 	case INTEL_FAM6_WESTMERE:	/* Westmere Client - Clarkdale, Arrandale */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) 	case INTEL_FAM6_WESTMERE_EP:	/* Westmere EP - Gulftown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) 		return INTEL_FAM6_NEHALEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) 	case INTEL_FAM6_NEHALEM_EX:	/* Nehalem-EX Xeon - Beckton */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) 	case INTEL_FAM6_WESTMERE_EX:	/* Westmere-EX Xeon - Eagleton */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) 		return INTEL_FAM6_NEHALEM_EX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) 	case INTEL_FAM6_XEON_PHI_KNM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) 		return INTEL_FAM6_XEON_PHI_KNL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) 	case INTEL_FAM6_BROADWELL_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) 	case INTEL_FAM6_BROADWELL_D:	/* BDX-DE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) 		return INTEL_FAM6_BROADWELL_X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) 	case INTEL_FAM6_SKYLAKE_L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) 	case INTEL_FAM6_SKYLAKE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) 	case INTEL_FAM6_KABYLAKE_L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) 	case INTEL_FAM6_KABYLAKE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) 	case INTEL_FAM6_COMETLAKE_L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) 	case INTEL_FAM6_COMETLAKE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) 		return INTEL_FAM6_SKYLAKE_L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972) 	case INTEL_FAM6_ICELAKE_L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) 	case INTEL_FAM6_ICELAKE_NNPI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) 	case INTEL_FAM6_TIGERLAKE_L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) 	case INTEL_FAM6_TIGERLAKE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) 	case INTEL_FAM6_ROCKETLAKE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) 	case INTEL_FAM6_LAKEFIELD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) 	case INTEL_FAM6_ALDERLAKE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) 		return INTEL_FAM6_CANNONLAKE_L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) 	case INTEL_FAM6_ATOM_TREMONT_L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) 		return INTEL_FAM6_ATOM_TREMONT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) 	case INTEL_FAM6_ICELAKE_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985) 	case INTEL_FAM6_SAPPHIRERAPIDS_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) 		return INTEL_FAM6_SKYLAKE_X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) 	return model;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) void print_dev_latency(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) 	char *path = "/dev/cpu_dma_latency";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) 	int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995) 	int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) 	fd = open(path, O_RDONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) 	if (fd < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000) 		warn("fopen %s\n", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) 	retval = read(fd, (void *)&value, sizeof(int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) 	if (retval != sizeof(int)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) 		warn("read %s\n", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) 		close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) 	fprintf(outf, "/dev/cpu_dma_latency: %d usec (%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) 		value, value == 2000000000 ? "default" : "constrained");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) 	close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) void process_cpuid()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018) 	unsigned int eax, ebx, ecx, edx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019) 	unsigned int fms, family, model, stepping, ecx_flags, edx_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) 	unsigned int has_turbo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) 	eax = ebx = ecx = edx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) 	__cpuid(0, max_level, ebx, ecx, edx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) 	if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027) 		genuine_intel = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) 	else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) 		authentic_amd = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030) 	else if (ebx == 0x6f677948 && ecx == 0x656e6975 && edx == 0x6e65476e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) 		hygon_genuine = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) 	if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) 		fprintf(outf, "CPUID(0): %.4s%.4s%.4s ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) 			(char *)&ebx, (char *)&edx, (char *)&ecx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) 	__cpuid(1, fms, ebx, ecx, edx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) 	family = (fms >> 8) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) 	model = (fms >> 4) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) 	stepping = fms & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) 	if (family == 0xf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) 		family += (fms >> 20) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) 	if (family >= 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) 		model += ((fms >> 16) & 0xf) << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045) 	ecx_flags = ecx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046) 	edx_flags = edx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) 	 * check max extended function levels of CPUID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050) 	 * This is needed to check for invariant TSC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) 	 * This check is valid for both Intel and AMD.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) 	ebx = ecx = edx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) 	__cpuid(0x80000000, max_extended_level, ebx, ecx, edx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) 	if (!quiet) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057) 		fprintf(outf, "0x%x CPUID levels; 0x%x xlevels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058) 			max_level, max_extended_level, family, model, stepping, family, model, stepping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) 		fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) 			ecx_flags & (1 << 0) ? "SSE3" : "-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) 			ecx_flags & (1 << 3) ? "MONITOR" : "-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062) 			ecx_flags & (1 << 6) ? "SMX" : "-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) 			ecx_flags & (1 << 7) ? "EIST" : "-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) 			ecx_flags & (1 << 8) ? "TM2" : "-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) 			edx_flags & (1 << 4) ? "TSC" : "-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) 			edx_flags & (1 << 5) ? "MSR" : "-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067) 			edx_flags & (1 << 22) ? "ACPI-TM" : "-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) 			edx_flags & (1 << 28) ? "HT" : "-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) 			edx_flags & (1 << 29) ? "TM" : "-");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) 	if (genuine_intel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) 		model = intel_model_duplicates(model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) 	if (!(edx_flags & (1 << 5)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) 		errx(1, "CPUID: no MSR");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) 	if (max_extended_level >= 0x80000007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) 		 * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) 		 * this check is valid for both Intel and AMD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083) 		__cpuid(0x80000007, eax, ebx, ecx, edx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) 		has_invariant_tsc = edx & (1 << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) 	 * APERF/MPERF is advertised by CPUID.EAX=0x6: ECX.bit0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) 	 * this check is valid for both Intel and AMD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) 	__cpuid(0x6, eax, ebx, ecx, edx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) 	has_aperf = ecx & (1 << 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) 	if (has_aperf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) 		BIC_PRESENT(BIC_Avg_MHz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) 		BIC_PRESENT(BIC_Busy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) 		BIC_PRESENT(BIC_Bzy_MHz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) 	do_dts = eax & (1 << 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) 	if (do_dts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) 		BIC_PRESENT(BIC_CoreTmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) 	has_turbo = eax & (1 << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103) 	do_ptm = eax & (1 << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104) 	if (do_ptm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105) 		BIC_PRESENT(BIC_PkgTmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) 	has_hwp = eax & (1 << 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) 	has_hwp_notify = eax & (1 << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) 	has_hwp_activity_window = eax & (1 << 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) 	has_hwp_epp = eax & (1 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110) 	has_hwp_pkg = eax & (1 << 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) 	has_epb = ecx & (1 << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) 	if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) 		fprintf(outf, "CPUID(6): %sAPERF, %sTURBO, %sDTS, %sPTM, %sHWP, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) 			"%sHWPnotify, %sHWPwindow, %sHWPepp, %sHWPpkg, %sEPB\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116) 			has_aperf ? "" : "No-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117) 			has_turbo ? "" : "No-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) 			do_dts ? "" : "No-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119) 			do_ptm ? "" : "No-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) 			has_hwp ? "" : "No-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) 			has_hwp_notify ? "" : "No-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122) 			has_hwp_activity_window ? "" : "No-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) 			has_hwp_epp ? "" : "No-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124) 			has_hwp_pkg ? "" : "No-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) 			has_epb ? "" : "No-");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) 	if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) 		decode_misc_enable_msr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) 	if (max_level >= 0x7 && !quiet) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) 		int has_sgx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) 		ecx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) 		__cpuid_count(0x7, 0, eax, ebx, ecx, edx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) 		has_sgx = ebx & (1 << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) 		fprintf(outf, "CPUID(7): %sSGX\n", has_sgx ? "" : "No-");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141) 		if (has_sgx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) 			decode_feature_control_msr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) 	if (max_level >= 0x15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) 		unsigned int eax_crystal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) 		unsigned int ebx_tsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) 		 * CPUID 15H TSC/Crystal ratio, possibly Crystal Hz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152) 		eax_crystal = ebx_tsc = crystal_hz = edx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) 		__cpuid(0x15, eax_crystal, ebx_tsc, crystal_hz, edx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) 		if (ebx_tsc != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) 			if (!quiet && (ebx != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) 				fprintf(outf, "CPUID(0x15): eax_crystal: %d ebx_tsc: %d ecx_crystal_hz: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) 					eax_crystal, ebx_tsc, crystal_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) 			if (crystal_hz == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) 				switch(model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) 				case INTEL_FAM6_SKYLAKE_L:	/* SKL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164) 					crystal_hz = 24000000;	/* 24.0 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) 				case INTEL_FAM6_ATOM_GOLDMONT_D:	/* DNV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) 					crystal_hz = 25000000;	/* 25.0 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) 				case INTEL_FAM6_ATOM_GOLDMONT:	/* BXT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) 				case INTEL_FAM6_ATOM_GOLDMONT_PLUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) 					crystal_hz = 19200000;	/* 19.2 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173) 				default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174) 					crystal_hz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) 			if (crystal_hz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) 				tsc_hz =  (unsigned long long) crystal_hz * ebx_tsc / eax_crystal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) 				if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180) 					fprintf(outf, "TSC: %lld MHz (%d Hz * %d / %d / 1000000)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) 						tsc_hz / 1000000, crystal_hz, ebx_tsc,  eax_crystal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) 	if (max_level >= 0x16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) 		unsigned int base_mhz, max_mhz, bus_mhz, edx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189) 		 * CPUID 16H Base MHz, Max MHz, Bus MHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) 		base_mhz = max_mhz = bus_mhz = edx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193) 		__cpuid(0x16, base_mhz, max_mhz, bus_mhz, edx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194) 		if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) 			fprintf(outf, "CPUID(0x16): base_mhz: %d max_mhz: %d bus_mhz: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196) 				base_mhz, max_mhz, bus_mhz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) 	if (has_aperf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) 		aperf_mperf_multiplier = get_aperf_mperf_multiplier(family, model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202) 	BIC_PRESENT(BIC_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) 	BIC_PRESENT(BIC_TSC_MHz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205) 	if (probe_nhm_msrs(family, model)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) 		do_nhm_platform_info = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207) 		BIC_PRESENT(BIC_CPU_c1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208) 		BIC_PRESENT(BIC_CPU_c3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209) 		BIC_PRESENT(BIC_CPU_c6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210) 		BIC_PRESENT(BIC_SMI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) 	do_snb_cstates = has_snb_msrs(family, model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214) 	if (do_snb_cstates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) 		BIC_PRESENT(BIC_CPU_c7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217) 	do_irtl_snb = has_snb_msrs(family, model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218) 	if (do_snb_cstates && (pkg_cstate_limit >= PCL__2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219) 		BIC_PRESENT(BIC_Pkgpc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) 	if (pkg_cstate_limit >= PCL__3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) 		BIC_PRESENT(BIC_Pkgpc3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222) 	if (pkg_cstate_limit >= PCL__6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) 		BIC_PRESENT(BIC_Pkgpc6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224) 	if (do_snb_cstates && (pkg_cstate_limit >= PCL__7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) 		BIC_PRESENT(BIC_Pkgpc7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226) 	if (has_slv_msrs(family, model)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) 		BIC_NOT_PRESENT(BIC_Pkgpc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228) 		BIC_NOT_PRESENT(BIC_Pkgpc3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) 		BIC_PRESENT(BIC_Pkgpc6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) 		BIC_NOT_PRESENT(BIC_Pkgpc7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231) 		BIC_PRESENT(BIC_Mod_c6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232) 		use_c1_residency_msr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234) 	if (is_jvl(family, model)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235) 		BIC_NOT_PRESENT(BIC_CPU_c3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) 		BIC_NOT_PRESENT(BIC_CPU_c7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) 		BIC_NOT_PRESENT(BIC_Pkgpc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238) 		BIC_NOT_PRESENT(BIC_Pkgpc3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) 		BIC_NOT_PRESENT(BIC_Pkgpc6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240) 		BIC_NOT_PRESENT(BIC_Pkgpc7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242) 	if (is_dnv(family, model)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243) 		BIC_PRESENT(BIC_CPU_c1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244) 		BIC_NOT_PRESENT(BIC_CPU_c3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) 		BIC_NOT_PRESENT(BIC_Pkgpc3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) 		BIC_NOT_PRESENT(BIC_CPU_c7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) 		BIC_NOT_PRESENT(BIC_Pkgpc7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248) 		use_c1_residency_msr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250) 	if (is_skx(family, model)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) 		BIC_NOT_PRESENT(BIC_CPU_c3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252) 		BIC_NOT_PRESENT(BIC_Pkgpc3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) 		BIC_NOT_PRESENT(BIC_CPU_c7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254) 		BIC_NOT_PRESENT(BIC_Pkgpc7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256) 	if (is_bdx(family, model)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) 		BIC_NOT_PRESENT(BIC_CPU_c7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258) 		BIC_NOT_PRESENT(BIC_Pkgpc7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260) 	if (has_c8910_msrs(family, model)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) 		if (pkg_cstate_limit >= PCL__8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262) 			BIC_PRESENT(BIC_Pkgpc8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263) 		if (pkg_cstate_limit >= PCL__9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264) 			BIC_PRESENT(BIC_Pkgpc9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) 		if (pkg_cstate_limit >= PCL_10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266) 			BIC_PRESENT(BIC_Pkgpc10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) 	do_irtl_hsw = has_c8910_msrs(family, model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269) 	if (has_skl_msrs(family, model)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270) 		BIC_PRESENT(BIC_Totl_c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) 		BIC_PRESENT(BIC_Any_c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272) 		BIC_PRESENT(BIC_GFX_c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273) 		BIC_PRESENT(BIC_CPUGFX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275) 	do_slm_cstates = is_slm(family, model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276) 	do_knl_cstates  = is_knl(family, model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) 	if (do_slm_cstates || do_knl_cstates || is_cnl(family, model) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279) 	    is_ehl(family, model))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280) 		BIC_NOT_PRESENT(BIC_CPU_c3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282) 	if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) 		decode_misc_pwr_mgmt_msr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) 	if (!quiet && has_slv_msrs(family, model))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286) 		decode_c6_demotion_policy_msr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288) 	rapl_probe(family, model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) 	perf_limit_reasons_probe(family, model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290) 	automatic_cstate_conversion_probe(family, model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) 	if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) 		dump_cstate_pstate_config_info(family, model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295) 	if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) 		print_dev_latency();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297) 	if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298) 		dump_sysfs_cstate_config();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299) 	if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) 		dump_sysfs_pstate_config();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302) 	if (has_skl_msrs(family, model))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303) 		calculate_tsc_tweak();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305) 	if (!access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306) 		BIC_PRESENT(BIC_GFX_rc6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308) 	if (!access("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", R_OK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) 		BIC_PRESENT(BIC_GFXMHz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) 	if (!access("/sys/class/graphics/fb0/device/drm/card0/gt_act_freq_mhz", R_OK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312) 		BIC_PRESENT(BIC_GFXACTMHz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314) 	if (!access("/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us", R_OK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315) 		BIC_PRESENT(BIC_CPU_LPI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) 		BIC_NOT_PRESENT(BIC_CPU_LPI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319) 	if (!access(sys_lpi_file_sysfs, R_OK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) 		sys_lpi_file = sys_lpi_file_sysfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) 		BIC_PRESENT(BIC_SYS_LPI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) 	} else if (!access(sys_lpi_file_debugfs, R_OK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) 		sys_lpi_file = sys_lpi_file_debugfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324) 		BIC_PRESENT(BIC_SYS_LPI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) 		sys_lpi_file_sysfs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327) 		BIC_NOT_PRESENT(BIC_SYS_LPI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330) 	if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331) 		decode_misc_feature_control();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337)  * in /dev/cpu/ return success for names that are numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338)  * ie. filter out ".", "..", "microcode".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340) int dir_filter(const struct dirent *dirp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342) 	if (isdigit(dirp->d_name[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) int open_dev_cpu_msr(int dummy1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353) void topology_probe()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356) 	int max_core_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357) 	int max_package_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) 	int max_die_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359) 	int max_siblings = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361) 	/* Initialize num_cpus, max_cpu_num */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362) 	set_max_cpu_num();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363) 	topo.num_cpus = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364) 	for_all_proc_cpus(count_cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365) 	if (!summary_only && topo.num_cpus > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366) 		BIC_PRESENT(BIC_CPU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368) 	if (debug > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369) 		fprintf(outf, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371) 	cpus = calloc(1, (topo.max_cpu_num  + 1) * sizeof(struct cpu_topology));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372) 	if (cpus == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373) 		err(1, "calloc cpus");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376) 	 * Allocate and initialize cpu_present_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378) 	cpu_present_set = CPU_ALLOC((topo.max_cpu_num + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379) 	if (cpu_present_set == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380) 		err(3, "CPU_ALLOC");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381) 	cpu_present_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382) 	CPU_ZERO_S(cpu_present_setsize, cpu_present_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383) 	for_all_proc_cpus(mark_cpu_present);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386) 	 * Validate that all cpus in cpu_subset are also in cpu_present_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388) 	for (i = 0; i < CPU_SUBSET_MAXCPUS; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389) 		if (CPU_ISSET_S(i, cpu_subset_size, cpu_subset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390) 			if (!CPU_ISSET_S(i, cpu_present_setsize, cpu_present_set))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391) 				err(1, "cpu%d not present", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395) 	 * Allocate and initialize cpu_affinity_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397) 	cpu_affinity_set = CPU_ALLOC((topo.max_cpu_num + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398) 	if (cpu_affinity_set == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399) 		err(3, "CPU_ALLOC");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400) 	cpu_affinity_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401) 	CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403) 	for_all_proc_cpus(init_thread_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406) 	 * For online cpus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407) 	 * find max_core_id, max_package_id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409) 	for (i = 0; i <= topo.max_cpu_num; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) 		int siblings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412) 		if (cpu_is_not_present(i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413) 			if (debug > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414) 				fprintf(outf, "cpu%d NOT PRESENT\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418) 		cpus[i].logical_cpu_id = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420) 		/* get package information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) 		cpus[i].physical_package_id = get_physical_package_id(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422) 		if (cpus[i].physical_package_id > max_package_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423) 			max_package_id = cpus[i].physical_package_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425) 		/* get die information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426) 		cpus[i].die_id = get_die_id(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427) 		if (cpus[i].die_id > max_die_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428) 			max_die_id = cpus[i].die_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430) 		/* get numa node information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431) 		cpus[i].physical_node_id = get_physical_node_id(&cpus[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432) 		if (cpus[i].physical_node_id > topo.max_node_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433) 			topo.max_node_num = cpus[i].physical_node_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435) 		/* get core information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436) 		cpus[i].physical_core_id = get_core_id(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437) 		if (cpus[i].physical_core_id > max_core_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438) 			max_core_id = cpus[i].physical_core_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440) 		/* get thread information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441) 		siblings = get_thread_siblings(&cpus[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) 		if (siblings > max_siblings)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443) 			max_siblings = siblings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5444) 		if (cpus[i].thread_id == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5445) 			topo.num_cores++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5446) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5448) 	topo.cores_per_node = max_core_id + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5449) 	if (debug > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5450) 		fprintf(outf, "max_core_id %d, sizing for %d cores per package\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5451) 			max_core_id, topo.cores_per_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5452) 	if (!summary_only && topo.cores_per_node > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5453) 		BIC_PRESENT(BIC_Core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5455) 	topo.num_die = max_die_id + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5456) 	if (debug > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5457) 		fprintf(outf, "max_die_id %d, sizing for %d die\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5458) 				max_die_id, topo.num_die);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5459) 	if (!summary_only && topo.num_die > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5460) 		BIC_PRESENT(BIC_Die);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5462) 	topo.num_packages = max_package_id + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5463) 	if (debug > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5464) 		fprintf(outf, "max_package_id %d, sizing for %d packages\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5465) 			max_package_id, topo.num_packages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5466) 	if (!summary_only && topo.num_packages > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5467) 		BIC_PRESENT(BIC_Package);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5469) 	set_node_data();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5470) 	if (debug > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5471) 		fprintf(outf, "nodes_per_pkg %d\n", topo.nodes_per_pkg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5472) 	if (!summary_only && topo.nodes_per_pkg > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5473) 		BIC_PRESENT(BIC_Node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5475) 	topo.threads_per_core = max_siblings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5476) 	if (debug > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5477) 		fprintf(outf, "max_siblings %d\n", max_siblings);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5479) 	if (debug < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5480) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5482) 	for (i = 0; i <= topo.max_cpu_num; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5483) 		if (cpu_is_not_present(i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5484) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5485) 		fprintf(outf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5486) 			"cpu %d pkg %d die %d node %d lnode %d core %d thread %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5487) 			i, cpus[i].physical_package_id, cpus[i].die_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5488) 			cpus[i].physical_node_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5489) 			cpus[i].logical_node_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5490) 			cpus[i].physical_core_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5491) 			cpus[i].thread_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5492) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5496) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5497) allocate_counters(struct thread_data **t, struct core_data **c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5498) 		  struct pkg_data **p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5500) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5501) 	int num_cores = topo.cores_per_node * topo.nodes_per_pkg *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5502) 			topo.num_packages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5503) 	int num_threads = topo.threads_per_core * num_cores;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5505) 	*t = calloc(num_threads, sizeof(struct thread_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5506) 	if (*t == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5507) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5509) 	for (i = 0; i < num_threads; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5510) 		(*t)[i].cpu_id = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5512) 	*c = calloc(num_cores, sizeof(struct core_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5513) 	if (*c == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5514) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5516) 	for (i = 0; i < num_cores; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5517) 		(*c)[i].core_id = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5519) 	*p = calloc(topo.num_packages, sizeof(struct pkg_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5520) 	if (*p == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5521) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5523) 	for (i = 0; i < topo.num_packages; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5524) 		(*p)[i].package_id = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5526) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5527) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5528) 	err(1, "calloc counters");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5530) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5531)  * init_counter()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5532)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5533)  * set FIRST_THREAD_IN_CORE and FIRST_CORE_IN_PACKAGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5534)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5535) void init_counter(struct thread_data *thread_base, struct core_data *core_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5536) 	struct pkg_data *pkg_base, int cpu_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5538) 	int pkg_id = cpus[cpu_id].physical_package_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5539) 	int node_id = cpus[cpu_id].logical_node_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5540) 	int core_id = cpus[cpu_id].physical_core_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5541) 	int thread_id = cpus[cpu_id].thread_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5542) 	struct thread_data *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5543) 	struct core_data *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5544) 	struct pkg_data *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5547) 	/* Workaround for systems where physical_node_id==-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5548) 	 * and logical_node_id==(-1 - topo.num_cpus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5549) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5550) 	if (node_id < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5551) 		node_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5553) 	t = GET_THREAD(thread_base, thread_id, core_id, node_id, pkg_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5554) 	c = GET_CORE(core_base, core_id, node_id, pkg_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5555) 	p = GET_PKG(pkg_base, pkg_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5557) 	t->cpu_id = cpu_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5558) 	if (thread_id == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5559) 		t->flags |= CPU_IS_FIRST_THREAD_IN_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5560) 		if (cpu_is_first_core_in_package(cpu_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5561) 			t->flags |= CPU_IS_FIRST_CORE_IN_PACKAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5562) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5564) 	c->core_id = core_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5565) 	p->package_id = pkg_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5569) int initialize_counters(int cpu_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5571) 	init_counter(EVEN_COUNTERS, cpu_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5572) 	init_counter(ODD_COUNTERS, cpu_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5573) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5576) void allocate_output_buffer()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5578) 	output_buffer = calloc(1, (1 + topo.num_cpus) * 2048);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5579) 	outp = output_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5580) 	if (outp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5581) 		err(-1, "calloc output buffer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5583) void allocate_fd_percpu(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5585) 	fd_percpu = calloc(topo.max_cpu_num + 1, sizeof(int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5586) 	if (fd_percpu == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5587) 		err(-1, "calloc fd_percpu");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5589) void allocate_irq_buffers(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5591) 	irq_column_2_cpu = calloc(topo.num_cpus, sizeof(int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5592) 	if (irq_column_2_cpu == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5593) 		err(-1, "calloc %d", topo.num_cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5595) 	irqs_per_cpu = calloc(topo.max_cpu_num + 1, sizeof(int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5596) 	if (irqs_per_cpu == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5597) 		err(-1, "calloc %d", topo.max_cpu_num + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5599) void setup_all_buffers(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5601) 	topology_probe();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5602) 	allocate_irq_buffers();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5603) 	allocate_fd_percpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5604) 	allocate_counters(&thread_even, &core_even, &package_even);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5605) 	allocate_counters(&thread_odd, &core_odd, &package_odd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5606) 	allocate_output_buffer();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5607) 	for_all_proc_cpus(initialize_counters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5610) void set_base_cpu(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5612) 	base_cpu = sched_getcpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5613) 	if (base_cpu < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5614) 		err(-ENODEV, "No valid cpus found");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5616) 	if (debug > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5617) 		fprintf(outf, "base_cpu = %d\n", base_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5620) void turbostat_init()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5622) 	setup_all_buffers();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5623) 	set_base_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5624) 	check_dev_msr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5625) 	check_permissions();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5626) 	process_cpuid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5629) 	if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5630) 		for_all_cpus(print_hwp, ODD_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5632) 	if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5633) 		for_all_cpus(print_epb, ODD_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5635) 	if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5636) 		for_all_cpus(print_perf_limit, ODD_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5638) 	if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5639) 		for_all_cpus(print_rapl, ODD_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5641) 	for_all_cpus(set_temperature_target, ODD_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5643) 	if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5644) 		for_all_cpus(print_thermal, ODD_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5646) 	if (!quiet && do_irtl_snb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5647) 		print_irtl();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5650) int fork_it(char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5651) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5652) 	pid_t child_pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5653) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5655) 	snapshot_proc_sysfs_files();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5656) 	status = for_all_cpus(get_counters, EVEN_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5657) 	first_counter_read = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5658) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5659) 		exit(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5660) 	/* clear affinity side-effect of get_counters() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5661) 	sched_setaffinity(0, cpu_present_setsize, cpu_present_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5662) 	gettimeofday(&tv_even, (struct timezone *)NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5664) 	child_pid = fork();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5665) 	if (!child_pid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5666) 		/* child */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5667) 		execvp(argv[0], argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5668) 		err(errno, "exec %s", argv[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5669) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5671) 		/* parent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5672) 		if (child_pid == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5673) 			err(1, "fork");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5675) 		signal(SIGINT, SIG_IGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5676) 		signal(SIGQUIT, SIG_IGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5677) 		if (waitpid(child_pid, &status, 0) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5678) 			err(status, "waitpid");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5680) 		if (WIFEXITED(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5681) 			status = WEXITSTATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5682) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5683) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5684) 	 * n.b. fork_it() does not check for errors from for_all_cpus()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5685) 	 * because re-starting is problematic when forking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5686) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5687) 	snapshot_proc_sysfs_files();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5688) 	for_all_cpus(get_counters, ODD_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5689) 	gettimeofday(&tv_odd, (struct timezone *)NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5690) 	timersub(&tv_odd, &tv_even, &tv_delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5691) 	if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5692) 		fprintf(outf, "%s: Counter reset detected\n", progname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5693) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5694) 		compute_average(EVEN_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5695) 		format_all_counters(EVEN_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5696) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5698) 	fprintf(outf, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5700) 	flush_output_stderr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5702) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5705) int get_and_dump_counters(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5707) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5709) 	snapshot_proc_sysfs_files();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5710) 	status = for_all_cpus(get_counters, ODD_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5711) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5712) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5714) 	status = for_all_cpus(dump_counters, ODD_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5715) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5716) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5718) 	flush_output_stdout();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5720) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5723) void print_version() {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5724) 	fprintf(outf, "turbostat version 20.09.30"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5725) 		" - Len Brown <lenb@kernel.org>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5728) int add_counter(unsigned int msr_num, char *path, char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5729) 	unsigned int width, enum counter_scope scope,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5730) 	enum counter_type type, enum counter_format format, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5732) 	struct msr_counter *msrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5734) 	msrp = calloc(1, sizeof(struct msr_counter));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5735) 	if (msrp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5736) 		perror("calloc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5737) 		exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5738) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5740) 	msrp->msr_num = msr_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5741) 	strncpy(msrp->name, name, NAME_BYTES - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5742) 	if (path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5743) 		strncpy(msrp->path, path, PATH_BYTES - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5744) 	msrp->width = width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5745) 	msrp->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5746) 	msrp->format = format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5747) 	msrp->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5749) 	switch (scope) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5751) 	case SCOPE_CPU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5752) 		msrp->next = sys.tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5753) 		sys.tp = msrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5754) 		sys.added_thread_counters++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5755) 		if (sys.added_thread_counters > MAX_ADDED_THREAD_COUNTERS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5756) 			fprintf(stderr, "exceeded max %d added thread counters\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5757) 				MAX_ADDED_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5758) 			exit(-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5759) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5760) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5762) 	case SCOPE_CORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5763) 		msrp->next = sys.cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5764) 		sys.cp = msrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5765) 		sys.added_core_counters++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5766) 		if (sys.added_core_counters > MAX_ADDED_COUNTERS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5767) 			fprintf(stderr, "exceeded max %d added core counters\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5768) 				MAX_ADDED_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5769) 			exit(-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5770) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5771) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5773) 	case SCOPE_PACKAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5774) 		msrp->next = sys.pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5775) 		sys.pp = msrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5776) 		sys.added_package_counters++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5777) 		if (sys.added_package_counters > MAX_ADDED_COUNTERS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5778) 			fprintf(stderr, "exceeded max %d added package counters\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5779) 				MAX_ADDED_COUNTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5780) 			exit(-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5781) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5782) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5783) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5785) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5788) void parse_add_command(char *add_command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5790) 	int msr_num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5791) 	char *path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5792) 	char name_buffer[NAME_BYTES] = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5793) 	int width = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5794) 	int fail = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5795) 	enum counter_scope scope = SCOPE_CPU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5796) 	enum counter_type type = COUNTER_CYCLES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5797) 	enum counter_format format = FORMAT_DELTA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5799) 	while (add_command) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5801) 		if (sscanf(add_command, "msr0x%x", &msr_num) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5802) 			goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5804) 		if (sscanf(add_command, "msr%d", &msr_num) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5805) 			goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5807) 		if (*add_command == '/') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5808) 			path = add_command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5809) 			goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5810) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5812) 		if (sscanf(add_command, "u%d", &width) == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5813) 			if ((width == 32) || (width == 64))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5814) 				goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5815) 			width = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5816) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5817) 		if (!strncmp(add_command, "cpu", strlen("cpu"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5818) 			scope = SCOPE_CPU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5819) 			goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5820) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5821) 		if (!strncmp(add_command, "core", strlen("core"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5822) 			scope = SCOPE_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5823) 			goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5824) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5825) 		if (!strncmp(add_command, "package", strlen("package"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5826) 			scope = SCOPE_PACKAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5827) 			goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5828) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5829) 		if (!strncmp(add_command, "cycles", strlen("cycles"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5830) 			type = COUNTER_CYCLES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5831) 			goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5832) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5833) 		if (!strncmp(add_command, "seconds", strlen("seconds"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5834) 			type = COUNTER_SECONDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5835) 			goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5836) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5837) 		if (!strncmp(add_command, "usec", strlen("usec"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5838) 			type = COUNTER_USEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5839) 			goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5840) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5841) 		if (!strncmp(add_command, "raw", strlen("raw"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5842) 			format = FORMAT_RAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5843) 			goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5844) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5845) 		if (!strncmp(add_command, "delta", strlen("delta"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5846) 			format = FORMAT_DELTA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5847) 			goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5848) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5849) 		if (!strncmp(add_command, "percent", strlen("percent"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5850) 			format = FORMAT_PERCENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5851) 			goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5852) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5854) 		if (sscanf(add_command, "%18s,%*s", name_buffer) == 1) {	/* 18 < NAME_BYTES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5855) 			char *eos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5857) 			eos = strchr(name_buffer, ',');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5858) 			if (eos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5859) 				*eos = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5860) 			goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5861) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5863) next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5864) 		add_command = strchr(add_command, ',');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5865) 		if (add_command) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5866) 			*add_command = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5867) 			add_command++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5868) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5870) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5871) 	if ((msr_num == 0) && (path == NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5872) 		fprintf(stderr, "--add: (msrDDD | msr0xXXX | /path_to_counter ) required\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5873) 		fail++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5874) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5876) 	/* generate default column header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5877) 	if (*name_buffer == '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5878) 		if (width == 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5879) 			sprintf(name_buffer, "M0x%x%s", msr_num, format == FORMAT_PERCENT ? "%" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5880) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5881) 			sprintf(name_buffer, "M0X%x%s", msr_num, format == FORMAT_PERCENT ? "%" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5882) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5884) 	if (add_counter(msr_num, path, name_buffer, width, scope, type, format, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5885) 		fail++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5887) 	if (fail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5888) 		help();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5889) 		exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5890) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5893) int is_deferred_skip(char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5895) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5897) 	for (i = 0; i < deferred_skip_index; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5898) 		if (!strcmp(name, deferred_skip_names[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5899) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5900) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5903) void probe_sysfs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5905) 	char path[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5906) 	char name_buf[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5907) 	FILE *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5908) 	int state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5909) 	char *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5911) 	if (!DO_BIC(BIC_sysfs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5912) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5914) 	for (state = 10; state >= 0; --state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5916) 		sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5917) 			base_cpu, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5918) 		input = fopen(path, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5919) 		if (input == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5920) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5921) 		if (!fgets(name_buf, sizeof(name_buf), input))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5922) 			err(1, "%s: failed to read file", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5924) 		 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5925) 		sp = strchr(name_buf, '-');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5926) 		if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5927) 			sp = strchrnul(name_buf, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5928) 		*sp = '%';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5929) 		*(sp + 1) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5931) 		remove_underbar(name_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5933) 		fclose(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5935) 		sprintf(path, "cpuidle/state%d/time", state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5937) 		if (is_deferred_skip(name_buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5938) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5940) 		add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_USEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5941) 				FORMAT_PERCENT, SYSFS_PERCPU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5942) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5944) 	for (state = 10; state >= 0; --state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5946) 		sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5947) 			base_cpu, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5948) 		input = fopen(path, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5949) 		if (input == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5950) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5951) 		if (!fgets(name_buf, sizeof(name_buf), input))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5952) 			err(1, "%s: failed to read file", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5953) 		 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5954) 		sp = strchr(name_buf, '-');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5955) 		if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5956) 			sp = strchrnul(name_buf, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5957) 		*sp = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5958) 		fclose(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5960) 		remove_underbar(name_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5962) 		sprintf(path, "cpuidle/state%d/usage", state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5964) 		if (is_deferred_skip(name_buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5965) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5967) 		add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5968) 				FORMAT_DELTA, SYSFS_PERCPU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5969) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5974) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5975)  * parse cpuset with following syntax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5976)  * 1,2,4..6,8-10 and set bits in cpu_subset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5977)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5978) void parse_cpu_command(char *optarg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5979) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5980) 	unsigned int start, end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5981) 	char *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5983) 	if (!strcmp(optarg, "core")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5984) 		if (cpu_subset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5985) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5986) 		show_core_only++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5987) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5988) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5989) 	if (!strcmp(optarg, "package")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5990) 		if (cpu_subset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5991) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5992) 		show_pkg_only++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5993) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5994) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5995) 	if (show_core_only || show_pkg_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5996) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5998) 	cpu_subset = CPU_ALLOC(CPU_SUBSET_MAXCPUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5999) 	if (cpu_subset == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6000) 		err(3, "CPU_ALLOC");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6001) 	cpu_subset_size = CPU_ALLOC_SIZE(CPU_SUBSET_MAXCPUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6003) 	CPU_ZERO_S(cpu_subset_size, cpu_subset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6005) 	next = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6007) 	while (next && *next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6009) 		if (*next == '-')	/* no negative cpu numbers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6010) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6012) 		start = strtoul(next, &next, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6014) 		if (start >= CPU_SUBSET_MAXCPUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6015) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6016) 		CPU_SET_S(start, cpu_subset_size, cpu_subset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6018) 		if (*next == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6019) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6021) 		if (*next == ',') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6022) 			next += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6023) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6024) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6026) 		if (*next == '-') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6027) 			next += 1;	/* start range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6028) 		} else if (*next == '.') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6029) 			next += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6030) 			if (*next == '.')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6031) 				next += 1;	/* start range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6032) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6033) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6034) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6036) 		end = strtoul(next, &next, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6037) 		if (end <= start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6038) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6040) 		while (++start <= end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6041) 			if (start >= CPU_SUBSET_MAXCPUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6042) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6043) 			CPU_SET_S(start, cpu_subset_size, cpu_subset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6044) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6046) 		if (*next == ',')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6047) 			next += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6048) 		else if (*next != '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6049) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6050) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6052) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6054) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6055) 	fprintf(stderr, "\"--cpu %s\" malformed\n", optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6056) 	help();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6057) 	exit(-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6061) void cmdline(int argc, char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6062) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6063) 	int opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6064) 	int option_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6065) 	static struct option long_options[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6066) 		{"add",		required_argument,	0, 'a'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6067) 		{"cpu",		required_argument,	0, 'c'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6068) 		{"Dump",	no_argument,		0, 'D'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6069) 		{"debug",	no_argument,		0, 'd'},	/* internal, not documented */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6070) 		{"enable",	required_argument,	0, 'e'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6071) 		{"interval",	required_argument,	0, 'i'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6072) 		{"num_iterations",	required_argument,	0, 'n'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6073) 		{"help",	no_argument,		0, 'h'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6074) 		{"hide",	required_argument,	0, 'H'},	// meh, -h taken by --help
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6075) 		{"Joules",	no_argument,		0, 'J'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6076) 		{"list",	no_argument,		0, 'l'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6077) 		{"out",		required_argument,	0, 'o'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6078) 		{"quiet",	no_argument,		0, 'q'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6079) 		{"show",	required_argument,	0, 's'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6080) 		{"Summary",	no_argument,		0, 'S'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6081) 		{"TCC",		required_argument,	0, 'T'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6082) 		{"version",	no_argument,		0, 'v' },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6083) 		{0,		0,			0,  0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6084) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6086) 	progname = argv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6088) 	while ((opt = getopt_long_only(argc, argv, "+C:c:Dde:hi:Jn:o:qST:v",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6089) 				long_options, &option_index)) != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6090) 		switch (opt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6091) 		case 'a':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6092) 			parse_add_command(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6093) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6094) 		case 'c':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6095) 			parse_cpu_command(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6096) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6097) 		case 'D':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6098) 			dump_only++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6099) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6100) 		case 'e':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6101) 			/* --enable specified counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6102) 			bic_enabled = bic_enabled | bic_lookup(optarg, SHOW_LIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6103) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6104) 		case 'd':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6105) 			debug++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6106) 			ENABLE_BIC(BIC_DISABLED_BY_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6107) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6108) 		case 'H':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6109) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6110) 			 * --hide: do not show those specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6111) 			 *  multiple invocations simply clear more bits in enabled mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6112) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6113) 			bic_enabled &= ~bic_lookup(optarg, HIDE_LIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6114) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6115) 		case 'h':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6116) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6117) 			help();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6118) 			exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6119) 		case 'i':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6120) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6121) 				double interval = strtod(optarg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6123) 				if (interval < 0.001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6124) 					fprintf(outf, "interval %f seconds is too small\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6125) 						interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6126) 					exit(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6127) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6129) 				interval_tv.tv_sec = interval_ts.tv_sec = interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6130) 				interval_tv.tv_usec = (interval - interval_tv.tv_sec) * 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6131) 				interval_ts.tv_nsec = (interval - interval_ts.tv_sec) * 1000000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6132) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6133) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6134) 		case 'J':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6135) 			rapl_joules++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6136) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6137) 		case 'l':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6138) 			ENABLE_BIC(BIC_DISABLED_BY_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6139) 			list_header_only++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6140) 			quiet++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6141) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6142) 		case 'o':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6143) 			outf = fopen_or_die(optarg, "w");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6144) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6145) 		case 'q':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6146) 			quiet = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6147) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6148) 		case 'n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6149) 			num_iterations = strtod(optarg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6151) 			if (num_iterations <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6152) 				fprintf(outf, "iterations %d should be positive number\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6153) 					num_iterations);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6154) 				exit(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6155) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6156) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6157) 		case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6158) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6159) 			 * --show: show only those specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6160) 			 *  The 1st invocation will clear and replace the enabled mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6161) 			 *  subsequent invocations can add to it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6162) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6163) 			if (shown == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6164) 				bic_enabled = bic_lookup(optarg, SHOW_LIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6165) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6166) 				bic_enabled |= bic_lookup(optarg, SHOW_LIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6167) 			shown = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6168) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6169) 		case 'S':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6170) 			summary_only++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6171) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6172) 		case 'T':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6173) 			tcc_activation_temp_override = atoi(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6174) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6175) 		case 'v':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6176) 			print_version();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6177) 			exit(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6178) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6179) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6180) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6183) int main(int argc, char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6185) 	outf = stderr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6186) 	cmdline(argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6188) 	if (!quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6189) 		print_version();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6191) 	probe_sysfs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6193) 	turbostat_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6195) 	/* dump counters and exit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6196) 	if (dump_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6197) 		return get_and_dump_counters();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6199) 	/* list header and exit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6200) 	if (list_header_only) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6201) 		print_header(",");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6202) 		flush_output_stdout();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6203) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6204) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6206) 	msr_sum_record();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6207) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6208) 	 * if any params left, it must be a command to fork
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6209) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6210) 	if (argc - optind)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6211) 		return fork_it(argv + optind);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6212) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6213) 		turbostat_loop();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6215) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6216) }