File Index
Files and directories
Sign in
FILE

turbostat.c

File preview with syntax highlighting.

linux-6.19.14/tools/power/x86/turbostat/turbostat.c C
    1// SPDX-License-Identifier: GPL-2.0-only
    2/*
    3 * turbostat -- show CPU frequency and C-state residency
    4 * on modern Intel and AMD processors.
    5 *
    6 * Copyright (c) 2025 Intel Corporation.
    7 * Len Brown <len.brown@intel.com>
    8 */
    9
   10#define _GNU_SOURCE
   11#include MSRHEADER
   12
   13// copied from arch/x86/include/asm/cpu_device_id.h
   14#define VFM_MODEL_BIT	0
   15#define VFM_FAMILY_BIT	8
   16#define VFM_VENDOR_BIT	16
   17#define VFM_RSVD_BIT	24
   18
   19#define	VFM_MODEL_MASK	GENMASK(VFM_FAMILY_BIT - 1, VFM_MODEL_BIT)
   20#define	VFM_FAMILY_MASK	GENMASK(VFM_VENDOR_BIT - 1, VFM_FAMILY_BIT)
   21#define	VFM_VENDOR_MASK	GENMASK(VFM_RSVD_BIT - 1, VFM_VENDOR_BIT)
   22
   23#define VFM_MODEL(vfm)	(((vfm) & VFM_MODEL_MASK) >> VFM_MODEL_BIT)
   24#define VFM_FAMILY(vfm)	(((vfm) & VFM_FAMILY_MASK) >> VFM_FAMILY_BIT)
   25#define VFM_VENDOR(vfm)	(((vfm) & VFM_VENDOR_MASK) >> VFM_VENDOR_BIT)
   26
   27#define	VFM_MAKE(_vendor, _family, _model) (	\
   28	((_model) << VFM_MODEL_BIT) |		\
   29	((_family) << VFM_FAMILY_BIT) |		\
   30	((_vendor) << VFM_VENDOR_BIT)		\
   31)
   32// end copied section
   33
   34#define CPUID_LEAF_MODEL_ID			0x1A
   35#define CPUID_LEAF_MODEL_ID_CORE_TYPE_SHIFT	24
   36
   37#define X86_VENDOR_INTEL	0
   38
   39#include INTEL_FAMILY_HEADER
   40#include BUILD_BUG_HEADER
   41#include <stdarg.h>
   42#include <stdio.h>
   43#include <err.h>
   44#include <unistd.h>
   45#include <sys/types.h>
   46#include <sys/wait.h>
   47#include <sys/stat.h>
   48#include <sys/select.h>
   49#include <sys/resource.h>
   50#include <sys/mman.h>
   51#include <fcntl.h>
   52#include <signal.h>
   53#include <sys/time.h>
   54#include <stdlib.h>
   55#include <getopt.h>
   56#include <dirent.h>
   57#include <string.h>
   58#include <ctype.h>
   59#include <sched.h>
   60#include <time.h>
   61#include <cpuid.h>
   62#include <sys/capability.h>
   63#include <errno.h>
   64#include <math.h>
   65#include <linux/perf_event.h>
   66#include <asm/unistd.h>
   67#include <stdbool.h>
   68#include <assert.h>
   69#include <linux/kernel.h>
   70#include <limits.h>
   71
   72#define UNUSED(x) (void)(x)
   73
   74/*
   75 * This list matches the column headers, except
   76 * 1. built-in only, the sysfs counters are not here -- we learn of those at run-time
   77 * 2. Core and CPU are moved to the end, we can't have strings that contain them
   78 *    matching on them for --show and --hide.
   79 */
   80
   81/*
   82 * buffer size used by sscanf() for added column names
   83 * Usually truncated to 7 characters, but also handles 18 columns for raw 64-bit counters
   84 */
   85#define	NAME_BYTES 20
   86#define PATH_BYTES 128
   87#define PERF_NAME_BYTES 128
   88
   89#define MAX_NOFILE 0x8000
   90
   91#define COUNTER_KIND_PERF_PREFIX "perf/"
   92#define COUNTER_KIND_PERF_PREFIX_LEN strlen(COUNTER_KIND_PERF_PREFIX)
   93#define PERF_DEV_NAME_BYTES 32
   94#define PERF_EVT_NAME_BYTES 32
   95
   96#define INTEL_ECORE_TYPE	0x20
   97#define INTEL_PCORE_TYPE	0x40
   98
   99#define ROUND_UP_TO_PAGE_SIZE(n) (((n) + 0x1000UL-1UL) & ~(0x1000UL-1UL))
  100
  101enum counter_scope { SCOPE_CPU, SCOPE_CORE, SCOPE_PACKAGE };
  102enum counter_type { COUNTER_ITEMS, COUNTER_CYCLES, COUNTER_SECONDS, COUNTER_USEC, COUNTER_K2M };
  103enum counter_format { FORMAT_RAW, FORMAT_DELTA, FORMAT_PERCENT, FORMAT_AVERAGE };
  104enum counter_source { COUNTER_SOURCE_NONE, COUNTER_SOURCE_PERF, COUNTER_SOURCE_MSR };
  105
  106struct perf_counter_info {
  107	struct perf_counter_info *next;
  108
  109	/* How to open the counter / What counter it is. */
  110	char device[PERF_DEV_NAME_BYTES];
  111	char event[PERF_EVT_NAME_BYTES];
  112
  113	/* How to show/format the counter. */
  114	char name[PERF_NAME_BYTES];
  115	unsigned int width;
  116	enum counter_scope scope;
  117	enum counter_type type;
  118	enum counter_format format;
  119	double scale;
  120
  121	/* For reading the counter. */
  122	int *fd_perf_per_domain;
  123	size_t num_domains;
  124};
  125
  126struct sysfs_path {
  127	char path[PATH_BYTES];
  128	int id;
  129	struct sysfs_path *next;
  130};
  131
  132struct msr_counter {
  133	unsigned int msr_num;
  134	char name[NAME_BYTES];
  135	struct sysfs_path *sp;
  136	unsigned int width;
  137	enum counter_type type;
  138	enum counter_format format;
  139	struct msr_counter *next;
  140	unsigned int flags;
  141#define	FLAGS_HIDE	(1 << 0)
  142#define	FLAGS_SHOW	(1 << 1)
  143#define	SYSFS_PERCPU	(1 << 1)
  144};
  145static int use_android_msr_path;
  146
  147struct msr_counter bic[] = {
  148	{ 0x0, "usec", NULL, 0, 0, 0, NULL, 0 },
  149	{ 0x0, "Time_Of_Day_Seconds", NULL, 0, 0, 0, NULL, 0 },
  150	{ 0x0, "Package", NULL, 0, 0, 0, NULL, 0 },
  151	{ 0x0, "Node", NULL, 0, 0, 0, NULL, 0 },
  152	{ 0x0, "Avg_MHz", NULL, 0, 0, 0, NULL, 0 },
  153	{ 0x0, "Busy%", NULL, 0, 0, 0, NULL, 0 },
  154	{ 0x0, "Bzy_MHz", NULL, 0, 0, 0, NULL, 0 },
  155	{ 0x0, "TSC_MHz", NULL, 0, 0, 0, NULL, 0 },
  156	{ 0x0, "IRQ", NULL, 0, 0, 0, NULL, 0 },
  157	{ 0x0, "SMI", NULL, 32, 0, FORMAT_DELTA, NULL, 0 },
  158	{ 0x0, "cpuidle", NULL, 0, 0, 0, NULL, 0 },
  159	{ 0x0, "CPU%c1", NULL, 0, 0, 0, NULL, 0 },
  160	{ 0x0, "CPU%c3", NULL, 0, 0, 0, NULL, 0 },
  161	{ 0x0, "CPU%c6", NULL, 0, 0, 0, NULL, 0 },
  162	{ 0x0, "CPU%c7", NULL, 0, 0, 0, NULL, 0 },
  163	{ 0x0, "ThreadC", NULL, 0, 0, 0, NULL, 0 },
  164	{ 0x0, "CoreTmp", NULL, 0, 0, 0, NULL, 0 },
  165	{ 0x0, "CoreCnt", NULL, 0, 0, 0, NULL, 0 },
  166	{ 0x0, "PkgTmp", NULL, 0, 0, 0, NULL, 0 },
  167	{ 0x0, "GFX%rc6", NULL, 0, 0, 0, NULL, 0 },
  168	{ 0x0, "GFXMHz", NULL, 0, 0, 0, NULL, 0 },
  169	{ 0x0, "Pkg%pc2", NULL, 0, 0, 0, NULL, 0 },
  170	{ 0x0, "Pkg%pc3", NULL, 0, 0, 0, NULL, 0 },
  171	{ 0x0, "Pkg%pc6", NULL, 0, 0, 0, NULL, 0 },
  172	{ 0x0, "Pkg%pc7", NULL, 0, 0, 0, NULL, 0 },
  173	{ 0x0, "Pkg%pc8", NULL, 0, 0, 0, NULL, 0 },
  174	{ 0x0, "Pkg%pc9", NULL, 0, 0, 0, NULL, 0 },
  175	{ 0x0, "Pk%pc10", NULL, 0, 0, 0, NULL, 0 },
  176	{ 0x0, "CPU%LPI", NULL, 0, 0, 0, NULL, 0 },
  177	{ 0x0, "SYS%LPI", NULL, 0, 0, 0, NULL, 0 },
  178	{ 0x0, "PkgWatt", NULL, 0, 0, 0, NULL, 0 },
  179	{ 0x0, "CorWatt", NULL, 0, 0, 0, NULL, 0 },
  180	{ 0x0, "GFXWatt", NULL, 0, 0, 0, NULL, 0 },
  181	{ 0x0, "PkgCnt", NULL, 0, 0, 0, NULL, 0 },
  182	{ 0x0, "RAMWatt", NULL, 0, 0, 0, NULL, 0 },
  183	{ 0x0, "PKG_%", NULL, 0, 0, 0, NULL, 0 },
  184	{ 0x0, "RAM_%", NULL, 0, 0, 0, NULL, 0 },
  185	{ 0x0, "Pkg_J", NULL, 0, 0, 0, NULL, 0 },
  186	{ 0x0, "Cor_J", NULL, 0, 0, 0, NULL, 0 },
  187	{ 0x0, "GFX_J", NULL, 0, 0, 0, NULL, 0 },
  188	{ 0x0, "RAM_J", NULL, 0, 0, 0, NULL, 0 },
  189	{ 0x0, "Mod%c6", NULL, 0, 0, 0, NULL, 0 },
  190	{ 0x0, "Totl%C0", NULL, 0, 0, 0, NULL, 0 },
  191	{ 0x0, "Any%C0", NULL, 0, 0, 0, NULL, 0 },
  192	{ 0x0, "GFX%C0", NULL, 0, 0, 0, NULL, 0 },
  193	{ 0x0, "CPUGFX%", NULL, 0, 0, 0, NULL, 0 },
  194	{ 0x0, "Core", NULL, 0, 0, 0, NULL, 0 },
  195	{ 0x0, "CPU", NULL, 0, 0, 0, NULL, 0 },
  196	{ 0x0, "APIC", NULL, 0, 0, 0, NULL, 0 },
  197	{ 0x0, "X2APIC", NULL, 0, 0, 0, NULL, 0 },
  198	{ 0x0, "Die", NULL, 0, 0, 0, NULL, 0 },
  199	{ 0x0, "L3", NULL, 0, 0, 0, NULL, 0 },
  200	{ 0x0, "GFXAMHz", NULL, 0, 0, 0, NULL, 0 },
  201	{ 0x0, "IPC", NULL, 0, 0, 0, NULL, 0 },
  202	{ 0x0, "CoreThr", NULL, 0, 0, 0, NULL, 0 },
  203	{ 0x0, "UncMHz", NULL, 0, 0, 0, NULL, 0 },
  204	{ 0x0, "SAM%mc6", NULL, 0, 0, 0, NULL, 0 },
  205	{ 0x0, "SAMMHz", NULL, 0, 0, 0, NULL, 0 },
  206	{ 0x0, "SAMAMHz", NULL, 0, 0, 0, NULL, 0 },
  207	{ 0x0, "Die%c6", NULL, 0, 0, 0, NULL, 0 },
  208	{ 0x0, "SysWatt", NULL, 0, 0, 0, NULL, 0 },
  209	{ 0x0, "Sys_J", NULL, 0, 0, 0, NULL, 0 },
  210	{ 0x0, "NMI", NULL, 0, 0, 0, NULL, 0 },
  211	{ 0x0, "CPU%c1e", NULL, 0, 0, 0, NULL, 0 },
  212	{ 0x0, "pct_idle", NULL, 0, 0, 0, NULL, 0 },
  213	{ 0x0, "LLCkRPS", NULL, 0, 0, 0, NULL, 0 },
  214	{ 0x0, "LLC%hit", NULL, 0, 0, 0, NULL, 0 },
  215};
  216
  217/* n.b. bic_names must match the order in bic[], above */
  218enum bic_names {
  219	BIC_USEC,
  220	BIC_TOD,
  221	BIC_Package,
  222	BIC_Node,
  223	BIC_Avg_MHz,
  224	BIC_Busy,
  225	BIC_Bzy_MHz,
  226	BIC_TSC_MHz,
  227	BIC_IRQ,
  228	BIC_SMI,
  229	BIC_cpuidle,
  230	BIC_CPU_c1,
  231	BIC_CPU_c3,
  232	BIC_CPU_c6,
  233	BIC_CPU_c7,
  234	BIC_ThreadC,
  235	BIC_CoreTmp,
  236	BIC_CoreCnt,
  237	BIC_PkgTmp,
  238	BIC_GFX_rc6,
  239	BIC_GFXMHz,
  240	BIC_Pkgpc2,
  241	BIC_Pkgpc3,
  242	BIC_Pkgpc6,
  243	BIC_Pkgpc7,
  244	BIC_Pkgpc8,
  245	BIC_Pkgpc9,
  246	BIC_Pkgpc10,
  247	BIC_CPU_LPI,
  248	BIC_SYS_LPI,
  249	BIC_PkgWatt,
  250	BIC_CorWatt,
  251	BIC_GFXWatt,
  252	BIC_PkgCnt,
  253	BIC_RAMWatt,
  254	BIC_PKG__,
  255	BIC_RAM__,
  256	BIC_Pkg_J,
  257	BIC_Cor_J,
  258	BIC_GFX_J,
  259	BIC_RAM_J,
  260	BIC_Mod_c6,
  261	BIC_Totl_c0,
  262	BIC_Any_c0,
  263	BIC_GFX_c0,
  264	BIC_CPUGFX,
  265	BIC_Core,
  266	BIC_CPU,
  267	BIC_APIC,
  268	BIC_X2APIC,
  269	BIC_Die,
  270	BIC_L3,
  271	BIC_GFXACTMHz,
  272	BIC_IPC,
  273	BIC_CORE_THROT_CNT,
  274	BIC_UNCORE_MHZ,
  275	BIC_SAM_mc6,
  276	BIC_SAMMHz,
  277	BIC_SAMACTMHz,
  278	BIC_Diec6,
  279	BIC_SysWatt,
  280	BIC_Sys_J,
  281	BIC_NMI,
  282	BIC_CPU_c1e,
  283	BIC_pct_idle,
  284	BIC_LLC_RPS,
  285	BIC_LLC_HIT,
  286	MAX_BIC
  287};
  288
  289void print_bic_set(char *s, cpu_set_t *set)
  290{
  291	int i;
  292
  293	assert(MAX_BIC < CPU_SETSIZE);
  294
  295	printf("%s:", s);
  296
  297	for (i = 0; i <= MAX_BIC; ++i) {
  298
  299		if (CPU_ISSET(i, set)) {
  300			assert(i < MAX_BIC);
  301			printf(" %s", bic[i].name);
  302		}
  303	}
  304	putchar('\n');
  305}
  306
  307static cpu_set_t bic_group_topology;
  308static cpu_set_t bic_group_thermal_pwr;
  309static cpu_set_t bic_group_frequency;
  310static cpu_set_t bic_group_hw_idle;
  311static cpu_set_t bic_group_sw_idle;
  312static cpu_set_t bic_group_idle;
  313static cpu_set_t bic_group_cache;
  314static cpu_set_t bic_group_other;
  315static cpu_set_t bic_group_disabled_by_default;
  316static cpu_set_t bic_enabled;
  317static cpu_set_t bic_present;
  318
  319/* modify */
  320#define BIC_INIT(set) CPU_ZERO(set)
  321
  322#define SET_BIC(COUNTER_NUMBER, set) CPU_SET(COUNTER_NUMBER, set)
  323#define CLR_BIC(COUNTER_NUMBER, set) CPU_CLR(COUNTER_NUMBER, set)
  324
  325#define BIC_PRESENT(COUNTER_NUMBER) SET_BIC(COUNTER_NUMBER, &bic_present)
  326#define BIC_NOT_PRESENT(COUNTER_NUMBER) CPU_CLR(COUNTER_NUMBER, &bic_present)
  327
  328/* test */
  329#define BIC_IS_ENABLED(COUNTER_NUMBER) CPU_ISSET(COUNTER_NUMBER, &bic_enabled)
  330#define DO_BIC_READ(COUNTER_NUMBER) CPU_ISSET(COUNTER_NUMBER, &bic_present)
  331#define DO_BIC(COUNTER_NUMBER) (CPU_ISSET(COUNTER_NUMBER, &bic_enabled) && CPU_ISSET(COUNTER_NUMBER, &bic_present))
  332
  333static void bic_set_all(cpu_set_t *set)
  334{
  335	int i;
  336
  337	assert(MAX_BIC < CPU_SETSIZE);
  338
  339	for (i = 0; i < MAX_BIC; ++i)
  340		SET_BIC(i, set);
  341}
  342
  343/*
  344 * bic_clear_bits()
  345 * clear all the bits from "clr" in "dst"
  346 */
  347static void bic_clear_bits(cpu_set_t *dst, cpu_set_t *clr)
  348{
  349	int i;
  350
  351	assert(MAX_BIC < CPU_SETSIZE);
  352
  353	for (i = 0; i < MAX_BIC; ++i)
  354		if (CPU_ISSET(i, clr))
  355			CLR_BIC(i, dst);
  356}
  357
  358static void bic_groups_init(void)
  359{
  360	BIC_INIT(&bic_group_topology);
  361	SET_BIC(BIC_Package, &bic_group_topology);
  362	SET_BIC(BIC_Node, &bic_group_topology);
  363	SET_BIC(BIC_CoreCnt, &bic_group_topology);
  364	SET_BIC(BIC_PkgCnt, &bic_group_topology);
  365	SET_BIC(BIC_Core, &bic_group_topology);
  366	SET_BIC(BIC_CPU, &bic_group_topology);
  367	SET_BIC(BIC_Die, &bic_group_topology);
  368	SET_BIC(BIC_L3, &bic_group_topology);
  369
  370	BIC_INIT(&bic_group_thermal_pwr);
  371	SET_BIC(BIC_CoreTmp, &bic_group_thermal_pwr);
  372	SET_BIC(BIC_PkgTmp, &bic_group_thermal_pwr);
  373	SET_BIC(BIC_PkgWatt, &bic_group_thermal_pwr);
  374	SET_BIC(BIC_CorWatt, &bic_group_thermal_pwr);
  375	SET_BIC(BIC_GFXWatt, &bic_group_thermal_pwr);
  376	SET_BIC(BIC_RAMWatt, &bic_group_thermal_pwr);
  377	SET_BIC(BIC_PKG__, &bic_group_thermal_pwr);
  378	SET_BIC(BIC_RAM__, &bic_group_thermal_pwr);
  379	SET_BIC(BIC_SysWatt, &bic_group_thermal_pwr);
  380
  381	BIC_INIT(&bic_group_frequency);
  382	SET_BIC(BIC_Avg_MHz, &bic_group_frequency);
  383	SET_BIC(BIC_Busy, &bic_group_frequency);
  384	SET_BIC(BIC_Bzy_MHz, &bic_group_frequency);
  385	SET_BIC(BIC_TSC_MHz, &bic_group_frequency);
  386	SET_BIC(BIC_GFXMHz, &bic_group_frequency);
  387	SET_BIC(BIC_GFXACTMHz, &bic_group_frequency);
  388	SET_BIC(BIC_SAMMHz, &bic_group_frequency);
  389	SET_BIC(BIC_SAMACTMHz, &bic_group_frequency);
  390	SET_BIC(BIC_UNCORE_MHZ, &bic_group_frequency);
  391
  392	BIC_INIT(&bic_group_hw_idle);
  393	SET_BIC(BIC_Busy, &bic_group_hw_idle);
  394	SET_BIC(BIC_CPU_c1, &bic_group_hw_idle);
  395	SET_BIC(BIC_CPU_c3, &bic_group_hw_idle);
  396	SET_BIC(BIC_CPU_c6, &bic_group_hw_idle);
  397	SET_BIC(BIC_CPU_c7, &bic_group_hw_idle);
  398	SET_BIC(BIC_GFX_rc6, &bic_group_hw_idle);
  399	SET_BIC(BIC_Pkgpc2, &bic_group_hw_idle);
  400	SET_BIC(BIC_Pkgpc3, &bic_group_hw_idle);
  401	SET_BIC(BIC_Pkgpc6, &bic_group_hw_idle);
  402	SET_BIC(BIC_Pkgpc7, &bic_group_hw_idle);
  403	SET_BIC(BIC_Pkgpc8, &bic_group_hw_idle);
  404	SET_BIC(BIC_Pkgpc9, &bic_group_hw_idle);
  405	SET_BIC(BIC_Pkgpc10, &bic_group_hw_idle);
  406	SET_BIC(BIC_CPU_LPI, &bic_group_hw_idle);
  407	SET_BIC(BIC_SYS_LPI, &bic_group_hw_idle);
  408	SET_BIC(BIC_Mod_c6, &bic_group_hw_idle);
  409	SET_BIC(BIC_Totl_c0, &bic_group_hw_idle);
  410	SET_BIC(BIC_Any_c0, &bic_group_hw_idle);
  411	SET_BIC(BIC_GFX_c0, &bic_group_hw_idle);
  412	SET_BIC(BIC_CPUGFX, &bic_group_hw_idle);
  413	SET_BIC(BIC_SAM_mc6, &bic_group_hw_idle);
  414	SET_BIC(BIC_Diec6, &bic_group_hw_idle);
  415
  416	BIC_INIT(&bic_group_sw_idle);
  417	SET_BIC(BIC_Busy, &bic_group_sw_idle);
  418	SET_BIC(BIC_cpuidle, &bic_group_sw_idle);
  419	SET_BIC(BIC_pct_idle, &bic_group_sw_idle);
  420
  421	BIC_INIT(&bic_group_idle);
  422
  423	CPU_OR(&bic_group_idle, &bic_group_idle, &bic_group_hw_idle);
  424	SET_BIC(BIC_pct_idle, &bic_group_idle);
  425
  426	BIC_INIT(&bic_group_cache);
  427	SET_BIC(BIC_LLC_RPS, &bic_group_cache);
  428	SET_BIC(BIC_LLC_HIT, &bic_group_cache);
  429
  430	BIC_INIT(&bic_group_other);
  431	SET_BIC(BIC_IRQ, &bic_group_other);
  432	SET_BIC(BIC_NMI, &bic_group_other);
  433	SET_BIC(BIC_SMI, &bic_group_other);
  434	SET_BIC(BIC_ThreadC, &bic_group_other);
  435	SET_BIC(BIC_CoreTmp, &bic_group_other);
  436	SET_BIC(BIC_IPC, &bic_group_other);
  437
  438	BIC_INIT(&bic_group_disabled_by_default);
  439	SET_BIC(BIC_USEC, &bic_group_disabled_by_default);
  440	SET_BIC(BIC_TOD, &bic_group_disabled_by_default);
  441	SET_BIC(BIC_cpuidle, &bic_group_disabled_by_default);
  442	SET_BIC(BIC_APIC, &bic_group_disabled_by_default);
  443	SET_BIC(BIC_X2APIC, &bic_group_disabled_by_default);
  444
  445	BIC_INIT(&bic_enabled);
  446	bic_set_all(&bic_enabled);
  447	bic_clear_bits(&bic_enabled, &bic_group_disabled_by_default);
  448
  449	BIC_INIT(&bic_present);
  450	SET_BIC(BIC_USEC, &bic_present);
  451	SET_BIC(BIC_TOD, &bic_present);
  452	SET_BIC(BIC_cpuidle, &bic_present);
  453	SET_BIC(BIC_APIC, &bic_present);
  454	SET_BIC(BIC_X2APIC, &bic_present);
  455	SET_BIC(BIC_pct_idle, &bic_present);
  456}
  457
  458/*
  459 * MSR_PKG_CST_CONFIG_CONTROL decoding for pkg_cstate_limit:
  460 * If you change the values, note they are used both in comparisons
  461 * (>= PCL__7) and to index pkg_cstate_limit_strings[].
  462 */
  463#define PCLUKN 0		/* Unknown */
  464#define PCLRSV 1		/* Reserved */
  465#define PCL__0 2		/* PC0 */
  466#define PCL__1 3		/* PC1 */
  467#define PCL__2 4		/* PC2 */
  468#define PCL__3 5		/* PC3 */
  469#define PCL__4 6		/* PC4 */
  470#define PCL__6 7		/* PC6 */
  471#define PCL_6N 8		/* PC6 No Retention */
  472#define PCL_6R 9		/* PC6 Retention */
  473#define PCL__7 10		/* PC7 */
  474#define PCL_7S 11		/* PC7 Shrink */
  475#define PCL__8 12		/* PC8 */
  476#define PCL__9 13		/* PC9 */
  477#define PCL_10 14		/* PC10 */
  478#define PCLUNL 15		/* Unlimited */
  479
  480char *proc_stat = "/proc/stat";
  481FILE *outf;
  482int *fd_percpu;
  483int *fd_instr_count_percpu;
  484int *fd_llc_percpu;
  485struct timeval interval_tv = { 5, 0 };
  486struct timespec interval_ts = { 5, 0 };
  487
  488unsigned int num_iterations;
  489unsigned int header_iterations;
  490unsigned int debug;
  491unsigned int quiet;
  492unsigned int shown;
  493unsigned int sums_need_wide_columns;
  494unsigned int rapl_joules;
  495unsigned int valid_rapl_msrs;
  496unsigned int summary_only;
  497unsigned int list_header_only;
  498unsigned int dump_only;
  499unsigned int force_load;
  500unsigned int cpuid_has_aperf_mperf;
  501unsigned int has_aperf_access;
  502unsigned int has_epb;
  503unsigned int has_turbo;
  504unsigned int is_hybrid;
  505unsigned int units = 1000000;	/* MHz etc */
  506unsigned int genuine_intel;
  507unsigned int authentic_amd;
  508unsigned int hygon_genuine;
  509unsigned int max_level, max_extended_level;
  510unsigned int has_invariant_tsc;
  511unsigned int aperf_mperf_multiplier = 1;
  512double bclk;
  513double base_hz;
  514unsigned int has_base_hz;
  515double tsc_tweak = 1.0;
  516unsigned int show_pkg_only;
  517unsigned int show_core_only;
  518char *output_buffer, *outp;
  519unsigned int do_dts;
  520unsigned int do_ptm;
  521unsigned int do_ipc;
  522unsigned long long cpuidle_cur_cpu_lpi_us;
  523unsigned long long cpuidle_cur_sys_lpi_us;
  524unsigned int tj_max;
  525unsigned int tj_max_override;
  526double rapl_power_units, rapl_time_units;
  527double rapl_dram_energy_units, rapl_energy_units, rapl_psys_energy_units;
  528double rapl_joule_counter_range;
  529unsigned int crystal_hz;
  530unsigned long long tsc_hz;
  531int base_cpu;
  532unsigned int has_hwp;		/* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */
  533			/* IA32_HWP_REQUEST, IA32_HWP_STATUS */
  534unsigned int has_hwp_notify;	/* IA32_HWP_INTERRUPT */
  535unsigned int has_hwp_activity_window;	/* IA32_HWP_REQUEST[bits 41:32] */
  536unsigned int has_hwp_epp;	/* IA32_HWP_REQUEST[bits 31:24] */
  537unsigned int has_hwp_pkg;	/* IA32_HWP_REQUEST_PKG */
  538unsigned int first_counter_read = 1;
  539
  540static struct timeval procsysfs_tv_begin;
  541
  542int ignore_stdin;
  543bool no_msr;
  544bool no_perf;
  545
  546enum gfx_sysfs_idx {
  547	GFX_rc6,
  548	GFX_MHz,
  549	GFX_ACTMHz,
  550	SAM_mc6,
  551	SAM_MHz,
  552	SAM_ACTMHz,
  553	GFX_MAX
  554};
  555
  556struct gfx_sysfs_info {
  557	FILE *fp;
  558	unsigned int val;
  559	unsigned long long val_ull;
  560};
  561
  562static struct gfx_sysfs_info gfx_info[GFX_MAX];
  563
  564int get_msr(int cpu, off_t offset, unsigned long long *msr);
  565int add_counter(unsigned int msr_num, char *path, char *name,
  566		unsigned int width, enum counter_scope scope, enum counter_type type, enum counter_format format, int flags, int package_num);
  567
  568/* Model specific support Start */
  569
  570/* List of features that may diverge among different platforms */
  571struct platform_features {
  572	bool has_msr_misc_feature_control;	/* MSR_MISC_FEATURE_CONTROL */
  573	bool has_msr_misc_pwr_mgmt;	/* MSR_MISC_PWR_MGMT */
  574	bool has_nhm_msrs;	/* MSR_PLATFORM_INFO, MSR_IA32_TEMPERATURE_TARGET, MSR_SMI_COUNT, MSR_PKG_CST_CONFIG_CONTROL, MSR_IA32_POWER_CTL, TRL MSRs */
  575	bool has_config_tdp;	/* MSR_CONFIG_TDP_NOMINAL/LEVEL_1/LEVEL_2/CONTROL, MSR_TURBO_ACTIVATION_RATIO */
  576	int bclk_freq;		/* CPU base clock */
  577	int crystal_freq;	/* Crystal clock to use when not available from CPUID.15 */
  578	int supported_cstates;	/* Core cstates and Package cstates supported */
  579	int cst_limit;		/* MSR_PKG_CST_CONFIG_CONTROL */
  580	bool has_cst_auto_convension;	/* AUTOMATIC_CSTATE_CONVERSION bit in MSR_PKG_CST_CONFIG_CONTROL */
  581	bool has_irtl_msrs;	/* MSR_PKGC3/PKGC6/PKGC7/PKGC8/PKGC9/PKGC10_IRTL */
  582	bool has_msr_core_c1_res;	/* MSR_CORE_C1_RES */
  583	bool has_msr_module_c6_res_ms;	/* MSR_MODULE_C6_RES_MS */
  584	bool has_msr_c6_demotion_policy_config;	/* MSR_CC6_DEMOTION_POLICY_CONFIG/MSR_MC6_DEMOTION_POLICY_CONFIG */
  585	bool has_msr_atom_pkg_c6_residency;	/* MSR_ATOM_PKG_C6_RESIDENCY */
  586	bool has_msr_knl_core_c6_residency;	/* MSR_KNL_CORE_C6_RESIDENCY */
  587	bool has_ext_cst_msrs;	/* MSR_PKG_WEIGHTED_CORE_C0_RES/MSR_PKG_ANY_CORE_C0_RES/MSR_PKG_ANY_GFXE_C0_RES/MSR_PKG_BOTH_CORE_GFXE_C0_RES */
  588	bool has_cst_prewake_bit;	/* Cstate prewake bit in MSR_IA32_POWER_CTL */
  589	int trl_msrs;		/* MSR_TURBO_RATIO_LIMIT/LIMIT1/LIMIT2/SECONDARY, Atom TRL MSRs */
  590	int plr_msrs;		/* MSR_CORE/GFX/RING_PERF_LIMIT_REASONS */
  591	int plat_rapl_msrs;	/* RAPL PKG/DRAM/CORE/GFX MSRs, AMD RAPL MSRs */
  592	bool has_per_core_rapl;	/* Indicates cores energy collection is per-core, not per-package. AMD specific for now */
  593	bool has_rapl_divisor;	/* Divisor for Energy unit raw value from MSR_RAPL_POWER_UNIT */
  594	bool has_fixed_rapl_unit;	/* Fixed Energy Unit used for DRAM RAPL Domain */
  595	bool has_fixed_rapl_psys_unit;	/* Fixed Energy Unit used for PSYS RAPL Domain */
  596	int rapl_quirk_tdp;	/* Hardcoded TDP value when cannot be retrieved from hardware */
  597	int tcc_offset_bits;	/* TCC Offset bits in MSR_IA32_TEMPERATURE_TARGET */
  598	bool enable_tsc_tweak;	/* Use CPU Base freq instead of TSC freq for aperf/mperf counter */
  599	bool need_perf_multiplier;	/* mperf/aperf multiplier */
  600};
  601
  602struct platform_data {
  603	unsigned int vfm;
  604	const struct platform_features *features;
  605};
  606
  607/* For BCLK */
  608enum bclk_freq {
  609	BCLK_100MHZ = 1,
  610	BCLK_133MHZ,
  611	BCLK_SLV,
  612};
  613
  614#define SLM_BCLK_FREQS 5
  615double slm_freq_table[SLM_BCLK_FREQS] = { 83.3, 100.0, 133.3, 116.7, 80.0 };
  616
  617double slm_bclk(void)
  618{
  619	unsigned long long msr = 3;
  620	unsigned int i;
  621	double freq;
  622
  623	if (get_msr(base_cpu, MSR_FSB_FREQ, &msr))
  624		fprintf(outf, "SLM BCLK: unknown\n");
  625
  626	i = msr & 0xf;
  627	if (i >= SLM_BCLK_FREQS) {
  628		fprintf(outf, "SLM BCLK[%d] invalid\n", i);
  629		i = 3;
  630	}
  631	freq = slm_freq_table[i];
  632
  633	if (!quiet)
  634		fprintf(outf, "SLM BCLK: %.1f Mhz\n", freq);
  635
  636	return freq;
  637}
  638
  639/* For Package cstate limit */
  640enum package_cstate_limit {
  641	CST_LIMIT_NHM = 1,
  642	CST_LIMIT_SNB,
  643	CST_LIMIT_HSW,
  644	CST_LIMIT_SKX,
  645	CST_LIMIT_ICX,
  646	CST_LIMIT_SLV,
  647	CST_LIMIT_AMT,
  648	CST_LIMIT_KNL,
  649	CST_LIMIT_GMT,
  650};
  651
  652/* For Turbo Ratio Limit MSRs */
  653enum turbo_ratio_limit_msrs {
  654	TRL_BASE = BIT(0),
  655	TRL_LIMIT1 = BIT(1),
  656	TRL_LIMIT2 = BIT(2),
  657	TRL_ATOM = BIT(3),
  658	TRL_KNL = BIT(4),
  659	TRL_CORECOUNT = BIT(5),
  660};
  661
  662/* For Perf Limit Reason MSRs */
  663enum perf_limit_reason_msrs {
  664	PLR_CORE = BIT(0),
  665	PLR_GFX = BIT(1),
  666	PLR_RING = BIT(2),
  667};
  668
  669/* For RAPL MSRs */
  670enum rapl_msrs {
  671	RAPL_PKG_POWER_LIMIT = BIT(0),	/* 0x610 MSR_PKG_POWER_LIMIT */
  672	RAPL_PKG_ENERGY_STATUS = BIT(1),	/* 0x611 MSR_PKG_ENERGY_STATUS */
  673	RAPL_PKG_PERF_STATUS = BIT(2),	/* 0x613 MSR_PKG_PERF_STATUS */
  674	RAPL_PKG_POWER_INFO = BIT(3),	/* 0x614 MSR_PKG_POWER_INFO */
  675	RAPL_DRAM_POWER_LIMIT = BIT(4),	/* 0x618 MSR_DRAM_POWER_LIMIT */
  676	RAPL_DRAM_ENERGY_STATUS = BIT(5),	/* 0x619 MSR_DRAM_ENERGY_STATUS */
  677	RAPL_DRAM_PERF_STATUS = BIT(6),	/* 0x61b MSR_DRAM_PERF_STATUS */
  678	RAPL_DRAM_POWER_INFO = BIT(7),	/* 0x61c MSR_DRAM_POWER_INFO */
  679	RAPL_CORE_POWER_LIMIT = BIT(8),	/* 0x638 MSR_PP0_POWER_LIMIT */
  680	RAPL_CORE_ENERGY_STATUS = BIT(9),	/* 0x639 MSR_PP0_ENERGY_STATUS */
  681	RAPL_CORE_POLICY = BIT(10),	/* 0x63a MSR_PP0_POLICY */
  682	RAPL_GFX_POWER_LIMIT = BIT(11),	/* 0x640 MSR_PP1_POWER_LIMIT */
  683	RAPL_GFX_ENERGY_STATUS = BIT(12),	/* 0x641 MSR_PP1_ENERGY_STATUS */
  684	RAPL_GFX_POLICY = BIT(13),	/* 0x642 MSR_PP1_POLICY */
  685	RAPL_AMD_PWR_UNIT = BIT(14),	/* 0xc0010299 MSR_AMD_RAPL_POWER_UNIT */
  686	RAPL_AMD_CORE_ENERGY_STAT = BIT(15),	/* 0xc001029a MSR_AMD_CORE_ENERGY_STATUS */
  687	RAPL_AMD_PKG_ENERGY_STAT = BIT(16),	/* 0xc001029b MSR_AMD_PKG_ENERGY_STATUS */
  688	RAPL_PLATFORM_ENERGY_LIMIT = BIT(17),	/* 0x64c MSR_PLATFORM_ENERGY_LIMIT */
  689	RAPL_PLATFORM_ENERGY_STATUS = BIT(18),	/* 0x64d MSR_PLATFORM_ENERGY_STATUS */
  690};
  691
  692#define RAPL_PKG	(RAPL_PKG_ENERGY_STATUS | RAPL_PKG_POWER_LIMIT)
  693#define RAPL_DRAM	(RAPL_DRAM_ENERGY_STATUS | RAPL_DRAM_POWER_LIMIT)
  694#define RAPL_CORE	(RAPL_CORE_ENERGY_STATUS | RAPL_CORE_POWER_LIMIT)
  695#define RAPL_GFX	(RAPL_GFX_POWER_LIMIT | RAPL_GFX_ENERGY_STATUS)
  696#define RAPL_PSYS	(RAPL_PLATFORM_ENERGY_STATUS | RAPL_PLATFORM_ENERGY_LIMIT)
  697
  698#define RAPL_PKG_ALL	(RAPL_PKG | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO)
  699#define RAPL_DRAM_ALL	(RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_DRAM_POWER_INFO)
  700#define RAPL_CORE_ALL	(RAPL_CORE | RAPL_CORE_POLICY)
  701#define RAPL_GFX_ALL	(RAPL_GFX | RAPL_GFX_POLICY)
  702
  703#define RAPL_AMD_F17H	(RAPL_AMD_PWR_UNIT | RAPL_AMD_CORE_ENERGY_STAT | RAPL_AMD_PKG_ENERGY_STAT)
  704
  705/* For Cstates */
  706enum cstates {
  707	CC1 = BIT(0),
  708	CC3 = BIT(1),
  709	CC6 = BIT(2),
  710	CC7 = BIT(3),
  711	PC2 = BIT(4),
  712	PC3 = BIT(5),
  713	PC6 = BIT(6),
  714	PC7 = BIT(7),
  715	PC8 = BIT(8),
  716	PC9 = BIT(9),
  717	PC10 = BIT(10),
  718};
  719
  720static const struct platform_features nhm_features = {
  721	.has_msr_misc_pwr_mgmt = 1,
  722	.has_nhm_msrs = 1,
  723	.bclk_freq = BCLK_133MHZ,
  724	.supported_cstates = CC1 | CC3 | CC6 | PC3 | PC6,
  725	.cst_limit = CST_LIMIT_NHM,
  726	.trl_msrs = TRL_BASE,
  727};
  728
  729static const struct platform_features nhx_features = {
  730	.has_msr_misc_pwr_mgmt = 1,
  731	.has_nhm_msrs = 1,
  732	.bclk_freq = BCLK_133MHZ,
  733	.supported_cstates = CC1 | CC3 | CC6 | PC3 | PC6,
  734	.cst_limit = CST_LIMIT_NHM,
  735};
  736
  737static const struct platform_features snb_features = {
  738	.has_msr_misc_feature_control = 1,
  739	.has_msr_misc_pwr_mgmt = 1,
  740	.has_nhm_msrs = 1,
  741	.bclk_freq = BCLK_100MHZ,
  742	.supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7,
  743	.cst_limit = CST_LIMIT_SNB,
  744	.has_irtl_msrs = 1,
  745	.trl_msrs = TRL_BASE,
  746	.plat_rapl_msrs = RAPL_PKG | RAPL_CORE_ALL | RAPL_GFX | RAPL_PKG_POWER_INFO,
  747};
  748
  749static const struct platform_features snx_features = {
  750	.has_msr_misc_feature_control = 1,
  751	.has_msr_misc_pwr_mgmt = 1,
  752	.has_nhm_msrs = 1,
  753	.bclk_freq = BCLK_100MHZ,
  754	.supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7,
  755	.cst_limit = CST_LIMIT_SNB,
  756	.has_irtl_msrs = 1,
  757	.trl_msrs = TRL_BASE,
  758	.plat_rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM_ALL,
  759};
  760
  761static const struct platform_features ivb_features = {
  762	.has_msr_misc_feature_control = 1,
  763	.has_msr_misc_pwr_mgmt = 1,
  764	.has_nhm_msrs = 1,
  765	.has_config_tdp = 1,
  766	.bclk_freq = BCLK_100MHZ,
  767	.supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7,
  768	.cst_limit = CST_LIMIT_SNB,
  769	.has_irtl_msrs = 1,
  770	.trl_msrs = TRL_BASE,
  771	.plat_rapl_msrs = RAPL_PKG | RAPL_CORE_ALL | RAPL_GFX | RAPL_PKG_POWER_INFO,
  772};
  773
  774static const struct platform_features ivx_features = {
  775	.has_msr_misc_feature_control = 1,
  776	.has_msr_misc_pwr_mgmt = 1,
  777	.has_nhm_msrs = 1,
  778	.bclk_freq = BCLK_100MHZ,
  779	.supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7,
  780	.cst_limit = CST_LIMIT_SNB,
  781	.has_irtl_msrs = 1,
  782	.trl_msrs = TRL_BASE | TRL_LIMIT1,
  783	.plat_rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM_ALL,
  784};
  785
  786static const struct platform_features hsw_features = {
  787	.has_msr_misc_feature_control = 1,
  788	.has_msr_misc_pwr_mgmt = 1,
  789	.has_nhm_msrs = 1,
  790	.has_config_tdp = 1,
  791	.bclk_freq = BCLK_100MHZ,
  792	.supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7,
  793	.cst_limit = CST_LIMIT_HSW,
  794	.has_irtl_msrs = 1,
  795	.trl_msrs = TRL_BASE,
  796	.plr_msrs = PLR_CORE | PLR_GFX | PLR_RING,
  797	.plat_rapl_msrs = RAPL_PKG | RAPL_CORE_ALL | RAPL_GFX | RAPL_PKG_POWER_INFO,
  798};
  799
  800static const struct platform_features hsx_features = {
  801	.has_msr_misc_feature_control = 1,
  802	.has_msr_misc_pwr_mgmt = 1,
  803	.has_nhm_msrs = 1,
  804	.has_config_tdp = 1,
  805	.bclk_freq = BCLK_100MHZ,
  806	.supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7,
  807	.cst_limit = CST_LIMIT_HSW,
  808	.has_irtl_msrs = 1,
  809	.trl_msrs = TRL_BASE | TRL_LIMIT1 | TRL_LIMIT2,
  810	.plr_msrs = PLR_CORE | PLR_RING,
  811	.plat_rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL,
  812	.has_fixed_rapl_unit = 1,
  813};
  814
  815static const struct platform_features hswl_features = {
  816	.has_msr_misc_feature_control = 1,
  817	.has_msr_misc_pwr_mgmt = 1,
  818	.has_nhm_msrs = 1,
  819	.has_config_tdp = 1,
  820	.bclk_freq = BCLK_100MHZ,
  821	.supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7 | PC8 | PC9 | PC10,
  822	.cst_limit = CST_LIMIT_HSW,
  823	.has_irtl_msrs = 1,
  824	.trl_msrs = TRL_BASE,
  825	.plr_msrs = PLR_CORE | PLR_GFX | PLR_RING,
  826	.plat_rapl_msrs = RAPL_PKG | RAPL_CORE_ALL | RAPL_GFX | RAPL_PKG_POWER_INFO,
  827};
  828
  829static const struct platform_features hswg_features = {
  830	.has_msr_misc_feature_control = 1,
  831	.has_msr_misc_pwr_mgmt = 1,
  832	.has_nhm_msrs = 1,
  833	.has_config_tdp = 1,
  834	.bclk_freq = BCLK_100MHZ,
  835	.supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7,
  836	.cst_limit = CST_LIMIT_HSW,
  837	.has_irtl_msrs = 1,
  838	.trl_msrs = TRL_BASE,
  839	.plr_msrs = PLR_CORE | PLR_GFX | PLR_RING,
  840	.plat_rapl_msrs = RAPL_PKG | RAPL_CORE_ALL | RAPL_GFX | RAPL_PKG_POWER_INFO,
  841};
  842
  843static const struct platform_features bdw_features = {
  844	.has_msr_misc_feature_control = 1,
  845	.has_msr_misc_pwr_mgmt = 1,
  846	.has_nhm_msrs = 1,
  847	.has_config_tdp = 1,
  848	.bclk_freq = BCLK_100MHZ,
  849	.supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7 | PC8 | PC9 | PC10,
  850	.cst_limit = CST_LIMIT_HSW,
  851	.has_irtl_msrs = 1,
  852	.trl_msrs = TRL_BASE,
  853	.plat_rapl_msrs = RAPL_PKG | RAPL_CORE_ALL | RAPL_GFX | RAPL_PKG_POWER_INFO,
  854};
  855
  856static const struct platform_features bdwg_features = {
  857	.has_msr_misc_feature_control = 1,
  858	.has_msr_misc_pwr_mgmt = 1,
  859	.has_nhm_msrs = 1,
  860	.has_config_tdp = 1,
  861	.bclk_freq = BCLK_100MHZ,
  862	.supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7,
  863	.cst_limit = CST_LIMIT_HSW,
  864	.has_irtl_msrs = 1,
  865	.trl_msrs = TRL_BASE,
  866	.plat_rapl_msrs = RAPL_PKG | RAPL_CORE_ALL | RAPL_GFX | RAPL_PKG_POWER_INFO,
  867};
  868
  869static const struct platform_features bdx_features = {
  870	.has_msr_misc_feature_control = 1,
  871	.has_msr_misc_pwr_mgmt = 1,
  872	.has_nhm_msrs = 1,
  873	.has_config_tdp = 1,
  874	.bclk_freq = BCLK_100MHZ,
  875	.supported_cstates = CC1 | CC3 | CC6 | PC2 | PC3 | PC6,
  876	.cst_limit = CST_LIMIT_HSW,
  877	.has_irtl_msrs = 1,
  878	.has_cst_auto_convension = 1,
  879	.trl_msrs = TRL_BASE,
  880	.plat_rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL,
  881	.has_fixed_rapl_unit = 1,
  882};
  883
  884static const struct platform_features skl_features = {
  885	.has_msr_misc_feature_control = 1,
  886	.has_msr_misc_pwr_mgmt = 1,
  887	.has_nhm_msrs = 1,
  888	.has_config_tdp = 1,
  889	.bclk_freq = BCLK_100MHZ,
  890	.crystal_freq = 24000000,
  891	.supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7 | PC8 | PC9 | PC10,
  892	.cst_limit = CST_LIMIT_HSW,
  893	.has_irtl_msrs = 1,
  894	.has_ext_cst_msrs = 1,
  895	.trl_msrs = TRL_BASE,
  896	.tcc_offset_bits = 6,
  897	.plat_rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_GFX | RAPL_PSYS,
  898	.enable_tsc_tweak = 1,
  899};
  900
  901static const struct platform_features cnl_features = {
  902	.has_msr_misc_feature_control = 1,
  903	.has_msr_misc_pwr_mgmt = 1,
  904	.has_nhm_msrs = 1,
  905	.has_config_tdp = 1,
  906	.bclk_freq = BCLK_100MHZ,
  907	.supported_cstates = CC1 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7 | PC8 | PC9 | PC10,
  908	.cst_limit = CST_LIMIT_HSW,
  909	.has_irtl_msrs = 1,
  910	.has_msr_core_c1_res = 1,
  911	.has_ext_cst_msrs = 1,
  912	.trl_msrs = TRL_BASE,
  913	.tcc_offset_bits = 6,
  914	.plat_rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_GFX | RAPL_PSYS,
  915	.enable_tsc_tweak = 1,
  916};
  917
  918/* Copied from cnl_features, with PC7/PC9 removed */
  919static const struct platform_features adl_features = {
  920	.has_msr_misc_feature_control	= cnl_features.has_msr_misc_feature_control,
  921	.has_msr_misc_pwr_mgmt		= cnl_features.has_msr_misc_pwr_mgmt,
  922	.has_nhm_msrs			= cnl_features.has_nhm_msrs,
  923	.has_config_tdp			= cnl_features.has_config_tdp,
  924	.bclk_freq			= cnl_features.bclk_freq,
  925	.supported_cstates		= CC1 | CC6 | CC7 | PC2 | PC3 | PC6 | PC8 | PC10,
  926	.cst_limit			= cnl_features.cst_limit,
  927	.has_irtl_msrs			= cnl_features.has_irtl_msrs,
  928	.has_msr_core_c1_res		= cnl_features.has_msr_core_c1_res,
  929	.has_ext_cst_msrs		= cnl_features.has_ext_cst_msrs,
  930	.trl_msrs			= cnl_features.trl_msrs,
  931	.tcc_offset_bits		= cnl_features.tcc_offset_bits,
  932	.plat_rapl_msrs			= cnl_features.plat_rapl_msrs,
  933	.enable_tsc_tweak		= cnl_features.enable_tsc_tweak,
  934};
  935
  936/* Copied from adl_features, with PC3/PC8 removed */
  937static const struct platform_features lnl_features = {
  938	.has_msr_misc_feature_control	= adl_features.has_msr_misc_feature_control,
  939	.has_msr_misc_pwr_mgmt		= adl_features.has_msr_misc_pwr_mgmt,
  940	.has_nhm_msrs			= adl_features.has_nhm_msrs,
  941	.has_config_tdp			= adl_features.has_config_tdp,
  942	.bclk_freq			= adl_features.bclk_freq,
  943	.supported_cstates		= CC1 | CC6 | CC7 | PC2 | PC6 | PC10,
  944	.cst_limit			= adl_features.cst_limit,
  945	.has_irtl_msrs			= adl_features.has_irtl_msrs,
  946	.has_msr_core_c1_res		= adl_features.has_msr_core_c1_res,
  947	.has_ext_cst_msrs		= adl_features.has_ext_cst_msrs,
  948	.trl_msrs			= adl_features.trl_msrs,
  949	.tcc_offset_bits		= adl_features.tcc_offset_bits,
  950	.plat_rapl_msrs			= adl_features.plat_rapl_msrs,
  951	.enable_tsc_tweak		= adl_features.enable_tsc_tweak,
  952};
  953
  954static const struct platform_features skx_features = {
  955	.has_msr_misc_feature_control = 1,
  956	.has_msr_misc_pwr_mgmt = 1,
  957	.has_nhm_msrs = 1,
  958	.has_config_tdp = 1,
  959	.bclk_freq = BCLK_100MHZ,
  960	.supported_cstates = CC1 | CC6 | PC2 | PC6,
  961	.cst_limit = CST_LIMIT_SKX,
  962	.has_irtl_msrs = 1,
  963	.has_cst_auto_convension = 1,
  964	.trl_msrs = TRL_BASE | TRL_CORECOUNT,
  965	.plat_rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL,
  966	.has_fixed_rapl_unit = 1,
  967};
  968
  969static const struct platform_features icx_features = {
  970	.has_msr_misc_feature_control = 1,
  971	.has_msr_misc_pwr_mgmt = 1,
  972	.has_nhm_msrs = 1,
  973	.has_config_tdp = 1,
  974	.bclk_freq = BCLK_100MHZ,
  975	.supported_cstates = CC1 | CC6 | PC2 | PC6,
  976	.cst_limit = CST_LIMIT_ICX,
  977	.has_msr_core_c1_res = 1,
  978	.has_irtl_msrs = 1,
  979	.has_cst_prewake_bit = 1,
  980	.trl_msrs = TRL_BASE | TRL_CORECOUNT,
  981	.plat_rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL | RAPL_PSYS,
  982	.has_fixed_rapl_unit = 1,
  983};
  984
  985static const struct platform_features spr_features = {
  986	.has_msr_misc_feature_control = 1,
  987	.has_msr_misc_pwr_mgmt = 1,
  988	.has_nhm_msrs = 1,
  989	.has_config_tdp = 1,
  990	.bclk_freq = BCLK_100MHZ,
  991	.supported_cstates = CC1 | CC6 | PC2 | PC6,
  992	.cst_limit = CST_LIMIT_SKX,
  993	.has_msr_core_c1_res = 1,
  994	.has_irtl_msrs = 1,
  995	.has_cst_prewake_bit = 1,
  996	.has_fixed_rapl_psys_unit = 1,
  997	.trl_msrs = TRL_BASE | TRL_CORECOUNT,
  998	.plat_rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL | RAPL_PSYS,
  999};
 1000
 1001static const struct platform_features dmr_features = {
 1002	.has_msr_misc_feature_control	= spr_features.has_msr_misc_feature_control,
 1003	.has_msr_misc_pwr_mgmt		= spr_features.has_msr_misc_pwr_mgmt,
 1004	.has_nhm_msrs			= spr_features.has_nhm_msrs,
 1005	.bclk_freq			= spr_features.bclk_freq,
 1006	.supported_cstates		= spr_features.supported_cstates,
 1007	.cst_limit			= spr_features.cst_limit,
 1008	.has_msr_core_c1_res		= spr_features.has_msr_core_c1_res,
 1009	.has_cst_prewake_bit		= spr_features.has_cst_prewake_bit,
 1010	.has_fixed_rapl_psys_unit	= spr_features.has_fixed_rapl_psys_unit,
 1011	.trl_msrs			= spr_features.trl_msrs,
 1012	.has_msr_module_c6_res_ms	= 1,	/* DMR has Dual-Core-Module and MC6 MSR */
 1013	.plat_rapl_msrs			= 0,	/* DMR does not have RAPL MSRs */
 1014	.plr_msrs			= 0,	/* DMR does not have PLR  MSRs */
 1015	.has_irtl_msrs			= 0,	/* DMR does not have IRTL MSRs */
 1016	.has_config_tdp			= 0,	/* DMR does not have CTDP MSRs */
 1017};
 1018
 1019static const struct platform_features srf_features = {
 1020	.has_msr_misc_feature_control = 1,
 1021	.has_msr_misc_pwr_mgmt = 1,
 1022	.has_nhm_msrs = 1,
 1023	.has_config_tdp = 1,
 1024	.bclk_freq = BCLK_100MHZ,
 1025	.supported_cstates = CC1 | CC6 | PC2 | PC6,
 1026	.cst_limit = CST_LIMIT_SKX,
 1027	.has_msr_core_c1_res = 1,
 1028	.has_msr_module_c6_res_ms = 1,
 1029	.has_irtl_msrs = 1,
 1030	.has_cst_prewake_bit = 1,
 1031	.trl_msrs = TRL_BASE | TRL_CORECOUNT,
 1032	.plat_rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL | RAPL_PSYS,
 1033};
 1034
 1035static const struct platform_features grr_features = {
 1036	.has_msr_misc_feature_control = 1,
 1037	.has_msr_misc_pwr_mgmt = 1,
 1038	.has_nhm_msrs = 1,
 1039	.has_config_tdp = 1,
 1040	.bclk_freq = BCLK_100MHZ,
 1041	.supported_cstates = CC1 | CC6,
 1042	.cst_limit = CST_LIMIT_SKX,
 1043	.has_msr_core_c1_res = 1,
 1044	.has_msr_module_c6_res_ms = 1,
 1045	.has_irtl_msrs = 1,
 1046	.has_cst_prewake_bit = 1,
 1047	.trl_msrs = TRL_BASE | TRL_CORECOUNT,
 1048	.plat_rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL | RAPL_PSYS,
 1049};
 1050
 1051static const struct platform_features slv_features = {
 1052	.has_nhm_msrs = 1,
 1053	.bclk_freq = BCLK_SLV,
 1054	.supported_cstates = CC1 | CC6 | PC6,
 1055	.cst_limit = CST_LIMIT_SLV,
 1056	.has_msr_core_c1_res = 1,
 1057	.has_msr_module_c6_res_ms = 1,
 1058	.has_msr_c6_demotion_policy_config = 1,
 1059	.has_msr_atom_pkg_c6_residency = 1,
 1060	.trl_msrs = TRL_ATOM,
 1061	.plat_rapl_msrs = RAPL_PKG | RAPL_CORE,
 1062	.has_rapl_divisor = 1,
 1063	.rapl_quirk_tdp = 30,
 1064};
 1065
 1066static const struct platform_features slvd_features = {
 1067	.has_msr_misc_pwr_mgmt = 1,
 1068	.has_nhm_msrs = 1,
 1069	.bclk_freq = BCLK_SLV,
 1070	.supported_cstates = CC1 | CC6 | PC3 | PC6,
 1071	.cst_limit = CST_LIMIT_SLV,
 1072	.has_msr_atom_pkg_c6_residency = 1,
 1073	.trl_msrs = TRL_BASE,
 1074	.plat_rapl_msrs = RAPL_PKG | RAPL_CORE,
 1075	.rapl_quirk_tdp = 30,
 1076};
 1077
 1078static const struct platform_features amt_features = {
 1079	.has_nhm_msrs = 1,
 1080	.bclk_freq = BCLK_133MHZ,
 1081	.supported_cstates = CC1 | CC3 | CC6 | PC3 | PC6,
 1082	.cst_limit = CST_LIMIT_AMT,
 1083	.trl_msrs = TRL_BASE,
 1084};
 1085
 1086static const struct platform_features gmt_features = {
 1087	.has_msr_misc_pwr_mgmt = 1,
 1088	.has_nhm_msrs = 1,
 1089	.bclk_freq = BCLK_100MHZ,
 1090	.crystal_freq = 19200000,
 1091	.supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7 | PC8 | PC9 | PC10,
 1092	.cst_limit = CST_LIMIT_GMT,
 1093	.has_irtl_msrs = 1,
 1094	.trl_msrs = TRL_BASE | TRL_CORECOUNT,
 1095	.plat_rapl_msrs = RAPL_PKG | RAPL_PKG_POWER_INFO,
 1096};
 1097
 1098static const struct platform_features gmtd_features = {
 1099	.has_msr_misc_pwr_mgmt = 1,
 1100	.has_nhm_msrs = 1,
 1101	.bclk_freq = BCLK_100MHZ,
 1102	.crystal_freq = 25000000,
 1103	.supported_cstates = CC1 | CC6 | PC2 | PC6,
 1104	.cst_limit = CST_LIMIT_GMT,
 1105	.has_irtl_msrs = 1,
 1106	.has_msr_core_c1_res = 1,
 1107	.trl_msrs = TRL_BASE | TRL_CORECOUNT,
 1108	.plat_rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL | RAPL_CORE_ENERGY_STATUS,
 1109};
 1110
 1111static const struct platform_features gmtp_features = {
 1112	.has_msr_misc_pwr_mgmt = 1,
 1113	.has_nhm_msrs = 1,
 1114	.bclk_freq = BCLK_100MHZ,
 1115	.crystal_freq = 19200000,
 1116	.supported_cstates = CC1 | CC3 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7 | PC8 | PC9 | PC10,
 1117	.cst_limit = CST_LIMIT_GMT,
 1118	.has_irtl_msrs = 1,
 1119	.trl_msrs = TRL_BASE,
 1120	.plat_rapl_msrs = RAPL_PKG | RAPL_PKG_POWER_INFO,
 1121};
 1122
 1123static const struct platform_features tmt_features = {
 1124	.has_msr_misc_pwr_mgmt = 1,
 1125	.has_nhm_msrs = 1,
 1126	.bclk_freq = BCLK_100MHZ,
 1127	.supported_cstates = CC1 | CC6 | CC7 | PC2 | PC3 | PC6 | PC7 | PC8 | PC9 | PC10,
 1128	.cst_limit = CST_LIMIT_GMT,
 1129	.has_irtl_msrs = 1,
 1130	.trl_msrs = TRL_BASE,
 1131	.plat_rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_GFX,
 1132	.enable_tsc_tweak = 1,
 1133};
 1134
 1135static const struct platform_features tmtd_features = {
 1136	.has_msr_misc_pwr_mgmt = 1,
 1137	.has_nhm_msrs = 1,
 1138	.bclk_freq = BCLK_100MHZ,
 1139	.supported_cstates = CC1 | CC6,
 1140	.cst_limit = CST_LIMIT_GMT,
 1141	.has_irtl_msrs = 1,
 1142	.trl_msrs = TRL_BASE | TRL_CORECOUNT,
 1143	.plat_rapl_msrs = RAPL_PKG_ALL,
 1144};
 1145
 1146static const struct platform_features knl_features = {
 1147	.has_msr_misc_pwr_mgmt = 1,
 1148	.has_nhm_msrs = 1,
 1149	.has_config_tdp = 1,
 1150	.bclk_freq = BCLK_100MHZ,
 1151	.supported_cstates = CC1 | CC6 | PC3 | PC6,
 1152	.cst_limit = CST_LIMIT_KNL,
 1153	.has_msr_knl_core_c6_residency = 1,
 1154	.trl_msrs = TRL_KNL,
 1155	.plat_rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL,
 1156	.has_fixed_rapl_unit = 1,
 1157	.need_perf_multiplier = 1,
 1158};
 1159
 1160static const struct platform_features default_features = {
 1161};
 1162
 1163static const struct platform_features amd_features_with_rapl = {
 1164	.plat_rapl_msrs = RAPL_AMD_F17H,
 1165	.has_per_core_rapl = 1,
 1166	.rapl_quirk_tdp = 280,	/* This is the max stock TDP of HEDT/Server Fam17h+ chips */
 1167};
 1168
 1169static const struct platform_data turbostat_pdata[] = {
 1170	{ INTEL_NEHALEM, &nhm_features },
 1171	{ INTEL_NEHALEM_G, &nhm_features },
 1172	{ INTEL_NEHALEM_EP, &nhm_features },
 1173	{ INTEL_NEHALEM_EX, &nhx_features },
 1174	{ INTEL_WESTMERE, &nhm_features },
 1175	{ INTEL_WESTMERE_EP, &nhm_features },
 1176	{ INTEL_WESTMERE_EX, &nhx_features },
 1177	{ INTEL_SANDYBRIDGE, &snb_features },
 1178	{ INTEL_SANDYBRIDGE_X, &snx_features },
 1179	{ INTEL_IVYBRIDGE, &ivb_features },
 1180	{ INTEL_IVYBRIDGE_X, &ivx_features },
 1181	{ INTEL_HASWELL, &hsw_features },
 1182	{ INTEL_HASWELL_X, &hsx_features },
 1183	{ INTEL_HASWELL_L, &hswl_features },
 1184	{ INTEL_HASWELL_G, &hswg_features },
 1185	{ INTEL_BROADWELL, &bdw_features },
 1186	{ INTEL_BROADWELL_G, &bdwg_features },
 1187	{ INTEL_BROADWELL_X, &bdx_features },
 1188	{ INTEL_BROADWELL_D, &bdx_features },
 1189	{ INTEL_SKYLAKE_L, &skl_features },
 1190	{ INTEL_SKYLAKE, &skl_features },
 1191	{ INTEL_SKYLAKE_X, &skx_features },
 1192	{ INTEL_KABYLAKE_L, &skl_features },
 1193	{ INTEL_KABYLAKE, &skl_features },
 1194	{ INTEL_COMETLAKE, &skl_features },
 1195	{ INTEL_COMETLAKE_L, &skl_features },
 1196	{ INTEL_CANNONLAKE_L, &cnl_features },
 1197	{ INTEL_ICELAKE_X, &icx_features },
 1198	{ INTEL_ICELAKE_D, &icx_features },
 1199	{ INTEL_ICELAKE_L, &cnl_features },
 1200	{ INTEL_ICELAKE_NNPI, &cnl_features },
 1201	{ INTEL_ROCKETLAKE, &cnl_features },
 1202	{ INTEL_TIGERLAKE_L, &cnl_features },
 1203	{ INTEL_TIGERLAKE, &cnl_features },
 1204	{ INTEL_SAPPHIRERAPIDS_X, &spr_features },
 1205	{ INTEL_EMERALDRAPIDS_X, &spr_features },
 1206	{ INTEL_GRANITERAPIDS_X, &spr_features },
 1207	{ INTEL_GRANITERAPIDS_D, &spr_features },
 1208	{ INTEL_DIAMONDRAPIDS_X, &dmr_features },
 1209	{ INTEL_LAKEFIELD, &cnl_features },
 1210	{ INTEL_ALDERLAKE, &adl_features },
 1211	{ INTEL_ALDERLAKE_L, &adl_features },
 1212	{ INTEL_RAPTORLAKE, &adl_features },
 1213	{ INTEL_RAPTORLAKE_P, &adl_features },
 1214	{ INTEL_RAPTORLAKE_S, &adl_features },
 1215	{ INTEL_BARTLETTLAKE, &adl_features },
 1216	{ INTEL_METEORLAKE, &adl_features },
 1217	{ INTEL_METEORLAKE_L, &adl_features },
 1218	{ INTEL_ARROWLAKE_H, &adl_features },
 1219	{ INTEL_ARROWLAKE_U, &adl_features },
 1220	{ INTEL_ARROWLAKE, &adl_features },
 1221	{ INTEL_LUNARLAKE_M, &lnl_features },
 1222	{ INTEL_PANTHERLAKE_L, &lnl_features },
 1223	{ INTEL_NOVALAKE, &lnl_features },
 1224	{ INTEL_NOVALAKE_L, &lnl_features },
 1225	{ INTEL_WILDCATLAKE_L, &lnl_features },
 1226	{ INTEL_ATOM_SILVERMONT, &slv_features },
 1227	{ INTEL_ATOM_SILVERMONT_D, &slvd_features },
 1228	{ INTEL_ATOM_AIRMONT, &amt_features },
 1229	{ INTEL_ATOM_GOLDMONT, &gmt_features },
 1230	{ INTEL_ATOM_GOLDMONT_D, &gmtd_features },
 1231	{ INTEL_ATOM_GOLDMONT_PLUS, &gmtp_features },
 1232	{ INTEL_ATOM_TREMONT_D, &tmtd_features },
 1233	{ INTEL_ATOM_TREMONT, &tmt_features },
 1234	{ INTEL_ATOM_TREMONT_L, &tmt_features },
 1235	{ INTEL_ATOM_GRACEMONT, &adl_features },
 1236	{ INTEL_ATOM_CRESTMONT_X, &srf_features },
 1237	{ INTEL_ATOM_CRESTMONT, &grr_features },
 1238	{ INTEL_ATOM_DARKMONT_X, &srf_features },
 1239	{ INTEL_XEON_PHI_KNL, &knl_features },
 1240	{ INTEL_XEON_PHI_KNM, &knl_features },
 1241	/*
 1242	 * Missing support for
 1243	 * INTEL_ICELAKE
 1244	 * INTEL_ATOM_SILVERMONT_MID
 1245	 * INTEL_ATOM_SILVERMONT_MID2
 1246	 * INTEL_ATOM_AIRMONT_NP
 1247	 */
 1248	{ 0, NULL },
 1249};
 1250
 1251static const struct platform_features *platform;
 1252
 1253void probe_platform_features(unsigned int family, unsigned int model)
 1254{
 1255	int i;
 1256
 1257	if (authentic_amd || hygon_genuine) {
 1258		/* fallback to default features on unsupported models */
 1259		force_load++;
 1260		if (max_extended_level >= 0x80000007) {
 1261			unsigned int eax, ebx, ecx, edx;
 1262
 1263			__cpuid(0x80000007, eax, ebx, ecx, edx);
 1264			/* RAPL (Fam 17h+) */
 1265			if ((edx & (1 << 14)) && family >= 0x17)
 1266				platform = &amd_features_with_rapl;
 1267		}
 1268		goto end;
 1269	}
 1270
 1271	if (!genuine_intel)
 1272		goto end;
 1273
 1274	for (i = 0; turbostat_pdata[i].features; i++) {
 1275		if (VFM_FAMILY(turbostat_pdata[i].vfm) == family && VFM_MODEL(turbostat_pdata[i].vfm) == model) {
 1276			platform = turbostat_pdata[i].features;
 1277			return;
 1278		}
 1279	}
 1280
 1281end:
 1282	if (force_load && !platform) {
 1283		fprintf(outf, "Forced to run on unsupported platform!\n");
 1284		platform = &default_features;
 1285	}
 1286
 1287	if (platform)
 1288		return;
 1289
 1290	fprintf(stderr, "Unsupported platform detected.\n\tSee RUN THE LATEST VERSION on turbostat(8)\n");
 1291	exit(1);
 1292}
 1293
 1294/* Model specific support End */
 1295
 1296#define	TJMAX_DEFAULT	100
 1297
 1298/* MSRs that are not yet in the kernel-provided header. */
 1299#define MSR_RAPL_PWR_UNIT	0xc0010299
 1300#define MSR_CORE_ENERGY_STAT	0xc001029a
 1301#define MSR_PKG_ENERGY_STAT	0xc001029b
 1302
 1303#define MAX(a, b) ((a) > (b) ? (a) : (b))
 1304
 1305int backwards_count;
 1306char *progname;
 1307
 1308#define CPU_SUBSET_MAXCPUS	8192	/* need to use before probe... */
 1309cpu_set_t *cpu_present_set, *cpu_possible_set, *cpu_effective_set, *cpu_allowed_set, *cpu_affinity_set, *cpu_subset;
 1310size_t cpu_present_setsize, cpu_possible_setsize, cpu_effective_setsize, cpu_allowed_setsize, cpu_affinity_setsize, cpu_subset_size;
 1311#define MAX_ADDED_THREAD_COUNTERS 24
 1312#define MAX_ADDED_CORE_COUNTERS 8
 1313#define MAX_ADDED_PACKAGE_COUNTERS 16
 1314#define PMT_MAX_ADDED_THREAD_COUNTERS 24
 1315#define PMT_MAX_ADDED_CORE_COUNTERS 8
 1316#define PMT_MAX_ADDED_PACKAGE_COUNTERS 16
 1317#define BITMASK_SIZE 32
 1318
 1319#define ZERO_ARRAY(arr) (memset(arr, 0, sizeof(arr)) + __must_be_array(arr))
 1320
 1321/* Indexes used to map data read from perf and MSRs into global variables */
 1322enum rapl_rci_index {
 1323	RAPL_RCI_INDEX_ENERGY_PKG = 0,
 1324	RAPL_RCI_INDEX_ENERGY_CORES = 1,
 1325	RAPL_RCI_INDEX_DRAM = 2,
 1326	RAPL_RCI_INDEX_GFX = 3,
 1327	RAPL_RCI_INDEX_PKG_PERF_STATUS = 4,
 1328	RAPL_RCI_INDEX_DRAM_PERF_STATUS = 5,
 1329	RAPL_RCI_INDEX_CORE_ENERGY = 6,
 1330	RAPL_RCI_INDEX_ENERGY_PLATFORM = 7,
 1331	NUM_RAPL_COUNTERS,
 1332};
 1333
 1334enum rapl_unit {
 1335	RAPL_UNIT_INVALID,
 1336	RAPL_UNIT_JOULES,
 1337	RAPL_UNIT_WATTS,
 1338};
 1339
 1340struct rapl_counter_info_t {
 1341	unsigned long long data[NUM_RAPL_COUNTERS];
 1342	enum counter_source source[NUM_RAPL_COUNTERS];
 1343	unsigned long long flags[NUM_RAPL_COUNTERS];
 1344	double scale[NUM_RAPL_COUNTERS];
 1345	enum rapl_unit unit[NUM_RAPL_COUNTERS];
 1346	unsigned long long msr[NUM_RAPL_COUNTERS];
 1347	unsigned long long msr_mask[NUM_RAPL_COUNTERS];
 1348	int msr_shift[NUM_RAPL_COUNTERS];
 1349
 1350	int fd_perf;
 1351};
 1352
 1353/* struct rapl_counter_info_t for each RAPL domain */
 1354struct rapl_counter_info_t *rapl_counter_info_perdomain;
 1355unsigned int rapl_counter_info_perdomain_size;
 1356
 1357#define RAPL_COUNTER_FLAG_PLATFORM_COUNTER (1u << 0)
 1358#define RAPL_COUNTER_FLAG_USE_MSR_SUM (1u << 1)
 1359
 1360struct rapl_counter_arch_info {
 1361	int feature_mask;	/* Mask for testing if the counter is supported on host */
 1362	const char *perf_subsys;
 1363	const char *perf_name;
 1364	unsigned long long msr;
 1365	unsigned long long msr_mask;
 1366	int msr_shift;		/* Positive mean shift right, negative mean shift left */
 1367	double *platform_rapl_msr_scale;	/* Scale applied to values read by MSR (platform dependent, filled at runtime) */
 1368	unsigned int rci_index;	/* Maps data from perf counters to global variables */
 1369	unsigned int bic_number;
 1370	double compat_scale;	/* Some counters require constant scaling to be in the same range as other, similar ones */
 1371	unsigned long long flags;
 1372};
 1373
 1374static const struct rapl_counter_arch_info rapl_counter_arch_infos[] = {
 1375	{
 1376	 .feature_mask = RAPL_PKG,
 1377	 .perf_subsys = "power",
 1378	 .perf_name = "energy-pkg",
 1379	 .msr = MSR_PKG_ENERGY_STATUS,
 1380	 .msr_mask = 0xFFFFFFFFFFFFFFFF,
 1381	 .msr_shift = 0,
 1382	 .platform_rapl_msr_scale = &rapl_energy_units,
 1383	 .rci_index = RAPL_RCI_INDEX_ENERGY_PKG,
 1384	 .bic_number = BIC_PkgWatt,
 1385	 .compat_scale = 1.0,
 1386	 .flags = RAPL_COUNTER_FLAG_USE_MSR_SUM,
 1387	  },
 1388	{
 1389	 .feature_mask = RAPL_PKG,
 1390	 .perf_subsys = "power",
 1391	 .perf_name = "energy-pkg",
 1392	 .msr = MSR_PKG_ENERGY_STATUS,
 1393	 .msr_mask = 0xFFFFFFFFFFFFFFFF,
 1394	 .msr_shift = 0,
 1395	 .platform_rapl_msr_scale = &rapl_energy_units,
 1396	 .rci_index = RAPL_RCI_INDEX_ENERGY_PKG,
 1397	 .bic_number = BIC_Pkg_J,
 1398	 .compat_scale = 1.0,
 1399	 .flags = RAPL_COUNTER_FLAG_USE_MSR_SUM,
 1400	  },
 1401	{
 1402	 .feature_mask = RAPL_AMD_F17H,
 1403	 .perf_subsys = "power",
 1404	 .perf_name = "energy-pkg",
 1405	 .msr = MSR_PKG_ENERGY_STAT,
 1406	 .msr_mask = 0xFFFFFFFFFFFFFFFF,
 1407	 .msr_shift = 0,
 1408	 .platform_rapl_msr_scale = &rapl_energy_units,
 1409	 .rci_index = RAPL_RCI_INDEX_ENERGY_PKG,
 1410	 .bic_number = BIC_PkgWatt,
 1411	 .compat_scale = 1.0,
 1412	 .flags = RAPL_COUNTER_FLAG_USE_MSR_SUM,
 1413	  },
 1414	{
 1415	 .feature_mask = RAPL_AMD_F17H,
 1416	 .perf_subsys = "power",
 1417	 .perf_name = "energy-pkg",
 1418	 .msr = MSR_PKG_ENERGY_STAT,
 1419	 .msr_mask = 0xFFFFFFFFFFFFFFFF,
 1420	 .msr_shift = 0,
 1421	 .platform_rapl_msr_scale = &rapl_energy_units,
 1422	 .rci_index = RAPL_RCI_INDEX_ENERGY_PKG,
 1423	 .bic_number = BIC_Pkg_J,
 1424	 .compat_scale = 1.0,
 1425	 .flags = RAPL_COUNTER_FLAG_USE_MSR_SUM,
 1426	  },
 1427	{
 1428	 .feature_mask = RAPL_CORE_ENERGY_STATUS,
 1429	 .perf_subsys = "power",
 1430	 .perf_name = "energy-cores",
 1431	 .msr = MSR_PP0_ENERGY_STATUS,
 1432	 .msr_mask = 0xFFFFFFFFFFFFFFFF,
 1433	 .msr_shift = 0,
 1434	 .platform_rapl_msr_scale = &rapl_energy_units,
 1435	 .rci_index = RAPL_RCI_INDEX_ENERGY_CORES,
 1436	 .bic_number = BIC_CorWatt,
 1437	 .compat_scale = 1.0,
 1438	 .flags = RAPL_COUNTER_FLAG_USE_MSR_SUM,
 1439	  },
 1440	{
 1441	 .feature_mask = RAPL_CORE_ENERGY_STATUS,
 1442	 .perf_subsys = "power",
 1443	 .perf_name = "energy-cores",
 1444	 .msr = MSR_PP0_ENERGY_STATUS,
 1445	 .msr_mask = 0xFFFFFFFFFFFFFFFF,
 1446	 .msr_shift = 0,
 1447	 .platform_rapl_msr_scale = &rapl_energy_units,
 1448	 .rci_index = RAPL_RCI_INDEX_ENERGY_CORES,
 1449	 .bic_number = BIC_Cor_J,
 1450	 .compat_scale = 1.0,
 1451	 .flags = RAPL_COUNTER_FLAG_USE_MSR_SUM,
 1452	  },
 1453	{
 1454	 .feature_mask = RAPL_DRAM,
 1455	 .perf_subsys = "power",
 1456	 .perf_name = "energy-ram",
 1457	 .msr = MSR_DRAM_ENERGY_STATUS,
 1458	 .msr_mask = 0xFFFFFFFFFFFFFFFF,
 1459	 .msr_shift = 0,
 1460	 .platform_rapl_msr_scale = &rapl_dram_energy_units,
 1461	 .rci_index = RAPL_RCI_INDEX_DRAM,
 1462	 .bic_number = BIC_RAMWatt,
 1463	 .compat_scale = 1.0,
 1464	 .flags = RAPL_COUNTER_FLAG_USE_MSR_SUM,
 1465	  },
 1466	{
 1467	 .feature_mask = RAPL_DRAM,
 1468	 .perf_subsys = "power",
 1469	 .perf_name = "energy-ram",
 1470	 .msr = MSR_DRAM_ENERGY_STATUS,
 1471	 .msr_mask = 0xFFFFFFFFFFFFFFFF,
 1472	 .msr_shift = 0,
 1473	 .platform_rapl_msr_scale = &rapl_dram_energy_units,
 1474	 .rci_index = RAPL_RCI_INDEX_DRAM,
 1475	 .bic_number = BIC_RAM_J,
 1476	 .compat_scale = 1.0,
 1477	 .flags = RAPL_COUNTER_FLAG_USE_MSR_SUM,
 1478	  },
 1479	{
 1480	 .feature_mask = RAPL_GFX,
 1481	 .perf_subsys = "power",
 1482	 .perf_name = "energy-gpu",
 1483	 .msr = MSR_PP1_ENERGY_STATUS,
 1484	 .msr_mask = 0xFFFFFFFFFFFFFFFF,
 1485	 .msr_shift = 0,
 1486	 .platform_rapl_msr_scale = &rapl_energy_units,
 1487	 .rci_index = RAPL_RCI_INDEX_GFX,
 1488	 .bic_number = BIC_GFXWatt,
 1489	 .compat_scale = 1.0,
 1490	 .flags = RAPL_COUNTER_FLAG_USE_MSR_SUM,
 1491	  },
 1492	{
 1493	 .feature_mask = RAPL_GFX,
 1494	 .perf_subsys = "power",
 1495	 .perf_name = "energy-gpu",
 1496	 .msr = MSR_PP1_ENERGY_STATUS,
 1497	 .msr_mask = 0xFFFFFFFFFFFFFFFF,
 1498	 .msr_shift = 0,
 1499	 .platform_rapl_msr_scale = &rapl_energy_units,
 1500	 .rci_index = RAPL_RCI_INDEX_GFX,
 1501	 .bic_number = BIC_GFX_J,
 1502	 .compat_scale = 1.0,
 1503	 .flags = RAPL_COUNTER_FLAG_USE_MSR_SUM,
 1504	  },
 1505	{
 1506	 .feature_mask = RAPL_PKG_PERF_STATUS,
 1507	 .perf_subsys = NULL,
 1508	 .perf_name = NULL,
 1509	 .msr = MSR_PKG_PERF_STATUS,
 1510	 .msr_mask = 0xFFFFFFFFFFFFFFFF,
 1511	 .msr_shift = 0,
 1512	 .platform_rapl_msr_scale = &rapl_time_units,
 1513	 .rci_index = RAPL_RCI_INDEX_PKG_PERF_STATUS,
 1514	 .bic_number = BIC_PKG__,
 1515	 .compat_scale = 100.0,
 1516	 .flags = RAPL_COUNTER_FLAG_USE_MSR_SUM,
 1517	  },
 1518	{
 1519	 .feature_mask = RAPL_DRAM_PERF_STATUS,
 1520	 .perf_subsys = NULL,
 1521	 .perf_name = NULL,
 1522	 .msr = MSR_DRAM_PERF_STATUS,
 1523	 .msr_mask = 0xFFFFFFFFFFFFFFFF,
 1524	 .msr_shift = 0,
 1525	 .platform_rapl_msr_scale = &rapl_time_units,
 1526	 .rci_index = RAPL_RCI_INDEX_DRAM_PERF_STATUS,
 1527	 .bic_number = BIC_RAM__,
 1528	 .compat_scale = 100.0,
 1529	 .flags = RAPL_COUNTER_FLAG_USE_MSR_SUM,
 1530	  },
 1531	{
 1532	 .feature_mask = RAPL_AMD_F17H,
 1533	 .perf_subsys = NULL,
 1534	 .perf_name = NULL,
 1535	 .msr = MSR_CORE_ENERGY_STAT,
 1536	 .msr_mask = 0xFFFFFFFF,
 1537	 .msr_shift = 0,
 1538	 .platform_rapl_msr_scale = &rapl_energy_units,
 1539	 .rci_index = RAPL_RCI_INDEX_CORE_ENERGY,
 1540	 .bic_number = BIC_CorWatt,
 1541	 .compat_scale = 1.0,
 1542	 .flags = 0,
 1543	  },
 1544	{
 1545	 .feature_mask = RAPL_AMD_F17H,
 1546	 .perf_subsys = NULL,
 1547	 .perf_name = NULL,
 1548	 .msr = MSR_CORE_ENERGY_STAT,
 1549	 .msr_mask = 0xFFFFFFFF,
 1550	 .msr_shift = 0,
 1551	 .platform_rapl_msr_scale = &rapl_energy_units,
 1552	 .rci_index = RAPL_RCI_INDEX_CORE_ENERGY,
 1553	 .bic_number = BIC_Cor_J,
 1554	 .compat_scale = 1.0,
 1555	 .flags = 0,
 1556	  },
 1557	{
 1558	 .feature_mask = RAPL_PSYS,
 1559	 .perf_subsys = "power",
 1560	 .perf_name = "energy-psys",
 1561	 .msr = MSR_PLATFORM_ENERGY_STATUS,
 1562	 .msr_mask = 0x00000000FFFFFFFF,
 1563	 .msr_shift = 0,
 1564	 .platform_rapl_msr_scale = &rapl_psys_energy_units,
 1565	 .rci_index = RAPL_RCI_INDEX_ENERGY_PLATFORM,
 1566	 .bic_number = BIC_SysWatt,
 1567	 .compat_scale = 1.0,
 1568	 .flags = RAPL_COUNTER_FLAG_PLATFORM_COUNTER | RAPL_COUNTER_FLAG_USE_MSR_SUM,
 1569	  },
 1570	{
 1571	 .feature_mask = RAPL_PSYS,
 1572	 .perf_subsys = "power",
 1573	 .perf_name = "energy-psys",
 1574	 .msr = MSR_PLATFORM_ENERGY_STATUS,
 1575	 .msr_mask = 0x00000000FFFFFFFF,
 1576	 .msr_shift = 0,
 1577	 .platform_rapl_msr_scale = &rapl_psys_energy_units,
 1578	 .rci_index = RAPL_RCI_INDEX_ENERGY_PLATFORM,
 1579	 .bic_number = BIC_Sys_J,
 1580	 .compat_scale = 1.0,
 1581	 .flags = RAPL_COUNTER_FLAG_PLATFORM_COUNTER | RAPL_COUNTER_FLAG_USE_MSR_SUM,
 1582	  },
 1583};
 1584
 1585struct rapl_counter {
 1586	unsigned long long raw_value;
 1587	enum rapl_unit unit;
 1588	double scale;
 1589};
 1590
 1591/* Indexes used to map data read from perf and MSRs into global variables */
 1592enum ccstate_rci_index {
 1593	CCSTATE_RCI_INDEX_C1_RESIDENCY = 0,
 1594	CCSTATE_RCI_INDEX_C3_RESIDENCY = 1,
 1595	CCSTATE_RCI_INDEX_C6_RESIDENCY = 2,
 1596	CCSTATE_RCI_INDEX_C7_RESIDENCY = 3,
 1597	PCSTATE_RCI_INDEX_C2_RESIDENCY = 4,
 1598	PCSTATE_RCI_INDEX_C3_RESIDENCY = 5,
 1599	PCSTATE_RCI_INDEX_C6_RESIDENCY = 6,
 1600	PCSTATE_RCI_INDEX_C7_RESIDENCY = 7,
 1601	PCSTATE_RCI_INDEX_C8_RESIDENCY = 8,
 1602	PCSTATE_RCI_INDEX_C9_RESIDENCY = 9,
 1603	PCSTATE_RCI_INDEX_C10_RESIDENCY = 10,
 1604	NUM_CSTATE_COUNTERS,
 1605};
 1606
 1607struct cstate_counter_info_t {
 1608	unsigned long long data[NUM_CSTATE_COUNTERS];
 1609	enum counter_source source[NUM_CSTATE_COUNTERS];
 1610	unsigned long long msr[NUM_CSTATE_COUNTERS];
 1611	int fd_perf_core;
 1612	int fd_perf_pkg;
 1613};
 1614
 1615struct cstate_counter_info_t *ccstate_counter_info;
 1616unsigned int ccstate_counter_info_size;
 1617
 1618#define CSTATE_COUNTER_FLAG_COLLECT_PER_CORE   (1u << 0)
 1619#define CSTATE_COUNTER_FLAG_COLLECT_PER_THREAD ((1u << 1) | CSTATE_COUNTER_FLAG_COLLECT_PER_CORE)
 1620#define CSTATE_COUNTER_FLAG_SOFT_C1_DEPENDENCY (1u << 2)
 1621
 1622struct cstate_counter_arch_info {
 1623	int feature_mask;	/* Mask for testing if the counter is supported on host */
 1624	const char *perf_subsys;
 1625	const char *perf_name;
 1626	unsigned long long msr;
 1627	unsigned int rci_index;	/* Maps data from perf counters to global variables */
 1628	unsigned int bic_number;
 1629	unsigned long long flags;
 1630	int pkg_cstate_limit;
 1631};
 1632
 1633static struct cstate_counter_arch_info ccstate_counter_arch_infos[] = {
 1634	{
 1635	 .feature_mask = CC1,
 1636	 .perf_subsys = "cstate_core",
 1637	 .perf_name = "c1-residency",
 1638	 .msr = MSR_CORE_C1_RES,
 1639	 .rci_index = CCSTATE_RCI_INDEX_C1_RESIDENCY,
 1640	 .bic_number = BIC_CPU_c1,
 1641	 .flags = CSTATE_COUNTER_FLAG_COLLECT_PER_THREAD,
 1642	 .pkg_cstate_limit = 0,
 1643	  },
 1644	{
 1645	 .feature_mask = CC3,
 1646	 .perf_subsys = "cstate_core",
 1647	 .perf_name = "c3-residency",
 1648	 .msr = MSR_CORE_C3_RESIDENCY,
 1649	 .rci_index = CCSTATE_RCI_INDEX_C3_RESIDENCY,
 1650	 .bic_number = BIC_CPU_c3,
 1651	 .flags = CSTATE_COUNTER_FLAG_COLLECT_PER_CORE | CSTATE_COUNTER_FLAG_SOFT_C1_DEPENDENCY,
 1652	 .pkg_cstate_limit = 0,
 1653	  },
 1654	{
 1655	 .feature_mask = CC6,
 1656	 .perf_subsys = "cstate_core",
 1657	 .perf_name = "c6-residency",
 1658	 .msr = MSR_CORE_C6_RESIDENCY,
 1659	 .rci_index = CCSTATE_RCI_INDEX_C6_RESIDENCY,
 1660	 .bic_number = BIC_CPU_c6,
 1661	 .flags = CSTATE_COUNTER_FLAG_COLLECT_PER_CORE | CSTATE_COUNTER_FLAG_SOFT_C1_DEPENDENCY,
 1662	 .pkg_cstate_limit = 0,
 1663	  },
 1664	{
 1665	 .feature_mask = CC7,
 1666	 .perf_subsys = "cstate_core",
 1667	 .perf_name = "c7-residency",
 1668	 .msr = MSR_CORE_C7_RESIDENCY,
 1669	 .rci_index = CCSTATE_RCI_INDEX_C7_RESIDENCY,
 1670	 .bic_number = BIC_CPU_c7,
 1671	 .flags = CSTATE_COUNTER_FLAG_COLLECT_PER_CORE | CSTATE_COUNTER_FLAG_SOFT_C1_DEPENDENCY,
 1672	 .pkg_cstate_limit = 0,
 1673	  },
 1674	{
 1675	 .feature_mask = PC2,
 1676	 .perf_subsys = "cstate_pkg",
 1677	 .perf_name = "c2-residency",
 1678	 .msr = MSR_PKG_C2_RESIDENCY,
 1679	 .rci_index = PCSTATE_RCI_INDEX_C2_RESIDENCY,
 1680	 .bic_number = BIC_Pkgpc2,
 1681	 .flags = 0,
 1682	 .pkg_cstate_limit = PCL__2,
 1683	  },
 1684	{
 1685	 .feature_mask = PC3,
 1686	 .perf_subsys = "cstate_pkg",
 1687	 .perf_name = "c3-residency",
 1688	 .msr = MSR_PKG_C3_RESIDENCY,
 1689	 .rci_index = PCSTATE_RCI_INDEX_C3_RESIDENCY,
 1690	 .bic_number = BIC_Pkgpc3,
 1691	 .flags = 0,
 1692	 .pkg_cstate_limit = PCL__3,
 1693	  },
 1694	{
 1695	 .feature_mask = PC6,
 1696	 .perf_subsys = "cstate_pkg",
 1697	 .perf_name = "c6-residency",
 1698	 .msr = MSR_PKG_C6_RESIDENCY,
 1699	 .rci_index = PCSTATE_RCI_INDEX_C6_RESIDENCY,
 1700	 .bic_number = BIC_Pkgpc6,
 1701	 .flags = 0,
 1702	 .pkg_cstate_limit = PCL__6,
 1703	  },
 1704	{
 1705	 .feature_mask = PC7,
 1706	 .perf_subsys = "cstate_pkg",
 1707	 .perf_name = "c7-residency",
 1708	 .msr = MSR_PKG_C7_RESIDENCY,
 1709	 .rci_index = PCSTATE_RCI_INDEX_C7_RESIDENCY,
 1710	 .bic_number = BIC_Pkgpc7,
 1711	 .flags = 0,
 1712	 .pkg_cstate_limit = PCL__7,
 1713	  },
 1714	{
 1715	 .feature_mask = PC8,
 1716	 .perf_subsys = "cstate_pkg",
 1717	 .perf_name = "c8-residency",
 1718	 .msr = MSR_PKG_C8_RESIDENCY,
 1719	 .rci_index = PCSTATE_RCI_INDEX_C8_RESIDENCY,
 1720	 .bic_number = BIC_Pkgpc8,
 1721	 .flags = 0,
 1722	 .pkg_cstate_limit = PCL__8,
 1723	  },
 1724	{
 1725	 .feature_mask = PC9,
 1726	 .perf_subsys = "cstate_pkg",
 1727	 .perf_name = "c9-residency",
 1728	 .msr = MSR_PKG_C9_RESIDENCY,
 1729	 .rci_index = PCSTATE_RCI_INDEX_C9_RESIDENCY,
 1730	 .bic_number = BIC_Pkgpc9,
 1731	 .flags = 0,
 1732	 .pkg_cstate_limit = PCL__9,
 1733	  },
 1734	{
 1735	 .feature_mask = PC10,
 1736	 .perf_subsys = "cstate_pkg",
 1737	 .perf_name = "c10-residency",
 1738	 .msr = MSR_PKG_C10_RESIDENCY,
 1739	 .rci_index = PCSTATE_RCI_INDEX_C10_RESIDENCY,
 1740	 .bic_number = BIC_Pkgpc10,
 1741	 .flags = 0,
 1742	 .pkg_cstate_limit = PCL_10,
 1743	  },
 1744};
 1745
 1746/* Indexes used to map data read from perf and MSRs into global variables */
 1747enum msr_rci_index {
 1748	MSR_RCI_INDEX_APERF = 0,
 1749	MSR_RCI_INDEX_MPERF = 1,
 1750	MSR_RCI_INDEX_SMI = 2,
 1751	NUM_MSR_COUNTERS,
 1752};
 1753
 1754struct msr_counter_info_t {
 1755	unsigned long long data[NUM_MSR_COUNTERS];
 1756	enum counter_source source[NUM_MSR_COUNTERS];
 1757	unsigned long long msr[NUM_MSR_COUNTERS];
 1758	unsigned long long msr_mask[NUM_MSR_COUNTERS];
 1759	int fd_perf;
 1760};
 1761
 1762struct msr_counter_info_t *msr_counter_info;
 1763unsigned int msr_counter_info_size;
 1764
 1765struct msr_counter_arch_info {
 1766	const char *perf_subsys;
 1767	const char *perf_name;
 1768	unsigned long long msr;
 1769	unsigned long long msr_mask;
 1770	unsigned int rci_index;	/* Maps data from perf counters to global variables */
 1771	bool needed;
 1772	bool present;
 1773};
 1774
 1775enum msr_arch_info_index {
 1776	MSR_ARCH_INFO_APERF_INDEX = 0,
 1777	MSR_ARCH_INFO_MPERF_INDEX = 1,
 1778	MSR_ARCH_INFO_SMI_INDEX = 2,
 1779};
 1780
 1781static struct msr_counter_arch_info msr_counter_arch_infos[] = {
 1782	[MSR_ARCH_INFO_APERF_INDEX] = {
 1783				       .perf_subsys = "msr",
 1784				       .perf_name = "aperf",
 1785				       .msr = MSR_IA32_APERF,
 1786				       .msr_mask = 0xFFFFFFFFFFFFFFFF,
 1787				       .rci_index = MSR_RCI_INDEX_APERF,
 1788				        },
 1789
 1790	[MSR_ARCH_INFO_MPERF_INDEX] = {
 1791				       .perf_subsys = "msr",
 1792				       .perf_name = "mperf",
 1793				       .msr = MSR_IA32_MPERF,
 1794				       .msr_mask = 0xFFFFFFFFFFFFFFFF,
 1795				       .rci_index = MSR_RCI_INDEX_MPERF,
 1796				        },
 1797
 1798	[MSR_ARCH_INFO_SMI_INDEX] = {
 1799				     .perf_subsys = "msr",
 1800				     .perf_name = "smi",
 1801				     .msr = MSR_SMI_COUNT,
 1802				     .msr_mask = 0xFFFFFFFF,
 1803				     .rci_index = MSR_RCI_INDEX_SMI,
 1804				      },
 1805};
 1806
 1807/* Can be redefined when compiling, useful for testing. */
 1808#ifndef SYSFS_TELEM_PATH
 1809#define SYSFS_TELEM_PATH "/sys/class/intel_pmt"
 1810#endif
 1811
 1812#define PMT_COUNTER_MTL_DC6_OFFSET 120
 1813#define PMT_COUNTER_MTL_DC6_LSB    0
 1814#define PMT_COUNTER_MTL_DC6_MSB    63
 1815#define PMT_MTL_DC6_GUID           0x1a067102
 1816#define PMT_MTL_DC6_SEQ            0
 1817
 1818#define PMT_COUNTER_CWF_MC1E_OFFSET_BASE          20936
 1819#define PMT_COUNTER_CWF_MC1E_OFFSET_INCREMENT     24
 1820#define PMT_COUNTER_CWF_MC1E_NUM_MODULES_PER_FILE 12
 1821#define PMT_COUNTER_CWF_CPUS_PER_MODULE           4
 1822#define PMT_COUNTER_CWF_MC1E_LSB                  0
 1823#define PMT_COUNTER_CWF_MC1E_MSB                  63
 1824#define PMT_CWF_MC1E_GUID                         0x14421519
 1825
 1826unsigned long long tcore_clock_freq_hz = 800000000;
 1827
 1828#define PMT_COUNTER_NAME_SIZE_BYTES      16
 1829#define PMT_COUNTER_TYPE_NAME_SIZE_BYTES 32
 1830
 1831struct pmt_mmio {
 1832	struct pmt_mmio *next;
 1833
 1834	unsigned int guid;
 1835	unsigned int size;
 1836
 1837	/* Base pointer to the mmaped memory. */
 1838	void *mmio_base;
 1839
 1840	/*
 1841	 * Offset to be applied to the mmio_base
 1842	 * to get the beginning of the PMT counters for given GUID.
 1843	 */
 1844	unsigned long pmt_offset;
 1845} *pmt_mmios;
 1846
 1847enum pmt_datatype {
 1848	PMT_TYPE_RAW,
 1849	PMT_TYPE_XTAL_TIME,
 1850	PMT_TYPE_TCORE_CLOCK,
 1851};
 1852
 1853struct pmt_domain_info {
 1854	/*
 1855	 * Pointer to the MMIO obtained by applying a counter offset
 1856	 * to the mmio_base of the mmaped region for the given GUID.
 1857	 *
 1858	 * This is where to read the raw value of the counter from.
 1859	 */
 1860	unsigned long *pcounter;
 1861};
 1862
 1863struct pmt_counter {
 1864	struct pmt_counter *next;
 1865
 1866	/* PMT metadata */
 1867	char name[PMT_COUNTER_NAME_SIZE_BYTES];
 1868	enum pmt_datatype type;
 1869	enum counter_scope scope;
 1870	unsigned int lsb;
 1871	unsigned int msb;
 1872
 1873	/* BIC-like metadata */
 1874	enum counter_format format;
 1875
 1876	unsigned int num_domains;
 1877	struct pmt_domain_info *domains;
 1878};
 1879
 1880/*
 1881 * PMT telemetry directory iterator.
 1882 * Used to iterate telemetry files in sysfs in correct order.
 1883 */
 1884struct pmt_diriter_t {
 1885	DIR *dir;
 1886	struct dirent **namelist;
 1887	unsigned int num_names;
 1888	unsigned int current_name_idx;
 1889};
 1890
 1891int pmt_telemdir_filter(const struct dirent *e)
 1892{
 1893	unsigned int dummy;
 1894
 1895	return sscanf(e->d_name, "telem%u", &dummy);
 1896}
 1897
 1898int pmt_telemdir_sort(const struct dirent **a, const struct dirent **b)
 1899{
 1900	unsigned int aidx = 0, bidx = 0;
 1901
 1902	sscanf((*a)->d_name, "telem%u", &aidx);
 1903	sscanf((*b)->d_name, "telem%u", &bidx);
 1904
 1905	return (aidx > bidx) ? 1 : (aidx < bidx) ? -1 : 0;
 1906}
 1907
 1908const struct dirent *pmt_diriter_next(struct pmt_diriter_t *iter)
 1909{
 1910	const struct dirent *ret = NULL;
 1911
 1912	if (!iter->dir)
 1913		return NULL;
 1914
 1915	if (iter->current_name_idx >= iter->num_names)
 1916		return NULL;
 1917
 1918	ret = iter->namelist[iter->current_name_idx];
 1919	++iter->current_name_idx;
 1920
 1921	return ret;
 1922}
 1923
 1924const struct dirent *pmt_diriter_begin(struct pmt_diriter_t *iter, const char *pmt_root_path)
 1925{
 1926	int num_names = iter->num_names;
 1927
 1928	if (!iter->dir) {
 1929		iter->dir = opendir(pmt_root_path);
 1930		if (iter->dir == NULL)
 1931			return NULL;
 1932
 1933		num_names = scandir(pmt_root_path, &iter->namelist, pmt_telemdir_filter, pmt_telemdir_sort);
 1934		if (num_names == -1)
 1935			return NULL;
 1936	}
 1937
 1938	iter->current_name_idx = 0;
 1939	iter->num_names = num_names;
 1940
 1941	return pmt_diriter_next(iter);
 1942}
 1943
 1944void pmt_diriter_init(struct pmt_diriter_t *iter)
 1945{
 1946	memset(iter, 0, sizeof(*iter));
 1947}
 1948
 1949void pmt_diriter_remove(struct pmt_diriter_t *iter)
 1950{
 1951	if (iter->namelist) {
 1952		for (unsigned int i = 0; i < iter->num_names; i++) {
 1953			free(iter->namelist[i]);
 1954			iter->namelist[i] = NULL;
 1955		}
 1956	}
 1957
 1958	free(iter->namelist);
 1959	iter->namelist = NULL;
 1960	iter->num_names = 0;
 1961	iter->current_name_idx = 0;
 1962
 1963	closedir(iter->dir);
 1964	iter->dir = NULL;
 1965}
 1966
 1967unsigned int pmt_counter_get_width(const struct pmt_counter *p)
 1968{
 1969	return (p->msb - p->lsb) + 1;
 1970}
 1971
 1972void pmt_counter_resize_(struct pmt_counter *pcounter, unsigned int new_size)
 1973{
 1974	struct pmt_domain_info *new_mem;
 1975
 1976	new_mem = (struct pmt_domain_info *)reallocarray(pcounter->domains, new_size, sizeof(*pcounter->domains));
 1977	if (!new_mem) {
 1978		fprintf(stderr, "%s: failed to allocate memory for PMT counters\n", __func__);
 1979		exit(1);
 1980	}
 1981
 1982	/* Zero initialize just allocated memory. */
 1983	const size_t num_new_domains = new_size - pcounter->num_domains;
 1984
 1985	memset(&new_mem[pcounter->num_domains], 0, num_new_domains * sizeof(*pcounter->domains));
 1986
 1987	pcounter->num_domains = new_size;
 1988	pcounter->domains = new_mem;
 1989}
 1990
 1991void pmt_counter_resize(struct pmt_counter *pcounter, unsigned int new_size)
 1992{
 1993	/*
 1994	 * Allocate more memory ahead of time.
 1995	 *
 1996	 * Always allocate space for at least 8 elements
 1997	 * and double the size when growing.
 1998	 */
 1999	if (new_size < 8)
 2000		new_size = 8;
 2001	new_size = MAX(new_size, pcounter->num_domains * 2);
 2002
 2003	pmt_counter_resize_(pcounter, new_size);
 2004}
 2005
 2006struct llc_stats {
 2007	unsigned long long references;
 2008	unsigned long long misses;
 2009};
 2010struct thread_data {
 2011	struct timeval tv_begin;
 2012	struct timeval tv_end;
 2013	struct timeval tv_delta;
 2014	unsigned long long tsc;
 2015	unsigned long long aperf;
 2016	unsigned long long mperf;
 2017	unsigned long long c1;
 2018	unsigned long long instr_count;
 2019	unsigned long long irq_count;
 2020	unsigned long long nmi_count;
 2021	unsigned int smi_count;
 2022	struct llc_stats llc;
 2023	unsigned int cpu_id;
 2024	unsigned int apic_id;
 2025	unsigned int x2apic_id;
 2026	unsigned int flags;
 2027	bool is_atom;
 2028	unsigned long long counter[MAX_ADDED_THREAD_COUNTERS];
 2029	unsigned long long perf_counter[MAX_ADDED_THREAD_COUNTERS];
 2030	unsigned long long pmt_counter[PMT_MAX_ADDED_THREAD_COUNTERS];
 2031} *thread_even, *thread_odd;
 2032
 2033struct core_data {
 2034	int base_cpu;
 2035	unsigned long long c3;
 2036	unsigned long long c6;
 2037	unsigned long long c7;
 2038	unsigned long long mc6_us;	/* duplicate as per-core for now, even though per module */
 2039	unsigned int core_temp_c;
 2040	struct rapl_counter core_energy;	/* MSR_CORE_ENERGY_STAT */
 2041	unsigned int core_id;
 2042	unsigned long long core_throt_cnt;
 2043	unsigned long long counter[MAX_ADDED_CORE_COUNTERS];
 2044	unsigned long long perf_counter[MAX_ADDED_CORE_COUNTERS];
 2045	unsigned long long pmt_counter[PMT_MAX_ADDED_CORE_COUNTERS];
 2046} *core_even, *core_odd;
 2047
 2048struct pkg_data {
 2049	int base_cpu;
 2050	unsigned long long pc2;
 2051	unsigned long long pc3;
 2052	unsigned long long pc6;
 2053	unsigned long long pc7;
 2054	unsigned long long pc8;
 2055	unsigned long long pc9;
 2056	unsigned long long pc10;
 2057	long long cpu_lpi;
 2058	long long sys_lpi;
 2059	unsigned long long pkg_wtd_core_c0;
 2060	unsigned long long pkg_any_core_c0;
 2061	unsigned long long pkg_any_gfxe_c0;
 2062	unsigned long long pkg_both_core_gfxe_c0;
 2063	long long gfx_rc6_ms;
 2064	unsigned int gfx_mhz;
 2065	unsigned int gfx_act_mhz;
 2066	long long sam_mc6_ms;
 2067	unsigned int sam_mhz;
 2068	unsigned int sam_act_mhz;
 2069	unsigned int package_id;
 2070	struct rapl_counter energy_pkg;	/* MSR_PKG_ENERGY_STATUS */
 2071	struct rapl_counter energy_dram;	/* MSR_DRAM_ENERGY_STATUS */
 2072	struct rapl_counter energy_cores;	/* MSR_PP0_ENERGY_STATUS */
 2073	struct rapl_counter energy_gfx;	/* MSR_PP1_ENERGY_STATUS */
 2074	struct rapl_counter rapl_pkg_perf_status;	/* MSR_PKG_PERF_STATUS */
 2075	struct rapl_counter rapl_dram_perf_status;	/* MSR_DRAM_PERF_STATUS */
 2076	unsigned int pkg_temp_c;
 2077	unsigned int uncore_mhz;
 2078	unsigned long long die_c6;
 2079	unsigned long long counter[MAX_ADDED_PACKAGE_COUNTERS];
 2080	unsigned long long perf_counter[MAX_ADDED_PACKAGE_COUNTERS];
 2081	unsigned long long pmt_counter[PMT_MAX_ADDED_PACKAGE_COUNTERS];
 2082} *package_even, *package_odd;
 2083
 2084#define ODD_COUNTERS thread_odd, core_odd, package_odd
 2085#define EVEN_COUNTERS thread_even, core_even, package_even
 2086
 2087#define GET_THREAD(thread_base, thread_no, core_no, node_no, pkg_no)	      \
 2088	((thread_base) +						      \
 2089	 ((pkg_no) *							      \
 2090	  topo.nodes_per_pkg * topo.cores_per_node * topo.threads_per_core) + \
 2091	 ((node_no) * topo.cores_per_node * topo.threads_per_core) +	      \
 2092	 ((core_no) * topo.threads_per_core) +				      \
 2093	 (thread_no))
 2094
 2095#define GET_CORE(core_base, core_no, node_no, pkg_no)			\
 2096	((core_base) +							\
 2097	 ((pkg_no) *  topo.nodes_per_pkg * topo.cores_per_node) +	\
 2098	 ((node_no) * topo.cores_per_node) +				\
 2099	 (core_no))
 2100
 2101/*
 2102 * The accumulated sum of MSR is defined as a monotonic
 2103 * increasing MSR, it will be accumulated periodically,
 2104 * despite its register's bit width.
 2105 */
 2106enum {
 2107	IDX_PKG_ENERGY,
 2108	IDX_DRAM_ENERGY,
 2109	IDX_PP0_ENERGY,
 2110	IDX_PP1_ENERGY,
 2111	IDX_PKG_PERF,
 2112	IDX_DRAM_PERF,
 2113	IDX_PSYS_ENERGY,
 2114	IDX_COUNT,
 2115};
 2116
 2117int get_msr_sum(int cpu, off_t offset, unsigned long long *msr);
 2118
 2119struct msr_sum_array {
 2120	/* get_msr_sum() = sum + (get_msr() - last) */
 2121	struct {
 2122		/*The accumulated MSR value is updated by the timer */
 2123		unsigned long long sum;
 2124		/*The MSR footprint recorded in last timer */
 2125		unsigned long long last;
 2126	} entries[IDX_COUNT];
 2127};
 2128
 2129/* The percpu MSR sum array.*/
 2130struct msr_sum_array *per_cpu_msr_sum;
 2131
 2132off_t idx_to_offset(int idx)
 2133{
 2134	off_t offset;
 2135
 2136	switch (idx) {
 2137	case IDX_PKG_ENERGY:
 2138		if (platform->plat_rapl_msrs & RAPL_AMD_F17H)
 2139			offset = MSR_PKG_ENERGY_STAT;
 2140		else
 2141			offset = MSR_PKG_ENERGY_STATUS;
 2142		break;
 2143	case IDX_DRAM_ENERGY:
 2144		offset = MSR_DRAM_ENERGY_STATUS;
 2145		break;
 2146	case IDX_PP0_ENERGY:
 2147		offset = MSR_PP0_ENERGY_STATUS;
 2148		break;
 2149	case IDX_PP1_ENERGY:
 2150		offset = MSR_PP1_ENERGY_STATUS;
 2151		break;
 2152	case IDX_PKG_PERF:
 2153		offset = MSR_PKG_PERF_STATUS;
 2154		break;
 2155	case IDX_DRAM_PERF:
 2156		offset = MSR_DRAM_PERF_STATUS;
 2157		break;
 2158	case IDX_PSYS_ENERGY:
 2159		offset = MSR_PLATFORM_ENERGY_STATUS;
 2160		break;
 2161	default:
 2162		offset = -1;
 2163	}
 2164	return offset;
 2165}
 2166
 2167int offset_to_idx(off_t offset)
 2168{
 2169	int idx;
 2170
 2171	switch (offset) {
 2172	case MSR_PKG_ENERGY_STATUS:
 2173	case MSR_PKG_ENERGY_STAT:
 2174		idx = IDX_PKG_ENERGY;
 2175		break;
 2176	case MSR_DRAM_ENERGY_STATUS:
 2177		idx = IDX_DRAM_ENERGY;
 2178		break;
 2179	case MSR_PP0_ENERGY_STATUS:
 2180		idx = IDX_PP0_ENERGY;
 2181		break;
 2182	case MSR_PP1_ENERGY_STATUS:
 2183		idx = IDX_PP1_ENERGY;
 2184		break;
 2185	case MSR_PKG_PERF_STATUS:
 2186		idx = IDX_PKG_PERF;
 2187		break;
 2188	case MSR_DRAM_PERF_STATUS:
 2189		idx = IDX_DRAM_PERF;
 2190		break;
 2191	case MSR_PLATFORM_ENERGY_STATUS:
 2192		idx = IDX_PSYS_ENERGY;
 2193		break;
 2194	default:
 2195		idx = -1;
 2196	}
 2197	return idx;
 2198}
 2199
 2200int idx_valid(int idx)
 2201{
 2202	switch (idx) {
 2203	case IDX_PKG_ENERGY:
 2204		return valid_rapl_msrs & (RAPL_PKG | RAPL_AMD_F17H);
 2205	case IDX_DRAM_ENERGY:
 2206		return valid_rapl_msrs & RAPL_DRAM;
 2207	case IDX_PP0_ENERGY:
 2208		return valid_rapl_msrs & RAPL_CORE_ENERGY_STATUS;
 2209	case IDX_PP1_ENERGY:
 2210		return valid_rapl_msrs & RAPL_GFX;
 2211	case IDX_PKG_PERF:
 2212		return valid_rapl_msrs & RAPL_PKG_PERF_STATUS;
 2213	case IDX_DRAM_PERF:
 2214		return valid_rapl_msrs & RAPL_DRAM_PERF_STATUS;
 2215	case IDX_PSYS_ENERGY:
 2216		return valid_rapl_msrs & RAPL_PSYS;
 2217	default:
 2218		return 0;
 2219	}
 2220}
 2221
 2222struct sys_counters {
 2223	/* MSR added counters */
 2224	unsigned int added_thread_counters;
 2225	unsigned int added_core_counters;
 2226	unsigned int added_package_counters;
 2227	struct msr_counter *tp;
 2228	struct msr_counter *cp;
 2229	struct msr_counter *pp;
 2230
 2231	/* perf added counters */
 2232	unsigned int added_thread_perf_counters;
 2233	unsigned int added_core_perf_counters;
 2234	unsigned int added_package_perf_counters;
 2235	struct perf_counter_info *perf_tp;
 2236	struct perf_counter_info *perf_cp;
 2237	struct perf_counter_info *perf_pp;
 2238
 2239	struct pmt_counter *pmt_tp;
 2240	struct pmt_counter *pmt_cp;
 2241	struct pmt_counter *pmt_pp;
 2242} sys;
 2243
 2244static size_t free_msr_counters_(struct msr_counter **pp)
 2245{
 2246	struct msr_counter *p = NULL;
 2247	size_t num_freed = 0;
 2248
 2249	while (*pp) {
 2250		p = *pp;
 2251
 2252		if (p->msr_num != 0) {
 2253			*pp = p->next;
 2254
 2255			free(p);
 2256			++num_freed;
 2257
 2258			continue;
 2259		}
 2260
 2261		pp = &p->next;
 2262	}
 2263
 2264	return num_freed;
 2265}
 2266
 2267/*
 2268 * Free all added counters accessed via msr.
 2269 */
 2270static void free_sys_msr_counters(void)
 2271{
 2272	/* Thread counters */
 2273	sys.added_thread_counters -= free_msr_counters_(&sys.tp);
 2274
 2275	/* Core counters */
 2276	sys.added_core_counters -= free_msr_counters_(&sys.cp);
 2277
 2278	/* Package counters */
 2279	sys.added_package_counters -= free_msr_counters_(&sys.pp);
 2280}
 2281
 2282struct system_summary {
 2283	struct thread_data threads;
 2284	struct core_data cores;
 2285	struct pkg_data packages;
 2286} average;
 2287
 2288struct platform_counters {
 2289	struct rapl_counter energy_psys;	/* MSR_PLATFORM_ENERGY_STATUS */
 2290} platform_counters_odd, platform_counters_even;
 2291
 2292struct cpu_topology {
 2293	int physical_package_id;
 2294	int die_id;
 2295	int l3_id;
 2296	int logical_cpu_id;
 2297	int physical_node_id;
 2298	int logical_node_id;	/* 0-based count within the package */
 2299	int physical_core_id;
 2300	int thread_id;
 2301	int type;
 2302	cpu_set_t *put_ids;	/* Processing Unit/Thread IDs */
 2303} *cpus;
 2304
 2305struct topo_params {
 2306	int num_packages;
 2307	int num_die;
 2308	int num_cpus;
 2309	int num_cores;
 2310	int allowed_packages;
 2311	int allowed_cpus;
 2312	int allowed_cores;
 2313	int max_cpu_num;
 2314	int max_core_id;
 2315	int max_package_id;
 2316	int max_die_id;
 2317	int max_l3_id;
 2318	int max_node_num;
 2319	int nodes_per_pkg;
 2320	int cores_per_node;
 2321	int threads_per_core;
 2322} topo;
 2323
 2324struct timeval tv_even, tv_odd, tv_delta;
 2325
 2326int *irq_column_2_cpu;		/* /proc/interrupts column numbers */
 2327int *irqs_per_cpu;		/* indexed by cpu_num */
 2328int *nmi_per_cpu;		/* indexed by cpu_num */
 2329
 2330void setup_all_buffers(bool startup);
 2331
 2332char *sys_lpi_file;
 2333char *sys_lpi_file_sysfs = "/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us";
 2334char *sys_lpi_file_debugfs = "/sys/kernel/debug/pmc_core/slp_s0_residency_usec";
 2335
 2336int cpu_is_not_present(int cpu)
 2337{
 2338	return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set);
 2339}
 2340
 2341int cpu_is_not_allowed(int cpu)
 2342{
 2343	return !CPU_ISSET_S(cpu, cpu_allowed_setsize, cpu_allowed_set);
 2344}
 2345
 2346/*
 2347 * run func(thread, core, package) in topology order
 2348 * skip non-present cpus
 2349 */
 2350
 2351#define PER_THREAD_PARAMS  struct thread_data *t, struct core_data *c, struct pkg_data *p
 2352
 2353int for_all_cpus(int (func) (struct thread_data *, struct core_data *, struct pkg_data *),
 2354		 struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base)
 2355{
 2356	int retval, pkg_no, core_no, thread_no, node_no;
 2357
 2358	retval = 0;
 2359
 2360	for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) {
 2361		for (node_no = 0; node_no < topo.nodes_per_pkg; node_no++) {
 2362			for (core_no = 0; core_no < topo.cores_per_node; ++core_no) {
 2363				for (thread_no = 0; thread_no < topo.threads_per_core; ++thread_no) {
 2364					struct thread_data *t;
 2365					struct core_data *c;
 2366
 2367					t = GET_THREAD(thread_base, thread_no, core_no, node_no, pkg_no);
 2368
 2369					if (cpu_is_not_allowed(t->cpu_id))
 2370						continue;
 2371
 2372					c = GET_CORE(core_base, core_no, node_no, pkg_no);
 2373
 2374					retval |= func(t, c, &pkg_base[pkg_no]);
 2375				}
 2376			}
 2377		}
 2378	}
 2379	return retval;
 2380}
 2381
 2382int is_cpu_first_thread_in_core(struct thread_data *t, struct core_data *c)
 2383{
 2384	return ((int)t->cpu_id == c->base_cpu || c->base_cpu < 0);
 2385}
 2386
 2387int is_cpu_first_core_in_package(struct thread_data *t, struct pkg_data *p)
 2388{
 2389	return ((int)t->cpu_id == p->base_cpu || p->base_cpu < 0);
 2390}
 2391
 2392int is_cpu_first_thread_in_package(struct thread_data *t, struct core_data *c, struct pkg_data *p)
 2393{
 2394	return is_cpu_first_thread_in_core(t, c) && is_cpu_first_core_in_package(t, p);
 2395}
 2396
 2397int cpu_migrate(int cpu)
 2398{
 2399	CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
 2400	CPU_SET_S(cpu, cpu_affinity_setsize, cpu_affinity_set);
 2401	if (sched_setaffinity(0, cpu_affinity_setsize, cpu_affinity_set) == -1)
 2402		return -1;
 2403	else
 2404		return 0;
 2405}
 2406
 2407int get_msr_fd(int cpu)
 2408{
 2409	char pathname[32];
 2410	int fd;
 2411
 2412	fd = fd_percpu[cpu];
 2413
 2414	if (fd)
 2415		return fd;
 2416	sprintf(pathname, use_android_msr_path ? "/dev/msr%d" : "/dev/cpu/%d/msr", cpu);
 2417	fd = open(pathname, O_RDONLY);
 2418	if (fd < 0)
 2419		err(-1, "%s open failed, try chown or chmod +r %s, "
 2420		    "or run with --no-msr, or run as root", pathname, use_android_msr_path ? "/dev/msr*" : "/dev/cpu/*/msr");
 2421	fd_percpu[cpu] = fd;
 2422
 2423	return fd;
 2424}
 2425
 2426static void bic_disable_msr_access(void)
 2427{
 2428	CLR_BIC(BIC_Mod_c6, &bic_enabled);
 2429	CLR_BIC(BIC_CoreTmp, &bic_enabled);
 2430	CLR_BIC(BIC_Totl_c0, &bic_enabled);
 2431	CLR_BIC(BIC_Any_c0, &bic_enabled);
 2432	CLR_BIC(BIC_GFX_c0, &bic_enabled);
 2433	CLR_BIC(BIC_CPUGFX, &bic_enabled);
 2434	CLR_BIC(BIC_PkgTmp, &bic_enabled);
 2435
 2436	free_sys_msr_counters();
 2437}
 2438
 2439static void bic_disable_perf_access(void)
 2440{
 2441	CLR_BIC(BIC_IPC, &bic_enabled);
 2442	CLR_BIC(BIC_LLC_RPS, &bic_enabled);
 2443	CLR_BIC(BIC_LLC_HIT, &bic_enabled);
 2444}
 2445
 2446static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, int group_fd, unsigned long flags)
 2447{
 2448	assert(!no_perf);
 2449
 2450	return syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
 2451}
 2452
 2453static long open_perf_counter(int cpu, unsigned int type, unsigned int config, int group_fd, __u64 read_format)
 2454{
 2455	struct perf_event_attr attr;
 2456	const pid_t pid = -1;
 2457	const unsigned long flags = 0;
 2458
 2459	assert(!no_perf);
 2460
 2461	memset(&attr, 0, sizeof(struct perf_event_attr));
 2462
 2463	attr.type = type;
 2464	attr.size = sizeof(struct perf_event_attr);
 2465	attr.config = config;
 2466	attr.disabled = 0;
 2467	attr.sample_type = PERF_SAMPLE_IDENTIFIER;
 2468	attr.read_format = read_format;
 2469
 2470	const int fd = perf_event_open(&attr, pid, cpu, group_fd, flags);
 2471
 2472	return fd;
 2473}
 2474
 2475int get_instr_count_fd(int cpu)
 2476{
 2477	if (fd_instr_count_percpu[cpu])
 2478		return fd_instr_count_percpu[cpu];
 2479
 2480	fd_instr_count_percpu[cpu] = open_perf_counter(cpu, PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS, -1, 0);
 2481
 2482	return fd_instr_count_percpu[cpu];
 2483}
 2484
 2485int get_msr(int cpu, off_t offset, unsigned long long *msr)
 2486{
 2487	ssize_t retval;
 2488
 2489	assert(!no_msr);
 2490
 2491	retval = pread(get_msr_fd(cpu), msr, sizeof(*msr), offset);
 2492
 2493	if (retval != sizeof *msr)
 2494		err(-1, "cpu%d: msr offset 0x%llx read failed", cpu, (unsigned long long)offset);
 2495
 2496	return 0;
 2497}
 2498
 2499int add_msr_counter(int cpu, off_t offset)
 2500{
 2501	ssize_t retval;
 2502	unsigned long long value;
 2503
 2504	if (no_msr)
 2505		return -1;
 2506
 2507	if (!offset)
 2508		return -1;
 2509
 2510	retval = pread(get_msr_fd(cpu), &value, sizeof(value), offset);
 2511
 2512	/* if the read failed, the probe fails */
 2513	if (retval != sizeof(value))
 2514		return -1;
 2515
 2516	if (value == 0)
 2517		return 0;
 2518
 2519	return 1;
 2520}
 2521
 2522int add_rapl_msr_counter(int cpu, const struct rapl_counter_arch_info *cai)
 2523{
 2524	int ret;
 2525
 2526	if (!(valid_rapl_msrs & cai->feature_mask))
 2527		return -1;
 2528
 2529	ret = add_msr_counter(cpu, cai->msr);
 2530	if (ret < 0)
 2531		return -1;
 2532
 2533	switch (cai->rci_index) {
 2534	case RAPL_RCI_INDEX_ENERGY_PKG:
 2535	case RAPL_RCI_INDEX_ENERGY_CORES:
 2536	case RAPL_RCI_INDEX_DRAM:
 2537	case RAPL_RCI_INDEX_GFX:
 2538	case RAPL_RCI_INDEX_ENERGY_PLATFORM:
 2539		if (ret == 0)
 2540			return 1;
 2541	}
 2542
 2543	/* PKG,DRAM_PERF_STATUS MSRs, can return any value */
 2544	return 1;
 2545}
 2546
 2547/* Convert CPU ID to domain ID for given added perf counter. */
 2548unsigned int cpu_to_domain(const struct perf_counter_info *pc, int cpu)
 2549{
 2550	switch (pc->scope) {
 2551	case SCOPE_CPU:
 2552		return cpu;
 2553
 2554	case SCOPE_CORE:
 2555		return cpus[cpu].physical_core_id;
 2556
 2557	case SCOPE_PACKAGE:
 2558		return cpus[cpu].physical_package_id;
 2559	}
 2560
 2561	__builtin_unreachable();
 2562}
 2563
 2564#define MAX_DEFERRED 16
 2565char *deferred_add_names[MAX_DEFERRED];
 2566char *deferred_skip_names[MAX_DEFERRED];
 2567int deferred_add_index;
 2568int deferred_skip_index;
 2569unsigned int deferred_add_consumed;
 2570unsigned int deferred_skip_consumed;
 2571
 2572/*
 2573 * HIDE_LIST - hide this list of counters, show the rest [default]
 2574 * SHOW_LIST - show this list of counters, hide the rest
 2575 */
 2576enum show_hide_mode { SHOW_LIST, HIDE_LIST } global_show_hide_mode = HIDE_LIST;
 2577
 2578void help(void)
 2579{
 2580	fprintf(outf,
 2581		"Usage: turbostat [OPTIONS][(--interval seconds) | COMMAND ...]\n"
 2582		"\n"
 2583		"Turbostat forks the specified COMMAND and prints statistics\n"
 2584		"when COMMAND completes.\n"
 2585		"If no COMMAND is specified, turbostat wakes every 5-seconds\n"
 2586		"to print statistics, until interrupted.\n"
 2587		"  -a, --add counter\n"
 2588		"		add a counter\n"
 2589		"		  eg. --add msr0x10,u64,cpu,delta,MY_TSC\n"
 2590		"		  eg. --add perf/cstate_pkg/c2-residency,package,delta,percent,perfPC2\n"
 2591		"		  eg. --add pmt,name=XTAL,type=raw,domain=package0,offset=0,lsb=0,msb=63,guid=0x1a067102\n"
 2592		"  -c, --cpu cpu-set\n"
 2593		"		limit output to summary plus cpu-set:\n"
 2594		"		  {core | package | j,k,l..m,n-p }\n"
 2595		"  -d, --debug\n"
 2596		"		displays usec, Time_Of_Day_Seconds and more debugging\n"
 2597		"		debug messages are printed to stderr\n"
 2598		"  -D, --Dump\n"
 2599		"		displays the raw counter values\n"
 2600		"  -e, --enable [all | column]\n"
 2601		"		shows all or the specified disabled column\n"
 2602		"  -f, --force\n"
 2603		"		force load turbostat with minimum default features on unsupported platforms.\n"
 2604		"  -H, --hide [column | column,column,...]\n"
 2605		"		hide the specified column(s)\n"
 2606		"  -i, --interval sec.subsec\n"
 2607		"		override default 5-second measurement interval\n"
 2608		"  -J, --Joules\n"
 2609		"		displays energy in Joules instead of Watts\n"
 2610		"  -l, --list\n"
 2611		"		list column headers only\n"
 2612		"  -M, --no-msr\n"
 2613		"		disable all uses of the MSR driver\n"
 2614		"  -P, --no-perf\n"
 2615		"		disable all uses of the perf API\n"
 2616		"  -n, --num_iterations num\n"
 2617		"		number of the measurement iterations\n"
 2618		"  -N, --header_iterations num\n"
 2619		"		print header every num iterations\n"
 2620		"  -o, --out file\n"
 2621		"		create or truncate \"file\" for all output\n"
 2622		"  -q, --quiet\n"
 2623		"		skip decoding system configuration header\n"
 2624		"  -s, --show [column | column,column,...]\n"
 2625		"		show only the specified column(s)\n"
 2626		"  -S, --Summary\n"
 2627		"		limits output to 1-line system summary per interval\n"
 2628		"  -T, --TCC temperature\n"
 2629		"		sets the Thermal Control Circuit temperature in\n"
 2630		"		  degrees Celsius\n"
 2631		"  -h, --help\n"
 2632		"		print this help message\n"
 2633		"  -v, --version\n\t\tprint version information\n\nFor more help, run \"man turbostat\"\n");
 2634}
 2635
 2636/*
 2637 * bic_lookup
 2638 * for all the strings in comma separate name_list,
 2639 * set the approprate bit in return value.
 2640 */
 2641void bic_lookup(cpu_set_t *ret_set, char *name_list, enum show_hide_mode mode)
 2642{
 2643	unsigned int i;
 2644
 2645	while (name_list) {
 2646		char *comma;
 2647
 2648		comma = strchr(name_list, ',');
 2649
 2650		if (comma)
 2651			*comma = '\0';
 2652
 2653		for (i = 0; i < MAX_BIC; ++i) {
 2654			if (!strcmp(name_list, bic[i].name)) {
 2655				SET_BIC(i, ret_set);
 2656				break;
 2657			}
 2658			if (!strcmp(name_list, "all")) {
 2659				bic_set_all(ret_set);
 2660				break;
 2661			} else if (!strcmp(name_list, "topology")) {
 2662				CPU_OR(ret_set, ret_set, &bic_group_topology);
 2663				break;
 2664			} else if (!strcmp(name_list, "power")) {
 2665				CPU_OR(ret_set, ret_set, &bic_group_thermal_pwr);
 2666				break;
 2667			} else if (!strcmp(name_list, "idle")) {
 2668				CPU_OR(ret_set, ret_set, &bic_group_idle);
 2669				break;
 2670			} else if (!strcmp(name_list, "cache")) {
 2671				CPU_OR(ret_set, ret_set, &bic_group_cache);
 2672				break;
 2673			} else if (!strcmp(name_list, "llc")) {
 2674				CPU_OR(ret_set, ret_set, &bic_group_cache);
 2675				break;
 2676			} else if (!strcmp(name_list, "swidle")) {
 2677				CPU_OR(ret_set, ret_set, &bic_group_sw_idle);
 2678				break;
 2679			} else if (!strcmp(name_list, "sysfs")) {	/* legacy compatibility */
 2680				CPU_OR(ret_set, ret_set, &bic_group_sw_idle);
 2681				break;
 2682			} else if (!strcmp(name_list, "hwidle")) {
 2683				CPU_OR(ret_set, ret_set, &bic_group_hw_idle);
 2684				break;
 2685			} else if (!strcmp(name_list, "frequency")) {
 2686				CPU_OR(ret_set, ret_set, &bic_group_frequency);
 2687				break;
 2688			} else if (!strcmp(name_list, "other")) {
 2689				CPU_OR(ret_set, ret_set, &bic_group_other);
 2690				break;
 2691			}
 2692		}
 2693		if (i == MAX_BIC) {
 2694			if (mode == SHOW_LIST) {
 2695				deferred_add_names[deferred_add_index++] = name_list;
 2696				if (deferred_add_index >= MAX_DEFERRED) {
 2697					fprintf(stderr, "More than max %d un-recognized --add options '%s'\n", MAX_DEFERRED, name_list);
 2698					help();
 2699					exit(1);
 2700				}
 2701			} else {
 2702				deferred_skip_names[deferred_skip_index++] = name_list;
 2703				if (debug)
 2704					fprintf(stderr, "deferred \"%s\"\n", name_list);
 2705				if (deferred_skip_index >= MAX_DEFERRED) {
 2706					fprintf(stderr, "More than max %d un-recognized --skip options '%s'\n", MAX_DEFERRED, name_list);
 2707					help();
 2708					exit(1);
 2709				}
 2710			}
 2711		}
 2712
 2713		name_list = comma;
 2714		if (name_list)
 2715			name_list++;
 2716
 2717	}
 2718}
 2719
 2720/*
 2721 * print_name()
 2722 * Print column header name for raw 64-bit counter in 16 columns (at least 8-char plus a tab)
 2723 * Otherwise, allow the name + tab to fit within 8-coumn tab-stop.
 2724 * In both cases, left justififed, just like other turbostat columns,
 2725 * to allow the column values to consume the tab.
 2726 *
 2727 * Yes, 32-bit counters can overflow 8-columns, and
 2728 * 64-bit counters can overflow 16-columns, but that is uncommon.
 2729 */
 2730static inline int print_name(int width, int *printed, char *delim, char *name, enum counter_type type, enum counter_format format)
 2731{
 2732	UNUSED(type);
 2733
 2734	if (format == FORMAT_RAW && width >= 64)
 2735		return (sprintf(outp, "%s%-8s", ((*printed)++ ? delim : ""), name));
 2736	else
 2737		return (sprintf(outp, "%s%s", ((*printed)++ ? delim : ""), name));
 2738}
 2739
 2740static inline int print_hex_value(int width, int *printed, char *delim, unsigned long long value)
 2741{
 2742	if (width <= 32)
 2743		return (sprintf(outp, "%s%08x", ((*printed)++ ? delim : ""), (unsigned int)value));
 2744	else
 2745		return (sprintf(outp, "%s%016llx", ((*printed)++ ? delim : ""), value));
 2746}
 2747
 2748static inline int print_decimal_value(int width, int *printed, char *delim, unsigned long long value)
 2749{
 2750	UNUSED(width);
 2751
 2752	return (sprintf(outp, "%s%lld", ((*printed)++ ? delim : ""), value));
 2753}
 2754
 2755static inline int print_float_value(int *printed, char *delim, double value)
 2756{
 2757	return (sprintf(outp, "%s%0.2f", ((*printed)++ ? delim : ""), value));
 2758}
 2759
 2760void print_header(char *delim)
 2761{
 2762	struct msr_counter *mp;
 2763	struct perf_counter_info *pp;
 2764	struct pmt_counter *ppmt;
 2765	int printed = 0;
 2766
 2767	if (DO_BIC(BIC_USEC))
 2768		outp += sprintf(outp, "%susec", (printed++ ? delim : ""));
 2769	if (DO_BIC(BIC_TOD))
 2770		outp += sprintf(outp, "%sTime_Of_Day_Seconds", (printed++ ? delim : ""));
 2771	if (DO_BIC(BIC_Package))
 2772		outp += sprintf(outp, "%sPackage", (printed++ ? delim : ""));
 2773	if (DO_BIC(BIC_Die))
 2774		outp += sprintf(outp, "%sDie", (printed++ ? delim : ""));
 2775	if (DO_BIC(BIC_L3))
 2776		outp += sprintf(outp, "%sL3", (printed++ ? delim : ""));
 2777	if (DO_BIC(BIC_Node))
 2778		outp += sprintf(outp, "%sNode", (printed++ ? delim : ""));
 2779	if (DO_BIC(BIC_Core))
 2780		outp += sprintf(outp, "%sCore", (printed++ ? delim : ""));
 2781	if (DO_BIC(BIC_CPU))
 2782		outp += sprintf(outp, "%sCPU", (printed++ ? delim : ""));
 2783	if (DO_BIC(BIC_APIC))
 2784		outp += sprintf(outp, "%sAPIC", (printed++ ? delim : ""));
 2785	if (DO_BIC(BIC_X2APIC))
 2786		outp += sprintf(outp, "%sX2APIC", (printed++ ? delim : ""));
 2787	if (DO_BIC(BIC_Avg_MHz))
 2788		outp += sprintf(outp, "%sAvg_MHz", (printed++ ? delim : ""));
 2789	if (DO_BIC(BIC_Busy))
 2790		outp += sprintf(outp, "%sBusy%%", (printed++ ? delim : ""));
 2791	if (DO_BIC(BIC_Bzy_MHz))
 2792		outp += sprintf(outp, "%sBzy_MHz", (printed++ ? delim : ""));
 2793	if (DO_BIC(BIC_TSC_MHz))
 2794		outp += sprintf(outp, "%sTSC_MHz", (printed++ ? delim : ""));
 2795
 2796	if (DO_BIC(BIC_IPC))
 2797		outp += sprintf(outp, "%sIPC", (printed++ ? delim : ""));
 2798
 2799	if (DO_BIC(BIC_IRQ)) {
 2800		if (sums_need_wide_columns)
 2801			outp += sprintf(outp, "%s     IRQ", (printed++ ? delim : ""));
 2802		else
 2803			outp += sprintf(outp, "%sIRQ", (printed++ ? delim : ""));
 2804	}
 2805	if (DO_BIC(BIC_NMI)) {
 2806		if (sums_need_wide_columns)
 2807			outp += sprintf(outp, "%s     NMI", (printed++ ? delim : ""));
 2808		else
 2809			outp += sprintf(outp, "%sNMI", (printed++ ? delim : ""));
 2810	}
 2811
 2812	if (DO_BIC(BIC_SMI))
 2813		outp += sprintf(outp, "%sSMI", (printed++ ? delim : ""));
 2814
 2815	if (DO_BIC(BIC_LLC_RPS))
 2816		outp += sprintf(outp, "%sLLCkRPS", (printed++ ? delim : ""));
 2817
 2818	if (DO_BIC(BIC_LLC_HIT))
 2819		outp += sprintf(outp, "%sLLC%%hit", (printed++ ? delim : ""));
 2820
 2821	for (mp = sys.tp; mp; mp = mp->next)
 2822		outp += print_name(mp->width, &printed, delim, mp->name, mp->type, mp->format);
 2823
 2824	for (pp = sys.perf_tp; pp; pp = pp->next)
 2825		outp += print_name(pp->width, &printed, delim, pp->name, pp->type, pp->format);
 2826
 2827	ppmt = sys.pmt_tp;
 2828	while (ppmt) {
 2829		switch (ppmt->type) {
 2830		case PMT_TYPE_RAW:
 2831			outp += print_name(pmt_counter_get_width(ppmt), &printed, delim, ppmt->name, COUNTER_ITEMS, ppmt->format);
 2832			break;
 2833
 2834		case PMT_TYPE_XTAL_TIME:
 2835		case PMT_TYPE_TCORE_CLOCK:
 2836			outp += print_name(32, &printed, delim, ppmt->name, COUNTER_ITEMS, ppmt->format);
 2837			break;
 2838		}
 2839
 2840		ppmt = ppmt->next;
 2841	}
 2842
 2843	if (DO_BIC(BIC_CPU_c1))
 2844		outp += sprintf(outp, "%sCPU%%c1", (printed++ ? delim : ""));
 2845	if (DO_BIC(BIC_CPU_c3))
 2846		outp += sprintf(outp, "%sCPU%%c3", (printed++ ? delim : ""));
 2847	if (DO_BIC(BIC_CPU_c6))
 2848		outp += sprintf(outp, "%sCPU%%c6", (printed++ ? delim : ""));
 2849	if (DO_BIC(BIC_CPU_c7))
 2850		outp += sprintf(outp, "%sCPU%%c7", (printed++ ? delim : ""));
 2851
 2852	if (DO_BIC(BIC_Mod_c6))
 2853		outp += sprintf(outp, "%sMod%%c6", (printed++ ? delim : ""));
 2854
 2855	if (DO_BIC(BIC_CoreTmp))
 2856		outp += sprintf(outp, "%sCoreTmp", (printed++ ? delim : ""));
 2857
 2858	if (DO_BIC(BIC_CORE_THROT_CNT))
 2859		outp += sprintf(outp, "%sCoreThr", (printed++ ? delim : ""));
 2860
 2861	if (valid_rapl_msrs && !rapl_joules) {
 2862		if (DO_BIC(BIC_CorWatt) && platform->has_per_core_rapl)
 2863			outp += sprintf(outp, "%sCorWatt", (printed++ ? delim : ""));
 2864	} else if (valid_rapl_msrs && rapl_joules) {
 2865		if (DO_BIC(BIC_Cor_J) && platform->has_per_core_rapl)
 2866			outp += sprintf(outp, "%sCor_J", (printed++ ? delim : ""));
 2867	}
 2868
 2869	for (mp = sys.cp; mp; mp = mp->next)
 2870		outp += print_name(mp->width, &printed, delim, mp->name, mp->type, mp->format);
 2871
 2872	for (pp = sys.perf_cp; pp; pp = pp->next)
 2873		outp += print_name(pp->width, &printed, delim, pp->name, pp->type, pp->format);
 2874
 2875	ppmt = sys.pmt_cp;
 2876	while (ppmt) {
 2877		switch (ppmt->type) {
 2878		case PMT_TYPE_RAW:
 2879			outp += print_name(pmt_counter_get_width(ppmt), &printed, delim, ppmt->name, COUNTER_ITEMS, ppmt->format);
 2880
 2881			break;
 2882
 2883		case PMT_TYPE_XTAL_TIME:
 2884		case PMT_TYPE_TCORE_CLOCK:
 2885			outp += print_name(32, &printed, delim, ppmt->name, COUNTER_ITEMS, ppmt->format);
 2886			break;
 2887		}
 2888
 2889		ppmt = ppmt->next;
 2890	}
 2891	if (DO_BIC(BIC_PkgTmp))
 2892		outp += sprintf(outp, "%sPkgTmp", (printed++ ? delim : ""));
 2893
 2894	if (DO_BIC(BIC_GFX_rc6))
 2895		outp += sprintf(outp, "%sGFX%%rc6", (printed++ ? delim : ""));
 2896
 2897	if (DO_BIC(BIC_GFXMHz))
 2898		outp += sprintf(outp, "%sGFXMHz", (printed++ ? delim : ""));
 2899
 2900	if (DO_BIC(BIC_GFXACTMHz))
 2901		outp += sprintf(outp, "%sGFXAMHz", (printed++ ? delim : ""));
 2902
 2903	if (DO_BIC(BIC_SAM_mc6))
 2904		outp += sprintf(outp, "%sSAM%%mc6", (printed++ ? delim : ""));
 2905
 2906	if (DO_BIC(BIC_SAMMHz))
 2907		outp += sprintf(outp, "%sSAMMHz", (printed++ ? delim : ""));
 2908
 2909	if (DO_BIC(BIC_SAMACTMHz))
 2910		outp += sprintf(outp, "%sSAMAMHz", (printed++ ? delim : ""));
 2911
 2912	if (DO_BIC(BIC_Totl_c0))
 2913		outp += sprintf(outp, "%sTotl%%C0", (printed++ ? delim : ""));
 2914	if (DO_BIC(BIC_Any_c0))
 2915		outp += sprintf(outp, "%sAny%%C0", (printed++ ? delim : ""));
 2916	if (DO_BIC(BIC_GFX_c0))
 2917		outp += sprintf(outp, "%sGFX%%C0", (printed++ ? delim : ""));
 2918	if (DO_BIC(BIC_CPUGFX))
 2919		outp += sprintf(outp, "%sCPUGFX%%", (printed++ ? delim : ""));
 2920
 2921	if (DO_BIC(BIC_Pkgpc2))
 2922		outp += sprintf(outp, "%sPkg%%pc2", (printed++ ? delim : ""));
 2923	if (DO_BIC(BIC_Pkgpc3))
 2924		outp += sprintf(outp, "%sPkg%%pc3", (printed++ ? delim : ""));
 2925	if (DO_BIC(BIC_Pkgpc6))
 2926		outp += sprintf(outp, "%sPkg%%pc6", (printed++ ? delim : ""));
 2927	if (DO_BIC(BIC_Pkgpc7))
 2928		outp += sprintf(outp, "%sPkg%%pc7", (printed++ ? delim : ""));
 2929	if (DO_BIC(BIC_Pkgpc8))
 2930		outp += sprintf(outp, "%sPkg%%pc8", (printed++ ? delim : ""));
 2931	if (DO_BIC(BIC_Pkgpc9))
 2932		outp += sprintf(outp, "%sPkg%%pc9", (printed++ ? delim : ""));
 2933	if (DO_BIC(BIC_Pkgpc10))
 2934		outp += sprintf(outp, "%sPk%%pc10", (printed++ ? delim : ""));
 2935	if (DO_BIC(BIC_Diec6))
 2936		outp += sprintf(outp, "%sDie%%c6", (printed++ ? delim : ""));
 2937	if (DO_BIC(BIC_CPU_LPI))
 2938		outp += sprintf(outp, "%sCPU%%LPI", (printed++ ? delim : ""));
 2939	if (DO_BIC(BIC_SYS_LPI))
 2940		outp += sprintf(outp, "%sSYS%%LPI", (printed++ ? delim : ""));
 2941
 2942	if (!rapl_joules) {
 2943		if (DO_BIC(BIC_PkgWatt))
 2944			outp += sprintf(outp, "%sPkgWatt", (printed++ ? delim : ""));
 2945		if (DO_BIC(BIC_CorWatt) && !platform->has_per_core_rapl)
 2946			outp += sprintf(outp, "%sCorWatt", (printed++ ? delim : ""));
 2947		if (DO_BIC(BIC_GFXWatt))
 2948			outp += sprintf(outp, "%sGFXWatt", (printed++ ? delim : ""));
 2949		if (DO_BIC(BIC_RAMWatt))
 2950			outp += sprintf(outp, "%sRAMWatt", (printed++ ? delim : ""));
 2951		if (DO_BIC(BIC_PKG__))
 2952			outp += sprintf(outp, "%sPKG_%%", (printed++ ? delim : ""));
 2953		if (DO_BIC(BIC_RAM__))
 2954			outp += sprintf(outp, "%sRAM_%%", (printed++ ? delim : ""));
 2955	} else {
 2956		if (DO_BIC(BIC_Pkg_J))
 2957			outp += sprintf(outp, "%sPkg_J", (printed++ ? delim : ""));
 2958		if (DO_BIC(BIC_Cor_J) && !platform->has_per_core_rapl)
 2959			outp += sprintf(outp, "%sCor_J", (printed++ ? delim : ""));
 2960		if (DO_BIC(BIC_GFX_J))
 2961			outp += sprintf(outp, "%sGFX_J", (printed++ ? delim : ""));
 2962		if (DO_BIC(BIC_RAM_J))
 2963			outp += sprintf(outp, "%sRAM_J", (printed++ ? delim : ""));
 2964		if (DO_BIC(BIC_PKG__))
 2965			outp += sprintf(outp, "%sPKG_%%", (printed++ ? delim : ""));
 2966		if (DO_BIC(BIC_RAM__))
 2967			outp += sprintf(outp, "%sRAM_%%", (printed++ ? delim : ""));
 2968	}
 2969	if (DO_BIC(BIC_UNCORE_MHZ))
 2970		outp += sprintf(outp, "%sUncMHz", (printed++ ? delim : ""));
 2971
 2972	for (mp = sys.pp; mp; mp = mp->next)
 2973		outp += print_name(mp->width, &printed, delim, mp->name, mp->type, mp->format);
 2974
 2975	for (pp = sys.perf_pp; pp; pp = pp->next)
 2976		outp += print_name(pp->width, &printed, delim, pp->name, pp->type, pp->format);
 2977
 2978	ppmt = sys.pmt_pp;
 2979	while (ppmt) {
 2980		switch (ppmt->type) {
 2981		case PMT_TYPE_RAW:
 2982			outp += print_name(pmt_counter_get_width(ppmt), &printed, delim, ppmt->name, COUNTER_ITEMS, ppmt->format);
 2983			break;
 2984
 2985		case PMT_TYPE_XTAL_TIME:
 2986		case PMT_TYPE_TCORE_CLOCK:
 2987			outp += print_name(32, &printed, delim, ppmt->name, COUNTER_ITEMS, ppmt->format);
 2988			break;
 2989		}
 2990
 2991		ppmt = ppmt->next;
 2992	}
 2993
 2994	if (DO_BIC(BIC_SysWatt))
 2995		outp += sprintf(outp, "%sSysWatt", (printed++ ? delim : ""));
 2996	if (DO_BIC(BIC_Sys_J))
 2997		outp += sprintf(outp, "%sSys_J", (printed++ ? delim : ""));
 2998
 2999	outp += sprintf(outp, "\n");
 3000}
 3001
 3002/*
 3003 * pct(numerator, denominator)
 3004 *
 3005 * Return sanity checked percentage (100.0 * numerator/denominotor)
 3006 *
 3007 * n < 0: nan
 3008 * d <= 0: nan
 3009 * n/d > 1.1: nan
 3010 */
 3011double pct(double numerator, double denominator)
 3012{
 3013	double retval;
 3014
 3015	if (numerator < 0)
 3016		return nan("");
 3017
 3018	if (denominator <= 0)
 3019		return nan("");
 3020
 3021	retval = 100.0 * numerator / denominator;
 3022
 3023	if (retval > 110.0)
 3024		return nan("");
 3025
 3026	return retval;
 3027}
 3028
 3029int dump_counters(PER_THREAD_PARAMS)
 3030{
 3031	int i;
 3032	struct msr_counter *mp;
 3033	struct platform_counters *pplat_cnt = p == package_odd ? &platform_counters_odd : &platform_counters_even;
 3034
 3035	outp += sprintf(outp, "t %p, c %p, p %p\n", t, c, p);
 3036
 3037	if (t) {
 3038		outp += sprintf(outp, "CPU: %d flags 0x%x\n", t->cpu_id, t->flags);
 3039		outp += sprintf(outp, "TSC: %016llX\n", t->tsc);
 3040		outp += sprintf(outp, "aperf: %016llX\n", t->aperf);
 3041		outp += sprintf(outp, "mperf: %016llX\n", t->mperf);
 3042		outp += sprintf(outp, "c1: %016llX\n", t->c1);
 3043
 3044		if (DO_BIC(BIC_IPC))
 3045			outp += sprintf(outp, "IPC: %lld\n", t->instr_count);
 3046
 3047		if (DO_BIC(BIC_IRQ))
 3048			outp += sprintf(outp, "IRQ: %lld\n", t->irq_count);
 3049		if (DO_BIC(BIC_NMI))
 3050			outp += sprintf(outp, "IRQ: %lld\n", t->nmi_count);
 3051		if (DO_BIC(BIC_SMI))
 3052			outp += sprintf(outp, "SMI: %d\n", t->smi_count);
 3053
 3054		outp += sprintf(outp, "LLC refs: %lld", t->llc.references);
 3055		outp += sprintf(outp, "LLC miss: %lld", t->llc.misses);
 3056		outp += sprintf(outp, "LLC Hit%%: %.2f", pct((t->llc.references - t->llc.misses), t->llc.references));
 3057
 3058		for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
 3059			outp += sprintf(outp, "tADDED [%d] %8s msr0x%x: %08llX %s\n", i, mp->name, mp->msr_num, t->counter[i], mp->sp->path);
 3060		}
 3061	}
 3062
 3063	if (c && is_cpu_first_thread_in_core(t, c)) {
 3064		outp += sprintf(outp, "core: %d\n", c->core_id);
 3065		outp += sprintf(outp, "c3: %016llX\n", c->c3);
 3066		outp += sprintf(outp, "c6: %016llX\n", c->c6);
 3067		outp += sprintf(outp, "c7: %016llX\n", c->c7);
 3068		outp += sprintf(outp, "DTS: %dC\n", c->core_temp_c);
 3069		outp += sprintf(outp, "cpu_throt_count: %016llX\n", c->core_throt_cnt);
 3070
 3071		const unsigned long long energy_value = c->core_energy.raw_value * c->core_energy.scale;
 3072		const double energy_scale = c->core_energy.scale;
 3073
 3074		if (c->core_energy.unit == RAPL_UNIT_JOULES)
 3075			outp += sprintf(outp, "Joules: %0llX (scale: %lf)\n", energy_value, energy_scale);
 3076
 3077		for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
 3078			outp += sprintf(outp, "cADDED [%d] %8s msr0x%x: %08llX %s\n", i, mp->name, mp->msr_num, c->counter[i], mp->sp->path);
 3079		}
 3080		outp += sprintf(outp, "mc6_us: %016llX\n", c->mc6_us);
 3081	}
 3082
 3083	if (p && is_cpu_first_core_in_package(t, p)) {
 3084		outp += sprintf(outp, "package: %d\n", p->package_id);
 3085
 3086		outp += sprintf(outp, "Weighted cores: %016llX\n", p->pkg_wtd_core_c0);
 3087		outp += sprintf(outp, "Any cores: %016llX\n", p->pkg_any_core_c0);
 3088		outp += sprintf(outp, "Any GFX: %016llX\n", p->pkg_any_gfxe_c0);
 3089		outp += sprintf(outp, "CPU + GFX: %016llX\n", p->pkg_both_core_gfxe_c0);
 3090
 3091		outp += sprintf(outp, "pc2: %016llX\n", p->pc2);
 3092		if (DO_BIC(BIC_Pkgpc3))
 3093			outp += sprintf(outp, "pc3: %016llX\n", p->pc3);
 3094		if (DO_BIC(BIC_Pkgpc6))
 3095			outp += sprintf(outp, "pc6: %016llX\n", p->pc6);
 3096		if (DO_BIC(BIC_Pkgpc7))
 3097			outp += sprintf(outp, "pc7: %016llX\n", p->pc7);
 3098		outp += sprintf(outp, "pc8: %016llX\n", p->pc8);
 3099		outp += sprintf(outp, "pc9: %016llX\n", p->pc9);
 3100		outp += sprintf(outp, "pc10: %016llX\n", p->pc10);
 3101		outp += sprintf(outp, "cpu_lpi: %016llX\n", p->cpu_lpi);
 3102		outp += sprintf(outp, "sys_lpi: %016llX\n", p->sys_lpi);
 3103		outp += sprintf(outp, "Joules PKG: %0llX\n", p->energy_pkg.raw_value);
 3104		outp += sprintf(outp, "Joules COR: %0llX\n", p->energy_cores.raw_value);
 3105		outp += sprintf(outp, "Joules GFX: %0llX\n", p->energy_gfx.raw_value);
 3106		outp += sprintf(outp, "Joules RAM: %0llX\n", p->energy_dram.raw_value);
 3107		outp += sprintf(outp, "Joules PSYS: %0llX\n", pplat_cnt->energy_psys.raw_value);
 3108		outp += sprintf(outp, "Throttle PKG: %0llX\n", p->rapl_pkg_perf_status.raw_value);
 3109		outp += sprintf(outp, "Throttle RAM: %0llX\n", p->rapl_dram_perf_status.raw_value);
 3110		outp += sprintf(outp, "PTM: %dC\n", p->pkg_temp_c);
 3111
 3112		for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
 3113			outp += sprintf(outp, "pADDED [%d] %8s msr0x%x: %08llX %s\n", i, mp->name, mp->msr_num, p->counter[i], mp->sp->path);
 3114		}
 3115	}
 3116
 3117	outp += sprintf(outp, "\n");
 3118
 3119	return 0;
 3120}
 3121
 3122double rapl_counter_get_value(const struct rapl_counter *c, enum rapl_unit desired_unit, double interval)
 3123{
 3124	assert(desired_unit != RAPL_UNIT_INVALID);
 3125
 3126	/*
 3127	 * For now we don't expect anything other than joules,
 3128	 * so just simplify the logic.
 3129	 */
 3130	assert(c->unit == RAPL_UNIT_JOULES);
 3131
 3132	const double scaled = c->raw_value * c->scale;
 3133
 3134	if (desired_unit == RAPL_UNIT_WATTS)
 3135		return scaled / interval;
 3136	return scaled;
 3137}
 3138
 3139void get_perf_llc_stats(int cpu, struct llc_stats *llc)
 3140{
 3141	struct read_format {
 3142		unsigned long long num_read;
 3143		struct llc_stats llc;
 3144	} r;
 3145	const ssize_t expected_read_size = sizeof(r);
 3146	ssize_t actual_read_size;
 3147
 3148	actual_read_size = read(fd_llc_percpu[cpu], &r, expected_read_size);
 3149
 3150	if (actual_read_size == -1)
 3151		err(-1, "%s(cpu%d,) %d,,%ld\n", __func__, cpu, fd_llc_percpu[cpu], expected_read_size);
 3152
 3153	llc->references = r.llc.references;
 3154	llc->misses = r.llc.misses;
 3155	if (actual_read_size != expected_read_size)
 3156		warn("%s: failed to read perf_data (req %zu act %zu)", __func__, expected_read_size, actual_read_size);
 3157}
 3158
 3159/*
 3160 * column formatting convention & formats
 3161 */
 3162int format_counters(PER_THREAD_PARAMS)
 3163{
 3164	static int count;
 3165
 3166	struct platform_counters *pplat_cnt = NULL;
 3167	double interval_float, tsc;
 3168	char *fmt8 = "%s%.2f";
 3169
 3170	int i;
 3171	struct msr_counter *mp;
 3172	struct perf_counter_info *pp;
 3173	struct pmt_counter *ppmt;
 3174	char *delim = "\t";
 3175	int printed = 0;
 3176
 3177	if (t == &average.threads) {
 3178		pplat_cnt = count & 1 ? &platform_counters_odd : &platform_counters_even;
 3179		++count;
 3180	}
 3181
 3182	/* if showing only 1st thread in core and this isn't one, bail out */
 3183	if (show_core_only && !is_cpu_first_thread_in_core(t, c))
 3184		return 0;
 3185
 3186	/* if showing only 1st thread in pkg and this isn't one, bail out */
 3187	if (show_pkg_only && !is_cpu_first_core_in_package(t, p))
 3188		return 0;
 3189
 3190	/*if not summary line and --cpu is used */
 3191	if ((t != &average.threads) && (cpu_subset && !CPU_ISSET_S(t->cpu_id, cpu_subset_size, cpu_subset)))
 3192		return 0;
 3193
 3194	if (DO_BIC(BIC_USEC)) {
 3195		/* on each row, print how many usec each timestamp took to gather */
 3196		struct timeval tv;
 3197
 3198		timersub(&t->tv_end, &t->tv_begin, &tv);
 3199		outp += sprintf(outp, "%5ld\t", tv.tv_sec * 1000000 + tv.tv_usec);
 3200	}
 3201
 3202	/* Time_Of_Day_Seconds: on each row, print sec.usec last timestamp taken */
 3203	if (DO_BIC(BIC_TOD))
 3204		outp += sprintf(outp, "%10ld.%06ld\t", t->tv_end.tv_sec, t->tv_end.tv_usec);
 3205
 3206	interval_float = t->tv_delta.tv_sec + t->tv_delta.tv_usec / 1000000.0;
 3207
 3208	tsc = t->tsc * tsc_tweak;
 3209
 3210	/* topo columns, print blanks on 1st (average) line */
 3211	if (t == &average.threads) {
 3212		if (DO_BIC(BIC_Package))
 3213			outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
 3214		if (DO_BIC(BIC_Die))
 3215			outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
 3216		if (DO_BIC(BIC_L3))
 3217			outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
 3218		if (DO_BIC(BIC_Node))
 3219			outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
 3220		if (DO_BIC(BIC_Core))
 3221			outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
 3222		if (DO_BIC(BIC_CPU))
 3223			outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
 3224		if (DO_BIC(BIC_APIC))
 3225			outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
 3226		if (DO_BIC(BIC_X2APIC))
 3227			outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
 3228	} else {
 3229		if (DO_BIC(BIC_Package)) {
 3230			if (p)
 3231				outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->package_id);
 3232			else
 3233				outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
 3234		}
 3235		if (DO_BIC(BIC_Die)) {
 3236			if (c)
 3237				outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), cpus[t->cpu_id].die_id);
 3238			else
 3239				outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
 3240		}
 3241		if (DO_BIC(BIC_L3)) {
 3242			if (c)
 3243				outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), cpus[t->cpu_id].l3_id);
 3244			else
 3245				outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
 3246		}
 3247		if (DO_BIC(BIC_Node)) {
 3248			if (t)
 3249				outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), cpus[t->cpu_id].physical_node_id);
 3250			else
 3251				outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
 3252		}
 3253		if (DO_BIC(BIC_Core)) {
 3254			if (c)
 3255				outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), c->core_id);
 3256			else
 3257				outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
 3258		}
 3259		if (DO_BIC(BIC_CPU))
 3260			outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->cpu_id);
 3261		if (DO_BIC(BIC_APIC))
 3262			outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->apic_id);
 3263		if (DO_BIC(BIC_X2APIC))
 3264			outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->x2apic_id);
 3265	}
 3266
 3267	if (DO_BIC(BIC_Avg_MHz))
 3268		outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), 1.0 / units * t->aperf / interval_float);
 3269
 3270	if (DO_BIC(BIC_Busy))
 3271		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->mperf, tsc));
 3272
 3273	if (DO_BIC(BIC_Bzy_MHz)) {
 3274		if (has_base_hz)
 3275			outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), base_hz / units * t->aperf / t->mperf);
 3276		else
 3277			outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), tsc / units * t->aperf / t->mperf / interval_float);
 3278	}
 3279
 3280	if (DO_BIC(BIC_TSC_MHz))
 3281		outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), 1.0 * t->tsc / units / interval_float);
 3282
 3283	if (DO_BIC(BIC_IPC))
 3284		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 1.0 * t->instr_count / t->aperf);
 3285
 3286	/* IRQ */
 3287	if (DO_BIC(BIC_IRQ)) {
 3288		if (sums_need_wide_columns)
 3289			outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), t->irq_count);
 3290		else
 3291			outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), t->irq_count);
 3292	}
 3293
 3294	/* NMI */
 3295	if (DO_BIC(BIC_NMI)) {
 3296		if (sums_need_wide_columns)
 3297			outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), t->nmi_count);
 3298		else
 3299			outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), t->nmi_count);
 3300	}
 3301
 3302	/* SMI */
 3303	if (DO_BIC(BIC_SMI))
 3304		outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->smi_count);
 3305
 3306	/* LLC Stats */
 3307	if (DO_BIC(BIC_LLC_RPS) || DO_BIC(BIC_LLC_HIT)) {
 3308		if (DO_BIC(BIC_LLC_RPS))
 3309			outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), t->llc.references / interval_float / 1000);
 3310
 3311		if (DO_BIC(BIC_LLC_HIT))
 3312			outp += sprintf(outp, fmt8, (printed++ ? delim : ""), pct((t->llc.references - t->llc.misses), t->llc.references));
 3313	}
 3314
 3315	/* Added Thread Counters */
 3316	for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
 3317		if (mp->format == FORMAT_RAW)
 3318			outp += print_hex_value(mp->width, &printed, delim, t->counter[i]);
 3319		else if (mp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE)
 3320			outp += print_decimal_value(mp->width, &printed, delim, t->counter[i]);
 3321		else if (mp->format == FORMAT_PERCENT) {
 3322			if (mp->type == COUNTER_USEC)
 3323				outp += print_float_value(&printed, delim, t->counter[i] / interval_float / 10000);
 3324			else
 3325				outp += print_float_value(&printed, delim, pct(t->counter[i], tsc));
 3326		}
 3327	}
 3328
 3329	/* Added perf Thread Counters */
 3330	for (i = 0, pp = sys.perf_tp; pp; ++i, pp = pp->next) {
 3331		if (pp->format == FORMAT_RAW)
 3332			outp += print_hex_value(pp->width, &printed, delim, t->perf_counter[i]);
 3333		else if (pp->format == FORMAT_DELTA || pp->format == FORMAT_AVERAGE)
 3334			outp += print_decimal_value(pp->width, &printed, delim, t->perf_counter[i]);
 3335		else if (pp->format == FORMAT_PERCENT) {
 3336			if (pp->type == COUNTER_USEC)
 3337				outp += print_float_value(&printed, delim, t->perf_counter[i] / interval_float / 10000);
 3338			else
 3339				outp += print_float_value(&printed, delim, pct(t->perf_counter[i], tsc));
 3340		}
 3341	}
 3342
 3343	/* Added PMT Thread Counters */
 3344	for (i = 0, ppmt = sys.pmt_tp; ppmt; i++, ppmt = ppmt->next) {
 3345		const unsigned long value_raw = t->pmt_counter[i];
 3346		double value_converted;
 3347		switch (ppmt->type) {
 3348		case PMT_TYPE_RAW:
 3349			outp += print_hex_value(pmt_counter_get_width(ppmt), &printed, delim, t->pmt_counter[i]);
 3350			break;
 3351
 3352		case PMT_TYPE_XTAL_TIME:
 3353			value_converted = pct(value_raw / crystal_hz, interval_float);
 3354			outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
 3355			break;
 3356
 3357		case PMT_TYPE_TCORE_CLOCK:
 3358			value_converted = pct(value_raw / tcore_clock_freq_hz, interval_float);
 3359			outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
 3360		}
 3361	}
 3362
 3363	/* C1 */
 3364	if (DO_BIC(BIC_CPU_c1))
 3365		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->c1, tsc));
 3366
 3367	/* print per-core data only for 1st thread in core */
 3368	if (!is_cpu_first_thread_in_core(t, c))
 3369		goto done;
 3370
 3371	if (DO_BIC(BIC_CPU_c3))
 3372		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c3, tsc));
 3373	if (DO_BIC(BIC_CPU_c6))
 3374		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c6, tsc));
 3375	if (DO_BIC(BIC_CPU_c7))
 3376		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c7, tsc));
 3377
 3378	/* Mod%c6 */
 3379	if (DO_BIC(BIC_Mod_c6))
 3380		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->mc6_us, tsc));
 3381
 3382	if (DO_BIC(BIC_CoreTmp))
 3383		outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), c->core_temp_c);
 3384
 3385	/* Core throttle count */
 3386	if (DO_BIC(BIC_CORE_THROT_CNT))
 3387		outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), c->core_throt_cnt);
 3388
 3389	/* Added Core Counters */
 3390	for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
 3391		if (mp->format == FORMAT_RAW)
 3392			outp += print_hex_value(mp->width, &printed, delim, c->counter[i]);
 3393		else if (mp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE)
 3394			outp += print_decimal_value(mp->width, &printed, delim, c->counter[i]);
 3395		else if (mp->format == FORMAT_PERCENT)
 3396			outp += print_float_value(&printed, delim, pct(c->counter[i], tsc));
 3397	}
 3398
 3399	/* Added perf Core counters */
 3400	for (i = 0, pp = sys.perf_cp; pp; i++, pp = pp->next) {
 3401		if (pp->format == FORMAT_RAW)
 3402			outp += print_hex_value(pp->width, &printed, delim, c->perf_counter[i]);
 3403		else if (pp->format == FORMAT_DELTA || pp->format == FORMAT_AVERAGE)
 3404			outp += print_decimal_value(pp->width, &printed, delim, c->perf_counter[i]);
 3405		else if (pp->format == FORMAT_PERCENT)
 3406			outp += print_float_value(&printed, delim, pct(c->perf_counter[i], tsc));
 3407	}
 3408
 3409	/* Added PMT Core counters */
 3410	for (i = 0, ppmt = sys.pmt_cp; ppmt; i++, ppmt = ppmt->next) {
 3411		const unsigned long value_raw = c->pmt_counter[i];
 3412		double value_converted;
 3413		switch (ppmt->type) {
 3414		case PMT_TYPE_RAW:
 3415			outp += print_hex_value(pmt_counter_get_width(ppmt), &printed, delim, c->pmt_counter[i]);
 3416			break;
 3417
 3418		case PMT_TYPE_XTAL_TIME:
 3419			value_converted = pct(value_raw / crystal_hz, interval_float);
 3420			outp += print_float_value(&printed, delim, value_converted);
 3421			break;
 3422
 3423		case PMT_TYPE_TCORE_CLOCK:
 3424			value_converted = pct(value_raw / tcore_clock_freq_hz, interval_float);
 3425			outp += print_float_value(&printed, delim, value_converted);
 3426		}
 3427	}
 3428
 3429	if (DO_BIC(BIC_CorWatt) && platform->has_per_core_rapl)
 3430		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), rapl_counter_get_value(&c->core_energy, RAPL_UNIT_WATTS, interval_float));
 3431	if (DO_BIC(BIC_Cor_J) && platform->has_per_core_rapl)
 3432		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), rapl_counter_get_value(&c->core_energy, RAPL_UNIT_JOULES, interval_float));
 3433
 3434	/* print per-package data only for 1st core in package */
 3435	if (!is_cpu_first_core_in_package(t, p))
 3436		goto done;
 3437
 3438	/* PkgTmp */
 3439	if (DO_BIC(BIC_PkgTmp))
 3440		outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->pkg_temp_c);
 3441
 3442	/* GFXrc6 */
 3443	if (DO_BIC(BIC_GFX_rc6)) {
 3444		if (p->gfx_rc6_ms == -1) {	/* detect GFX counter reset */
 3445			outp += sprintf(outp, "%s**.**", (printed++ ? delim : ""));
 3446		} else {
 3447			outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), p->gfx_rc6_ms / 10.0 / interval_float);
 3448		}
 3449	}
 3450
 3451	/* GFXMHz */
 3452	if (DO_BIC(BIC_GFXMHz))
 3453		outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->gfx_mhz);
 3454
 3455	/* GFXACTMHz */
 3456	if (DO_BIC(BIC_GFXACTMHz))
 3457		outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->gfx_act_mhz);
 3458
 3459	/* SAMmc6 */
 3460	if (DO_BIC(BIC_SAM_mc6)) {
 3461		if (p->sam_mc6_ms == -1) {	/* detect GFX counter reset */
 3462			outp += sprintf(outp, "%s**.**", (printed++ ? delim : ""));
 3463		} else {
 3464			outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), p->sam_mc6_ms / 10.0 / interval_float);
 3465		}
 3466	}
 3467
 3468	/* SAMMHz */
 3469	if (DO_BIC(BIC_SAMMHz))
 3470		outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->sam_mhz);
 3471
 3472	/* SAMACTMHz */
 3473	if (DO_BIC(BIC_SAMACTMHz))
 3474		outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->sam_act_mhz);
 3475
 3476	/* Totl%C0, Any%C0 GFX%C0 CPUGFX% */
 3477	if (DO_BIC(BIC_Totl_c0))
 3478		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100 * p->pkg_wtd_core_c0 / tsc);	/* can exceed 100% */
 3479	if (DO_BIC(BIC_Any_c0))
 3480		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_core_c0, tsc));
 3481	if (DO_BIC(BIC_GFX_c0))
 3482		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_gfxe_c0, tsc));
 3483	if (DO_BIC(BIC_CPUGFX))
 3484		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_both_core_gfxe_c0, tsc));
 3485
 3486	if (DO_BIC(BIC_Pkgpc2))
 3487		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc2, tsc));
 3488	if (DO_BIC(BIC_Pkgpc3))
 3489		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc3, tsc));
 3490	if (DO_BIC(BIC_Pkgpc6))
 3491		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc6, tsc));
 3492	if (DO_BIC(BIC_Pkgpc7))
 3493		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc7, tsc));
 3494	if (DO_BIC(BIC_Pkgpc8))
 3495		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc8, tsc));
 3496	if (DO_BIC(BIC_Pkgpc9))
 3497		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc9, tsc));
 3498	if (DO_BIC(BIC_Pkgpc10))
 3499		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc10, tsc));
 3500
 3501	if (DO_BIC(BIC_Diec6))
 3502		outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->die_c6 / crystal_hz, interval_float));
 3503
 3504	if (DO_BIC(BIC_CPU_LPI)) {
 3505		if (p->cpu_lpi >= 0)
 3506			outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->cpu_lpi / 1000000.0, interval_float));
 3507		else
 3508			outp += sprintf(outp, "%s(neg)", (printed++ ? delim : ""));
 3509	}
 3510	if (DO_BIC(BIC_SYS_LPI)) {
 3511		if (p->sys_lpi >= 0)
 3512			outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->sys_lpi / 1000000.0, interval_float));
 3513		else
 3514			outp += sprintf(outp, "%s(neg)", (printed++ ? delim : ""));
 3515	}
 3516
 3517	if (DO_BIC(BIC_PkgWatt))
 3518		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), rapl_counter_get_value(&p->energy_pkg, RAPL_UNIT_WATTS, interval_float));
 3519	if (DO_BIC(BIC_CorWatt) && !platform->has_per_core_rapl)
 3520		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), rapl_counter_get_value(&p->energy_cores, RAPL_UNIT_WATTS, interval_float));
 3521	if (DO_BIC(BIC_GFXWatt))
 3522		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), rapl_counter_get_value(&p->energy_gfx, RAPL_UNIT_WATTS, interval_float));
 3523	if (DO_BIC(BIC_RAMWatt))
 3524		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), rapl_counter_get_value(&p->energy_dram, RAPL_UNIT_WATTS, interval_float));
 3525	if (DO_BIC(BIC_Pkg_J))
 3526		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), rapl_counter_get_value(&p->energy_pkg, RAPL_UNIT_JOULES, interval_float));
 3527	if (DO_BIC(BIC_Cor_J) && !platform->has_per_core_rapl)
 3528		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), rapl_counter_get_value(&p->energy_cores, RAPL_UNIT_JOULES, interval_float));
 3529	if (DO_BIC(BIC_GFX_J))
 3530		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), rapl_counter_get_value(&p->energy_gfx, RAPL_UNIT_JOULES, interval_float));
 3531	if (DO_BIC(BIC_RAM_J))
 3532		outp += sprintf(outp, fmt8, (printed++ ? delim : ""), rapl_counter_get_value(&p->energy_dram, RAPL_UNIT_JOULES, interval_float));
 3533	if (DO_BIC(BIC_PKG__))
 3534		outp +=
 3535		    sprintf(outp, fmt8, (printed++ ? delim : ""), rapl_counter_get_value(&p->rapl_pkg_perf_status, RAPL_UNIT_WATTS, interval_float));
 3536	if (DO_BIC(BIC_RAM__))
 3537		outp +=
 3538		    sprintf(outp, fmt8, (printed++ ? delim : ""), rapl_counter_get_value(&p->rapl_dram_perf_status, RAPL_UNIT_WATTS, interval_float));
 3539	/* UncMHz */
 3540	if (DO_BIC(BIC_UNCORE_MHZ))
 3541		outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->uncore_mhz);
 3542
 3543	/* Added Package Counters */
 3544	for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
 3545		if (mp->format == FORMAT_RAW)
 3546			outp += print_hex_value(mp->width, &printed, delim, p->counter[i]);
 3547		else if (mp->type == COUNTER_K2M)
 3548			outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), (unsigned int)p->counter[i] / 1000);
 3549		else if (mp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE)
 3550			outp += print_decimal_value(mp->width, &printed, delim, p->counter[i]);
 3551		else if (mp->format == FORMAT_PERCENT)
 3552			outp += print_float_value(&printed, delim, pct(p->counter[i], tsc));
 3553	}
 3554
 3555	/* Added perf Package Counters */
 3556	for (i = 0, pp = sys.perf_pp; pp; i++, pp = pp->next) {
 3557		if (pp->format == FORMAT_RAW)
 3558			outp += print_hex_value(pp->width, &printed, delim, p->perf_counter[i]);
 3559		else if (pp->type == COUNTER_K2M)
 3560			outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), (unsigned int)p->perf_counter[i] / 1000);
 3561		else if (pp->format == FORMAT_DELTA || pp->format == FORMAT_AVERAGE)
 3562			outp += print_decimal_value(pp->width, &printed, delim, p->perf_counter[i]);
 3563		else if (pp->format == FORMAT_PERCENT)
 3564			outp += print_float_value(&printed, delim, pct(p->perf_counter[i], tsc));
 3565	}
 3566
 3567	/* Added PMT Package Counters */
 3568	for (i = 0, ppmt = sys.pmt_pp; ppmt; i++, ppmt = ppmt->next) {
 3569		const unsigned long value_raw = p->pmt_counter[i];
 3570		double value_converted;
 3571		switch (ppmt->type) {
 3572		case PMT_TYPE_RAW:
 3573			outp += print_hex_value(pmt_counter_get_width(ppmt), &printed, delim, p->pmt_counter[i]);
 3574			break;
 3575
 3576		case PMT_TYPE_XTAL_TIME:
 3577			value_converted = pct(value_raw / crystal_hz, interval_float);
 3578			outp += print_float_value(&printed, delim, value_converted);
 3579			break;
 3580
 3581		case PMT_TYPE_TCORE_CLOCK:
 3582			value_converted = pct(value_raw / tcore_clock_freq_hz, interval_float);
 3583			outp += print_float_value(&printed, delim, value_converted);
 3584		}
 3585	}
 3586
 3587	if (DO_BIC(BIC_SysWatt) && (t == &average.threads))
 3588		outp += sprintf(outp, fmt8, (printed++ ? delim : ""),
 3589				rapl_counter_get_value(&pplat_cnt->energy_psys, RAPL_UNIT_WATTS, interval_float));
 3590	if (DO_BIC(BIC_Sys_J) && (t == &average.threads))
 3591		outp += sprintf(outp, fmt8, (printed++ ? delim : ""),
 3592				rapl_counter_get_value(&pplat_cnt->energy_psys, RAPL_UNIT_JOULES, interval_float));
 3593
 3594done:
 3595	if (*(outp - 1) != '\n')
 3596		outp += sprintf(outp, "\n");
 3597
 3598	return 0;
 3599}
 3600
 3601void flush_output_stdout(void)
 3602{
 3603	FILE *filep;
 3604
 3605	if (outf == stderr)
 3606		filep = stdout;
 3607	else
 3608		filep = outf;
 3609
 3610	fputs(output_buffer, filep);
 3611	fflush(filep);
 3612
 3613	outp = output_buffer;
 3614}
 3615
 3616void flush_output_stderr(void)
 3617{
 3618	fputs(output_buffer, outf);
 3619	fflush(outf);
 3620	outp = output_buffer;
 3621}
 3622
 3623void format_all_counters(PER_THREAD_PARAMS)
 3624{
 3625	static int count;
 3626
 3627	if ((!count || (header_iterations && !(count % header_iterations))) || !summary_only)
 3628		print_header("\t");
 3629
 3630	format_counters(&average.threads, &average.cores, &average.packages);
 3631
 3632	count++;
 3633
 3634	if (summary_only)
 3635		return;
 3636
 3637	for_all_cpus(format_counters, t, c, p);
 3638}
 3639
 3640#define DELTA_WRAP32(new, old)			\
 3641	old = ((((unsigned long long)new << 32) - ((unsigned long long)old << 32)) >> 32);
 3642
 3643int delta_package(struct pkg_data *new, struct pkg_data *old)
 3644{
 3645	int i;
 3646	struct msr_counter *mp;
 3647	struct perf_counter_info *pp;
 3648	struct pmt_counter *ppmt;
 3649
 3650	if (DO_BIC(BIC_Totl_c0))
 3651		old->pkg_wtd_core_c0 = new->pkg_wtd_core_c0 - old->pkg_wtd_core_c0;
 3652	if (DO_BIC(BIC_Any_c0))
 3653		old->pkg_any_core_c0 = new->pkg_any_core_c0 - old->pkg_any_core_c0;
 3654	if (DO_BIC(BIC_GFX_c0))
 3655		old->pkg_any_gfxe_c0 = new->pkg_any_gfxe_c0 - old->pkg_any_gfxe_c0;
 3656	if (DO_BIC(BIC_CPUGFX))
 3657		old->pkg_both_core_gfxe_c0 = new->pkg_both_core_gfxe_c0 - old->pkg_both_core_gfxe_c0;
 3658
 3659	old->pc2 = new->pc2 - old->pc2;
 3660	if (DO_BIC(BIC_Pkgpc3))
 3661		old->pc3 = new->pc3 - old->pc3;
 3662	if (DO_BIC(BIC_Pkgpc6))
 3663		old->pc6 = new->pc6 - old->pc6;
 3664	if (DO_BIC(BIC_Pkgpc7))
 3665		old->pc7 = new->pc7 - old->pc7;
 3666	old->pc8 = new->pc8 - old->pc8;
 3667	old->pc9 = new->pc9 - old->pc9;
 3668	old->pc10 = new->pc10 - old->pc10;
 3669	old->die_c6 = new->die_c6 - old->die_c6;
 3670	old->cpu_lpi = new->cpu_lpi - old->cpu_lpi;
 3671	old->sys_lpi = new->sys_lpi - old->sys_lpi;
 3672	old->pkg_temp_c = new->pkg_temp_c;
 3673
 3674	/* flag an error when rc6 counter resets/wraps */
 3675	if (old->gfx_rc6_ms > new->gfx_rc6_ms)
 3676		old->gfx_rc6_ms = -1;
 3677	else
 3678		old->gfx_rc6_ms = new->gfx_rc6_ms - old->gfx_rc6_ms;
 3679
 3680	old->uncore_mhz = new->uncore_mhz;
 3681	old->gfx_mhz = new->gfx_mhz;
 3682	old->gfx_act_mhz = new->gfx_act_mhz;
 3683
 3684	/* flag an error when mc6 counter resets/wraps */
 3685	if (old->sam_mc6_ms > new->sam_mc6_ms)
 3686		old->sam_mc6_ms = -1;
 3687	else
 3688		old->sam_mc6_ms = new->sam_mc6_ms - old->sam_mc6_ms;
 3689
 3690	old->sam_mhz = new->sam_mhz;
 3691	old->sam_act_mhz = new->sam_act_mhz;
 3692
 3693	old->energy_pkg.raw_value = new->energy_pkg.raw_value - old->energy_pkg.raw_value;
 3694	old->energy_cores.raw_value = new->energy_cores.raw_value - old->energy_cores.raw_value;
 3695	old->energy_gfx.raw_value = new->energy_gfx.raw_value - old->energy_gfx.raw_value;
 3696	old->energy_dram.raw_value = new->energy_dram.raw_value - old->energy_dram.raw_value;
 3697	old->rapl_pkg_perf_status.raw_value = new->rapl_pkg_perf_status.raw_value - old->rapl_pkg_perf_status.raw_value;
 3698	old->rapl_dram_perf_status.raw_value = new->rapl_dram_perf_status.raw_value - old->rapl_dram_perf_status.raw_value;
 3699
 3700	for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
 3701		if (mp->format == FORMAT_RAW)
 3702			old->counter[i] = new->counter[i];
 3703		else if (mp->format == FORMAT_AVERAGE)
 3704			old->counter[i] = new->counter[i];
 3705		else
 3706			old->counter[i] = new->counter[i] - old->counter[i];
 3707	}
 3708
 3709	for (i = 0, pp = sys.perf_pp; pp; i++, pp = pp->next) {
 3710		if (pp->format == FORMAT_RAW)
 3711			old->perf_counter[i] = new->perf_counter[i];
 3712		else if (pp->format == FORMAT_AVERAGE)
 3713			old->perf_counter[i] = new->perf_counter[i];
 3714		else
 3715			old->perf_counter[i] = new->perf_counter[i] - old->perf_counter[i];
 3716	}
 3717
 3718	for (i = 0, ppmt = sys.pmt_pp; ppmt; i++, ppmt = ppmt->next) {
 3719		if (ppmt->format == FORMAT_RAW)
 3720			old->pmt_counter[i] = new->pmt_counter[i];
 3721		else
 3722			old->pmt_counter[i] = new->pmt_counter[i] - old->pmt_counter[i];
 3723	}
 3724
 3725	return 0;
 3726}
 3727
 3728void delta_core(struct core_data *new, struct core_data *old)
 3729{
 3730	int i;
 3731	struct msr_counter *mp;
 3732	struct perf_counter_info *pp;
 3733	struct pmt_counter *ppmt;
 3734
 3735	old->c3 = new->c3 - old->c3;
 3736	old->c6 = new->c6 - old->c6;
 3737	old->c7 = new->c7 - old->c7;
 3738	old->core_temp_c = new->core_temp_c;
 3739	old->core_throt_cnt = new->core_throt_cnt - old->core_throt_cnt;
 3740	old->mc6_us = new->mc6_us - old->mc6_us;
 3741
 3742	DELTA_WRAP32(new->core_energy.raw_value, old->core_energy.raw_value);
 3743
 3744	for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
 3745		if (mp->format == FORMAT_RAW || mp->format == FORMAT_AVERAGE)
 3746			old->counter[i] = new->counter[i];
 3747		else
 3748			old->counter[i] = new->counter[i] - old->counter[i];
 3749	}
 3750
 3751	for (i = 0, pp = sys.perf_cp; pp; i++, pp = pp->next) {
 3752		if (pp->format == FORMAT_RAW)
 3753			old->perf_counter[i] = new->perf_counter[i];
 3754		else
 3755			old->perf_counter[i] = new->perf_counter[i] - old->perf_counter[i];
 3756	}
 3757
 3758	for (i = 0, ppmt = sys.pmt_cp; ppmt; i++, ppmt = ppmt->next) {
 3759		if (ppmt->format == FORMAT_RAW)
 3760			old->pmt_counter[i] = new->pmt_counter[i];
 3761		else
 3762			old->pmt_counter[i] = new->pmt_counter[i] - old->pmt_counter[i];
 3763	}
 3764}
 3765
 3766int soft_c1_residency_display(int bic)
 3767{
 3768	if (!DO_BIC(BIC_CPU_c1) || platform->has_msr_core_c1_res)
 3769		return 0;
 3770
 3771	return DO_BIC_READ(bic);
 3772}
 3773
 3774/*
 3775 * old = new - old
 3776 */
 3777int delta_thread(struct thread_data *new, struct thread_data *old, struct core_data *core_delta)
 3778{
 3779	int i;
 3780	struct msr_counter *mp;
 3781	struct perf_counter_info *pp;
 3782	struct pmt_counter *ppmt;
 3783
 3784	/* we run cpuid just the 1st time, copy the results */
 3785	if (DO_BIC(BIC_APIC))
 3786		new->apic_id = old->apic_id;
 3787	if (DO_BIC(BIC_X2APIC))
 3788		new->x2apic_id = old->x2apic_id;
 3789
 3790	/*
 3791	 * the timestamps from start of measurement interval are in "old"
 3792	 * the timestamp from end of measurement interval are in "new"
 3793	 * over-write old w/ new so we can print end of interval values
 3794	 */
 3795
 3796	timersub(&new->tv_begin, &old->tv_begin, &old->tv_delta);
 3797	old->tv_begin = new->tv_begin;
 3798	old->tv_end = new->tv_end;
 3799
 3800	old->tsc = new->tsc - old->tsc;
 3801
 3802	/* check for TSC < 1 Mcycles over interval */
 3803	if (old->tsc < (1000 * 1000))
 3804		errx(-3, "Insanely slow TSC rate, TSC stops in idle?\n"
 3805		     "You can disable all c-states by booting with \"idle=poll\"\n" "or just the deep ones with \"processor.max_cstate=1\"");
 3806
 3807	old->c1 = new->c1 - old->c1;
 3808
 3809	if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz) || DO_BIC(BIC_IPC)
 3810	    || soft_c1_residency_display(BIC_Avg_MHz)) {
 3811		if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) {
 3812			old->aperf = new->aperf - old->aperf;
 3813			old->mperf = new->mperf - old->mperf;
 3814		} else {
 3815			return -1;
 3816		}
 3817	}
 3818
 3819	if (platform->has_msr_core_c1_res) {
 3820		/*
 3821		 * Some models have a dedicated C1 residency MSR,
 3822		 * which should be more accurate than the derivation below.
 3823		 */
 3824	} else {
 3825		/*
 3826		 * As counter collection is not atomic,
 3827		 * it is possible for mperf's non-halted cycles + idle states
 3828		 * to exceed TSC's all cycles: show c1 = 0% in that case.
 3829		 */
 3830		if ((old->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > (old->tsc * tsc_tweak))
 3831			old->c1 = 0;
 3832		else {
 3833			/* normal case, derive c1 */
 3834			old->c1 = (old->tsc * tsc_tweak) - old->mperf - core_delta->c3 - core_delta->c6 - core_delta->c7;
 3835		}
 3836	}
 3837
 3838	if (old->mperf == 0) {
 3839		if (debug > 1)
 3840			fprintf(outf, "cpu%d MPERF 0!\n", old->cpu_id);
 3841		old->mperf = 1;	/* divide by 0 protection */
 3842	}
 3843
 3844	if (DO_BIC(BIC_IPC))
 3845		old->instr_count = new->instr_count - old->instr_count;
 3846
 3847	if (DO_BIC(BIC_IRQ))
 3848		old->irq_count = new->irq_count - old->irq_count;
 3849
 3850	if (DO_BIC(BIC_NMI))
 3851		old->nmi_count = new->nmi_count - old->nmi_count;
 3852
 3853	if (DO_BIC(BIC_SMI))
 3854		old->smi_count = new->smi_count - old->smi_count;
 3855
 3856	if (DO_BIC(BIC_LLC_RPS))
 3857		old->llc.references = new->llc.references - old->llc.references;
 3858
 3859	if (DO_BIC(BIC_LLC_HIT))
 3860		old->llc.misses = new->llc.misses - old->llc.misses;
 3861
 3862	for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
 3863		if (mp->format == FORMAT_RAW || mp->format == FORMAT_AVERAGE)
 3864			old->counter[i] = new->counter[i];
 3865		else
 3866			old->counter[i] = new->counter[i] - old->counter[i];
 3867	}
 3868
 3869	for (i = 0, pp = sys.perf_tp; pp; i++, pp = pp->next) {
 3870		if (pp->format == FORMAT_RAW)
 3871			old->perf_counter[i] = new->perf_counter[i];
 3872		else
 3873			old->perf_counter[i] = new->perf_counter[i] - old->perf_counter[i];
 3874	}
 3875
 3876	for (i = 0, ppmt = sys.pmt_tp; ppmt; i++, ppmt = ppmt->next) {
 3877		if (ppmt->format == FORMAT_RAW)
 3878			old->pmt_counter[i] = new->pmt_counter[i];
 3879		else
 3880			old->pmt_counter[i] = new->pmt_counter[i] - old->pmt_counter[i];
 3881	}
 3882
 3883	return 0;
 3884}
 3885
 3886int delta_cpu(struct thread_data *t, struct core_data *c, struct pkg_data *p, struct thread_data *t2, struct core_data *c2, struct pkg_data *p2)
 3887{
 3888	int retval = 0;
 3889
 3890	/* calculate core delta only for 1st thread in core */
 3891	if (is_cpu_first_thread_in_core(t, c))
 3892		delta_core(c, c2);
 3893
 3894	/* always calculate thread delta */
 3895	retval = delta_thread(t, t2, c2);	/* c2 is core delta */
 3896
 3897	/* calculate package delta only for 1st core in package */
 3898	if (is_cpu_first_core_in_package(t, p))
 3899		retval |= delta_package(p, p2);
 3900
 3901	return retval;
 3902}
 3903
 3904void delta_platform(struct platform_counters *new, struct platform_counters *old)
 3905{
 3906	old->energy_psys.raw_value = new->energy_psys.raw_value - old->energy_psys.raw_value;
 3907}
 3908
 3909void rapl_counter_clear(struct rapl_counter *c)
 3910{
 3911	c->raw_value = 0;
 3912	c->scale = 0.0;
 3913	c->unit = RAPL_UNIT_INVALID;
 3914}
 3915
 3916void clear_counters(PER_THREAD_PARAMS)
 3917{
 3918	int i;
 3919	struct msr_counter *mp;
 3920
 3921	t->tv_begin.tv_sec = 0;
 3922	t->tv_begin.tv_usec = 0;
 3923	t->tv_end.tv_sec = 0;
 3924	t->tv_end.tv_usec = 0;
 3925	t->tv_delta.tv_sec = 0;
 3926	t->tv_delta.tv_usec = 0;
 3927
 3928	t->tsc = 0;
 3929	t->aperf = 0;
 3930	t->mperf = 0;
 3931	t->c1 = 0;
 3932
 3933	t->instr_count = 0;
 3934
 3935	t->irq_count = 0;
 3936	t->nmi_count = 0;
 3937	t->smi_count = 0;
 3938
 3939	t->llc.references = 0;
 3940	t->llc.misses = 0;
 3941
 3942	c->c3 = 0;
 3943	c->c6 = 0;
 3944	c->c7 = 0;
 3945	c->mc6_us = 0;
 3946	c->core_temp_c = 0;
 3947	rapl_counter_clear(&c->core_energy);
 3948	c->core_throt_cnt = 0;
 3949
 3950	t->llc.references = 0;
 3951	t->llc.misses = 0;
 3952
 3953	p->pkg_wtd_core_c0 = 0;
 3954	p->pkg_any_core_c0 = 0;
 3955	p->pkg_any_gfxe_c0 = 0;
 3956	p->pkg_both_core_gfxe_c0 = 0;
 3957
 3958	p->pc2 = 0;
 3959	if (DO_BIC(BIC_Pkgpc3))
 3960		p->pc3 = 0;
 3961	if (DO_BIC(BIC_Pkgpc6))
 3962		p->pc6 = 0;
 3963	if (DO_BIC(BIC_Pkgpc7))
 3964		p->pc7 = 0;
 3965	p->pc8 = 0;
 3966	p->pc9 = 0;
 3967	p->pc10 = 0;
 3968	p->die_c6 = 0;
 3969	p->cpu_lpi = 0;
 3970	p->sys_lpi = 0;
 3971
 3972	rapl_counter_clear(&p->energy_pkg);
 3973	rapl_counter_clear(&p->energy_dram);
 3974	rapl_counter_clear(&p->energy_cores);
 3975	rapl_counter_clear(&p->energy_gfx);
 3976	rapl_counter_clear(&p->rapl_pkg_perf_status);
 3977	rapl_counter_clear(&p->rapl_dram_perf_status);
 3978	p->pkg_temp_c = 0;
 3979
 3980	p->gfx_rc6_ms = 0;
 3981	p->uncore_mhz = 0;
 3982	p->gfx_mhz = 0;
 3983	p->gfx_act_mhz = 0;
 3984	p->sam_mc6_ms = 0;
 3985	p->sam_mhz = 0;
 3986	p->sam_act_mhz = 0;
 3987	for (i = 0, mp = sys.tp; mp; i++, mp = mp->next)
 3988		t->counter[i] = 0;
 3989
 3990	for (i = 0, mp = sys.cp; mp; i++, mp = mp->next)
 3991		c->counter[i] = 0;
 3992
 3993	for (i = 0, mp = sys.pp; mp; i++, mp = mp->next)
 3994		p->counter[i] = 0;
 3995
 3996	memset(&t->perf_counter[0], 0, sizeof(t->perf_counter));
 3997	memset(&c->perf_counter[0], 0, sizeof(c->perf_counter));
 3998	memset(&p->perf_counter[0], 0, sizeof(p->perf_counter));
 3999
 4000	memset(&t->pmt_counter[0], 0, ARRAY_SIZE(t->pmt_counter));
 4001	memset(&c->pmt_counter[0], 0, ARRAY_SIZE(c->pmt_counter));
 4002	memset(&p->pmt_counter[0], 0, ARRAY_SIZE(p->pmt_counter));
 4003}
 4004
 4005void rapl_counter_accumulate(struct rapl_counter *dst, const struct rapl_counter *src)
 4006{
 4007	/* Copy unit and scale from src if dst is not initialized */
 4008	if (dst->unit == RAPL_UNIT_INVALID) {
 4009		dst->unit = src->unit;
 4010		dst->scale = src->scale;
 4011	}
 4012
 4013	assert(dst->unit == src->unit);
 4014	assert(dst->scale == src->scale);
 4015
 4016	dst->raw_value += src->raw_value;
 4017}
 4018
 4019int sum_counters(PER_THREAD_PARAMS)
 4020{
 4021	int i;
 4022	struct msr_counter *mp;
 4023	struct perf_counter_info *pp;
 4024	struct pmt_counter *ppmt;
 4025
 4026	/* copy un-changing apic_id's */
 4027	if (DO_BIC(BIC_APIC))
 4028		average.threads.apic_id = t->apic_id;
 4029	if (DO_BIC(BIC_X2APIC))
 4030		average.threads.x2apic_id = t->x2apic_id;
 4031
 4032	/* remember first tv_begin */
 4033	if (average.threads.tv_begin.tv_sec == 0)
 4034		average.threads.tv_begin = procsysfs_tv_begin;
 4035
 4036	/* remember last tv_end */
 4037	average.threads.tv_end = t->tv_end;
 4038
 4039	average.threads.tsc += t->tsc;
 4040	average.threads.aperf += t->aperf;
 4041	average.threads.mperf += t->mperf;
 4042	average.threads.c1 += t->c1;
 4043
 4044	average.threads.instr_count += t->instr_count;
 4045
 4046	average.threads.irq_count += t->irq_count;
 4047	average.threads.nmi_count += t->nmi_count;
 4048	average.threads.smi_count += t->smi_count;
 4049
 4050	average.threads.llc.references += t->llc.references;
 4051	average.threads.llc.misses += t->llc.misses;
 4052
 4053	for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
 4054		if (mp->format == FORMAT_RAW)
 4055			continue;
 4056		average.threads.counter[i] += t->counter[i];
 4057	}
 4058
 4059	for (i = 0, pp = sys.perf_tp; pp; i++, pp = pp->next) {
 4060		if (pp->format == FORMAT_RAW)
 4061			continue;
 4062		average.threads.perf_counter[i] += t->perf_counter[i];
 4063	}
 4064
 4065	for (i = 0, ppmt = sys.pmt_tp; ppmt; i++, ppmt = ppmt->next) {
 4066		average.threads.pmt_counter[i] += t->pmt_counter[i];
 4067	}
 4068
 4069	/* sum per-core values only for 1st thread in core */
 4070	if (!is_cpu_first_thread_in_core(t, c))
 4071		return 0;
 4072
 4073	average.cores.c3 += c->c3;
 4074	average.cores.c6 += c->c6;
 4075	average.cores.c7 += c->c7;
 4076	average.cores.mc6_us += c->mc6_us;
 4077
 4078	average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c);
 4079	average.cores.core_throt_cnt = MAX(average.cores.core_throt_cnt, c->core_throt_cnt);
 4080
 4081	rapl_counter_accumulate(&average.cores.core_energy, &c->core_energy);
 4082
 4083	for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
 4084		if (mp->format == FORMAT_RAW)
 4085			continue;
 4086		average.cores.counter[i] += c->counter[i];
 4087	}
 4088
 4089	for (i = 0, pp = sys.perf_cp; pp; i++, pp = pp->next) {
 4090		if (pp->format == FORMAT_RAW)
 4091			continue;
 4092		average.cores.perf_counter[i] += c->perf_counter[i];
 4093	}
 4094
 4095	for (i = 0, ppmt = sys.pmt_cp; ppmt; i++, ppmt = ppmt->next) {
 4096		average.cores.pmt_counter[i] += c->pmt_counter[i];
 4097	}
 4098
 4099	/* sum per-pkg values only for 1st core in pkg */
 4100	if (!is_cpu_first_core_in_package(t, p))
 4101		return 0;
 4102
 4103	if (DO_BIC(BIC_Totl_c0))
 4104		average.packages.pkg_wtd_core_c0 += p->pkg_wtd_core_c0;
 4105	if (DO_BIC(BIC_Any_c0))
 4106		average.packages.pkg_any_core_c0 += p->pkg_any_core_c0;
 4107	if (DO_BIC(BIC_GFX_c0))
 4108		average.packages.pkg_any_gfxe_c0 += p->pkg_any_gfxe_c0;
 4109	if (DO_BIC(BIC_CPUGFX))
 4110		average.packages.pkg_both_core_gfxe_c0 += p->pkg_both_core_gfxe_c0;
 4111
 4112	average.packages.pc2 += p->pc2;
 4113	if (DO_BIC(BIC_Pkgpc3))
 4114		average.packages.pc3 += p->pc3;
 4115	if (DO_BIC(BIC_Pkgpc6))
 4116		average.packages.pc6 += p->pc6;
 4117	if (DO_BIC(BIC_Pkgpc7))
 4118		average.packages.pc7 += p->pc7;
 4119	average.packages.pc8 += p->pc8;
 4120	average.packages.pc9 += p->pc9;
 4121	average.packages.pc10 += p->pc10;
 4122	average.packages.die_c6 += p->die_c6;
 4123
 4124	average.packages.cpu_lpi = p->cpu_lpi;
 4125	average.packages.sys_lpi = p->sys_lpi;
 4126
 4127	rapl_counter_accumulate(&average.packages.energy_pkg, &p->energy_pkg);
 4128	rapl_counter_accumulate(&average.packages.energy_dram, &p->energy_dram);
 4129	rapl_counter_accumulate(&average.packages.energy_cores, &p->energy_cores);
 4130	rapl_counter_accumulate(&average.packages.energy_gfx, &p->energy_gfx);
 4131
 4132	average.packages.gfx_rc6_ms = p->gfx_rc6_ms;
 4133	average.packages.uncore_mhz = p->uncore_mhz;
 4134	average.packages.gfx_mhz = p->gfx_mhz;
 4135	average.packages.gfx_act_mhz = p->gfx_act_mhz;
 4136	average.packages.sam_mc6_ms = p->sam_mc6_ms;
 4137	average.packages.sam_mhz = p->sam_mhz;
 4138	average.packages.sam_act_mhz = p->sam_act_mhz;
 4139
 4140	average.packages.pkg_temp_c = MAX(average.packages.pkg_temp_c, p->pkg_temp_c);
 4141
 4142	rapl_counter_accumulate(&average.packages.rapl_pkg_perf_status, &p->rapl_pkg_perf_status);
 4143	rapl_counter_accumulate(&average.packages.rapl_dram_perf_status, &p->rapl_dram_perf_status);
 4144
 4145	for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
 4146		if ((mp->format == FORMAT_RAW) && (topo.num_packages == 0))
 4147			average.packages.counter[i] = p->counter[i];
 4148		else
 4149			average.packages.counter[i] += p->counter[i];
 4150	}
 4151
 4152	for (i = 0, pp = sys.perf_pp; pp; i++, pp = pp->next) {
 4153		if ((pp->format == FORMAT_RAW) && (topo.num_packages == 0))
 4154			average.packages.perf_counter[i] = p->perf_counter[i];
 4155		else
 4156			average.packages.perf_counter[i] += p->perf_counter[i];
 4157	}
 4158
 4159	for (i = 0, ppmt = sys.pmt_pp; ppmt; i++, ppmt = ppmt->next) {
 4160		average.packages.pmt_counter[i] += p->pmt_counter[i];
 4161	}
 4162
 4163	return 0;
 4164}
 4165
 4166/*
 4167 * sum the counters for all cpus in the system
 4168 * compute the weighted average
 4169 */
 4170void compute_average(PER_THREAD_PARAMS)
 4171{
 4172	int i;
 4173	struct msr_counter *mp;
 4174	struct perf_counter_info *pp;
 4175	struct pmt_counter *ppmt;
 4176
 4177	clear_counters(&average.threads, &average.cores, &average.packages);
 4178
 4179	for_all_cpus(sum_counters, t, c, p);
 4180
 4181	/* Use the global time delta for the average. */
 4182	average.threads.tv_delta = tv_delta;
 4183
 4184	average.threads.tsc /= topo.allowed_cpus;
 4185	average.threads.aperf /= topo.allowed_cpus;
 4186	average.threads.mperf /= topo.allowed_cpus;
 4187	average.threads.instr_count /= topo.allowed_cpus;
 4188	average.threads.c1 /= topo.allowed_cpus;
 4189
 4190	if (average.threads.irq_count > 9999999)
 4191		sums_need_wide_columns = 1;
 4192	if (average.threads.nmi_count > 9999999)
 4193		sums_need_wide_columns = 1;
 4194
 4195	average.cores.c3 /= topo.allowed_cores;
 4196	average.cores.c6 /= topo.allowed_cores;
 4197	average.cores.c7 /= topo.allowed_cores;
 4198	average.cores.mc6_us /= topo.allowed_cores;
 4199
 4200	if (DO_BIC(BIC_Totl_c0))
 4201		average.packages.pkg_wtd_core_c0 /= topo.allowed_packages;
 4202	if (DO_BIC(BIC_Any_c0))
 4203		average.packages.pkg_any_core_c0 /= topo.allowed_packages;
 4204	if (DO_BIC(BIC_GFX_c0))
 4205		average.packages.pkg_any_gfxe_c0 /= topo.allowed_packages;
 4206	if (DO_BIC(BIC_CPUGFX))
 4207		average.packages.pkg_both_core_gfxe_c0 /= topo.allowed_packages;
 4208
 4209	average.packages.pc2 /= topo.allowed_packages;
 4210	if (DO_BIC(BIC_Pkgpc3))
 4211		average.packages.pc3 /= topo.allowed_packages;
 4212	if (DO_BIC(BIC_Pkgpc6))
 4213		average.packages.pc6 /= topo.allowed_packages;
 4214	if (DO_BIC(BIC_Pkgpc7))
 4215		average.packages.pc7 /= topo.allowed_packages;
 4216
 4217	average.packages.pc8 /= topo.allowed_packages;
 4218	average.packages.pc9 /= topo.allowed_packages;
 4219	average.packages.pc10 /= topo.allowed_packages;
 4220	average.packages.die_c6 /= topo.allowed_packages;
 4221
 4222	for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
 4223		if (mp->format == FORMAT_RAW)
 4224			continue;
 4225		if (mp->type == COUNTER_ITEMS) {
 4226			if (average.threads.counter[i] > 9999999)
 4227				sums_need_wide_columns = 1;
 4228			continue;
 4229		}
 4230		average.threads.counter[i] /= topo.allowed_cpus;
 4231	}
 4232	for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
 4233		if (mp->format == FORMAT_RAW)
 4234			continue;
 4235		if (mp->type == COUNTER_ITEMS) {
 4236			if (average.cores.counter[i] > 9999999)
 4237				sums_need_wide_columns = 1;
 4238		}
 4239		average.cores.counter[i] /= topo.allowed_cores;
 4240	}
 4241	for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
 4242		if (mp->format == FORMAT_RAW)
 4243			continue;
 4244		if (mp->type == COUNTER_ITEMS) {
 4245			if (average.packages.counter[i] > 9999999)
 4246				sums_need_wide_columns = 1;
 4247		}
 4248		average.packages.counter[i] /= topo.allowed_packages;
 4249	}
 4250
 4251	for (i = 0, pp = sys.perf_tp; pp; i++, pp = pp->next) {
 4252		if (pp->format == FORMAT_RAW)
 4253			continue;
 4254		if (pp->type == COUNTER_ITEMS) {
 4255			if (average.threads.perf_counter[i] > 9999999)
 4256				sums_need_wide_columns = 1;
 4257			continue;
 4258		}
 4259		average.threads.perf_counter[i] /= topo.allowed_cpus;
 4260	}
 4261	for (i = 0, pp = sys.perf_cp; pp; i++, pp = pp->next) {
 4262		if (pp->format == FORMAT_RAW)
 4263			continue;
 4264		if (pp->type == COUNTER_ITEMS) {
 4265			if (average.cores.perf_counter[i] > 9999999)
 4266				sums_need_wide_columns = 1;
 4267		}
 4268		average.cores.perf_counter[i] /= topo.allowed_cores;
 4269	}
 4270	for (i = 0, pp = sys.perf_pp; pp; i++, pp = pp->next) {
 4271		if (pp->format == FORMAT_RAW)
 4272			continue;
 4273		if (pp->type == COUNTER_ITEMS) {
 4274			if (average.packages.perf_counter[i] > 9999999)
 4275				sums_need_wide_columns = 1;
 4276		}
 4277		average.packages.perf_counter[i] /= topo.allowed_packages;
 4278	}
 4279
 4280	for (i = 0, ppmt = sys.pmt_tp; ppmt; i++, ppmt = ppmt->next) {
 4281		average.threads.pmt_counter[i] /= topo.allowed_cpus;
 4282	}
 4283	for (i = 0, ppmt = sys.pmt_cp; ppmt; i++, ppmt = ppmt->next) {
 4284		average.cores.pmt_counter[i] /= topo.allowed_cores;
 4285	}
 4286	for (i = 0, ppmt = sys.pmt_pp; ppmt; i++, ppmt = ppmt->next) {
 4287		average.packages.pmt_counter[i] /= topo.allowed_packages;
 4288	}
 4289}
 4290
 4291static unsigned long long rdtsc(void)
 4292{
 4293	unsigned int low, high;
 4294
 4295	asm volatile ("rdtsc":"=a" (low), "=d"(high));
 4296
 4297	return low | ((unsigned long long)high) << 32;
 4298}
 4299
 4300/*
 4301 * Open a file, and exit on failure
 4302 */
 4303FILE *fopen_or_die(const char *path, const char *mode)
 4304{
 4305	FILE *filep = fopen(path, mode);
 4306
 4307	if (!filep)
 4308		err(1, "%s: open failed", path);
 4309	return filep;
 4310}
 4311
 4312/*
 4313 * snapshot_sysfs_counter()
 4314 *
 4315 * return snapshot of given counter
 4316 */
 4317unsigned long long snapshot_sysfs_counter(char *path)
 4318{
 4319	FILE *fp;
 4320	int retval;
 4321	unsigned long long counter;
 4322
 4323	fp = fopen_or_die(path, "r");
 4324
 4325	retval = fscanf(fp, "%lld", &counter);
 4326	if (retval != 1)
 4327		err(1, "snapshot_sysfs_counter(%s)", path);
 4328
 4329	fclose(fp);
 4330
 4331	return counter;
 4332}
 4333
 4334int get_mp(int cpu, struct msr_counter *mp, unsigned long long *counterp, char *counter_path)
 4335{
 4336	if (mp->msr_num != 0) {
 4337		assert(!no_msr);
 4338		if (get_msr(cpu, mp->msr_num, counterp))
 4339			return -1;
 4340	} else {
 4341		char path[128 + PATH_BYTES];
 4342
 4343		if (mp->flags & SYSFS_PERCPU) {
 4344			sprintf(path, "/sys/devices/system/cpu/cpu%d/%s", cpu, mp->sp->path);
 4345
 4346			*counterp = snapshot_sysfs_counter(path);
 4347		} else {
 4348			*counterp = snapshot_sysfs_counter(counter_path);
 4349		}
 4350	}
 4351
 4352	return 0;
 4353}
 4354
 4355unsigned long long get_legacy_uncore_mhz(int package)
 4356{
 4357	char path[128];
 4358	int die;
 4359	static int warn_once;
 4360
 4361	/*
 4362	 * for this package, use the first die_id that exists
 4363	 */
 4364	for (die = 0; die <= topo.max_die_id; ++die) {
 4365
 4366		sprintf(path, "/sys/devices/system/cpu/intel_uncore_frequency/package_%02d_die_%02d/current_freq_khz", package, die);
 4367
 4368		if (access(path, R_OK) == 0)
 4369			return (snapshot_sysfs_counter(path) / 1000);
 4370	}
 4371	if (!warn_once) {
 4372		warnx("BUG: %s: No %s", __func__, path);
 4373		warn_once = 1;
 4374	}
 4375
 4376	return 0;
 4377}
 4378
 4379int get_epb(int cpu)
 4380{
 4381	char path[128 + PATH_BYTES];
 4382	unsigned long long msr;
 4383	int ret, epb = -1;
 4384	FILE *fp;
 4385
 4386	sprintf(path, "/sys/devices/system/cpu/cpu%d/power/energy_perf_bias", cpu);
 4387
 4388	fp = fopen(path, "r");
 4389	if (!fp)
 4390		goto msr_fallback;
 4391
 4392	ret = fscanf(fp, "%d", &epb);
 4393	if (ret != 1)
 4394		err(1, "%s(%s)", __func__, path);
 4395
 4396	fclose(fp);
 4397
 4398	return epb;
 4399
 4400msr_fallback:
 4401	if (no_msr)
 4402		return -1;
 4403
 4404	get_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &msr);
 4405
 4406	return msr & 0xf;
 4407}
 4408
 4409void get_apic_id(struct thread_data *t)
 4410{
 4411	unsigned int eax, ebx, ecx, edx;
 4412
 4413	if (DO_BIC(BIC_APIC)) {
 4414		eax = ebx = ecx = edx = 0;
 4415		__cpuid(1, eax, ebx, ecx, edx);
 4416
 4417		t->apic_id = (ebx >> 24) & 0xff;
 4418	}
 4419
 4420	if (!DO_BIC(BIC_X2APIC))
 4421		return;
 4422
 4423	if (authentic_amd || hygon_genuine) {
 4424		unsigned int topology_extensions;
 4425
 4426		if (max_extended_level < 0x8000001e)
 4427			return;
 4428
 4429		eax = ebx = ecx = edx = 0;
 4430		__cpuid(0x80000001, eax, ebx, ecx, edx);
 4431		topology_extensions = ecx & (1 << 22);
 4432
 4433		if (topology_extensions == 0)
 4434			return;
 4435
 4436		eax = ebx = ecx = edx = 0;
 4437		__cpuid(0x8000001e, eax, ebx, ecx, edx);
 4438
 4439		t->x2apic_id = eax;
 4440		return;
 4441	}
 4442
 4443	if (!genuine_intel)
 4444		return;
 4445
 4446	if (max_level < 0xb)
 4447		return;
 4448
 4449	ecx = 0;
 4450	__cpuid(0xb, eax, ebx, ecx, edx);
 4451	t->x2apic_id = edx;
 4452
 4453	if (debug && (t->apic_id != (t->x2apic_id & 0xff)))
 4454		fprintf(outf, "cpu%d: BIOS BUG: apic 0x%x x2apic 0x%x\n", t->cpu_id, t->apic_id, t->x2apic_id);
 4455}
 4456
 4457int get_core_throt_cnt(int cpu, unsigned long long *cnt)
 4458{
 4459	char path[128 + PATH_BYTES];
 4460	unsigned long long tmp;
 4461	FILE *fp;
 4462	int ret;
 4463
 4464	sprintf(path, "/sys/devices/system/cpu/cpu%d/thermal_throttle/core_throttle_count", cpu);
 4465	fp = fopen(path, "r");
 4466	if (!fp)
 4467		return -1;
 4468	ret = fscanf(fp, "%lld", &tmp);
 4469	fclose(fp);
 4470	if (ret != 1)
 4471		return -1;
 4472	*cnt = tmp;
 4473
 4474	return 0;
 4475}
 4476
 4477static int read_perf_counter_info(const char *const path, const char *const parse_format, void *value_ptr)
 4478{
 4479	int fdmt;
 4480	int bytes_read;
 4481	char buf[64];
 4482	int ret = -1;
 4483
 4484	fdmt = open(path, O_RDONLY, 0);
 4485	if (fdmt == -1) {
 4486		if (debug)
 4487			fprintf(stderr, "Failed to parse perf counter info %s\n", path);
 4488		ret = -1;
 4489		goto cleanup_and_exit;
 4490	}
 4491
 4492	bytes_read = read(fdmt, buf, sizeof(buf) - 1);
 4493	if (bytes_read <= 0 || bytes_read >= (int)sizeof(buf)) {
 4494		if (debug)
 4495			fprintf(stderr, "Failed to parse perf counter info %s\n", path);
 4496		ret = -1;
 4497		goto cleanup_and_exit;
 4498	}
 4499
 4500	buf[bytes_read] = '\0';
 4501
 4502	if (sscanf(buf, parse_format, value_ptr) != 1) {
 4503		if (debug)
 4504			fprintf(stderr, "Failed to parse perf counter info %s\n", path);
 4505		ret = -1;
 4506		goto cleanup_and_exit;
 4507	}
 4508
 4509	ret = 0;
 4510
 4511cleanup_and_exit:
 4512	close(fdmt);
 4513	return ret;
 4514}
 4515
 4516static unsigned int read_perf_counter_info_n(const char *const path, const char *const parse_format)
 4517{
 4518	unsigned int v;
 4519	int status;
 4520
 4521	status = read_perf_counter_info(path, parse_format, &v);
 4522	if (status)
 4523		v = -1;
 4524
 4525	return v;
 4526}
 4527
 4528static unsigned int read_perf_type(const char *subsys)
 4529{
 4530	const char *const path_format = "/sys/bus/event_source/devices/%s/type";
 4531	const char *const format = "%u";
 4532	char path[128];
 4533
 4534	snprintf(path, sizeof(path), path_format, subsys);
 4535
 4536	return read_perf_counter_info_n(path, format);
 4537}
 4538
 4539static unsigned int read_perf_config(const char *subsys, const char *event_name)
 4540{
 4541	const char *const path_format = "/sys/bus/event_source/devices/%s/events/%s";
 4542	FILE *fconfig = NULL;
 4543	char path[128];
 4544	char config_str[64];
 4545	unsigned int config;
 4546	unsigned int umask;
 4547	bool has_config = false;
 4548	bool has_umask = false;
 4549	unsigned int ret = -1;
 4550
 4551	snprintf(path, sizeof(path), path_format, subsys, event_name);
 4552
 4553	fconfig = fopen(path, "r");
 4554	if (!fconfig)
 4555		return -1;
 4556
 4557	if (fgets(config_str, ARRAY_SIZE(config_str), fconfig) != config_str)
 4558		goto cleanup_and_exit;
 4559
 4560	for (char *pconfig_str = &config_str[0]; pconfig_str;) {
 4561		if (sscanf(pconfig_str, "event=%x", &config) == 1) {
 4562			has_config = true;
 4563			goto next;
 4564		}
 4565
 4566		if (sscanf(pconfig_str, "umask=%x", &umask) == 1) {
 4567			has_umask = true;
 4568			goto next;
 4569		}
 4570
 4571next:
 4572		pconfig_str = strchr(pconfig_str, ',');
 4573		if (pconfig_str) {
 4574			*pconfig_str = '\0';
 4575			++pconfig_str;
 4576		}
 4577	}
 4578
 4579	if (!has_umask)
 4580		umask = 0;
 4581
 4582	if (has_config)
 4583		ret = (umask << 8) | config;
 4584
 4585cleanup_and_exit:
 4586	fclose(fconfig);
 4587	return ret;
 4588}
 4589
 4590static unsigned int read_perf_rapl_unit(const char *subsys, const char *event_name)
 4591{
 4592	const char *const path_format = "/sys/bus/event_source/devices/%s/events/%s.unit";
 4593	const char *const format = "%s";
 4594	char path[128];
 4595	char unit_buffer[16];
 4596
 4597	snprintf(path, sizeof(path), path_format, subsys, event_name);
 4598
 4599	read_perf_counter_info(path, format, &unit_buffer);
 4600	if (strcmp("Joules", unit_buffer) == 0)
 4601		return RAPL_UNIT_JOULES;
 4602
 4603	return RAPL_UNIT_INVALID;
 4604}
 4605
 4606static double read_perf_scale(const char *subsys, const char *event_name)
 4607{
 4608	const char *const path_format = "/sys/bus/event_source/devices/%s/events/%s.scale";
 4609	const char *const format = "%lf";
 4610	char path[128];
 4611	double scale;
 4612
 4613	snprintf(path, sizeof(path), path_format, subsys, event_name);
 4614
 4615	if (read_perf_counter_info(path, format, &scale))
 4616		return 0.0;
 4617
 4618	return scale;
 4619}
 4620
 4621size_t rapl_counter_info_count_perf(const struct rapl_counter_info_t *rci)
 4622{
 4623	size_t ret = 0;
 4624
 4625	for (int i = 0; i < NUM_RAPL_COUNTERS; ++i)
 4626		if (rci->source[i] == COUNTER_SOURCE_PERF)
 4627			++ret;
 4628
 4629	return ret;
 4630}
 4631
 4632static size_t cstate_counter_info_count_perf(const struct cstate_counter_info_t *cci)
 4633{
 4634	size_t ret = 0;
 4635
 4636	for (int i = 0; i < NUM_CSTATE_COUNTERS; ++i)
 4637		if (cci->source[i] == COUNTER_SOURCE_PERF)
 4638			++ret;
 4639
 4640	return ret;
 4641}
 4642
 4643void write_rapl_counter(struct rapl_counter *rc, struct rapl_counter_info_t *rci, unsigned int idx)
 4644{
 4645	if (rci->source[idx] == COUNTER_SOURCE_NONE)
 4646		return;
 4647
 4648	rc->raw_value = rci->data[idx];
 4649	rc->unit = rci->unit[idx];
 4650	rc->scale = rci->scale[idx];
 4651}
 4652
 4653int get_rapl_counters(int cpu, unsigned int domain, struct core_data *c, struct pkg_data *p)
 4654{
 4655	struct platform_counters *pplat_cnt = p == package_odd ? &platform_counters_odd : &platform_counters_even;
 4656	unsigned long long perf_data[NUM_RAPL_COUNTERS + 1];
 4657	struct rapl_counter_info_t *rci;
 4658
 4659	if (debug >= 2)
 4660		fprintf(stderr, "%s: cpu%d domain%d\n", __func__, cpu, domain);
 4661
 4662	assert(rapl_counter_info_perdomain);
 4663	assert(domain < rapl_counter_info_perdomain_size);
 4664
 4665	rci = &rapl_counter_info_perdomain[domain];
 4666
 4667	/*
 4668	 * If we have any perf counters to read, read them all now, in bulk
 4669	 */
 4670	if (rci->fd_perf != -1) {
 4671		size_t num_perf_counters = rapl_counter_info_count_perf(rci);
 4672		const ssize_t expected_read_size = (num_perf_counters + 1) * sizeof(unsigned long long);
 4673		const ssize_t actual_read_size = read(rci->fd_perf, &perf_data[0], sizeof(perf_data));
 4674
 4675		if (actual_read_size != expected_read_size)
 4676			err(-1, "%s: failed to read perf_data (%zu %zu)", __func__, expected_read_size, actual_read_size);
 4677	}
 4678
 4679	for (unsigned int i = 0, pi = 1; i < NUM_RAPL_COUNTERS; ++i) {
 4680		switch (rci->source[i]) {
 4681		case COUNTER_SOURCE_NONE:
 4682			rci->data[i] = 0;
 4683			break;
 4684
 4685		case COUNTER_SOURCE_PERF:
 4686			assert(pi < ARRAY_SIZE(perf_data));
 4687			assert(rci->fd_perf != -1);
 4688
 4689			if (debug >= 2)
 4690				fprintf(stderr, "Reading rapl counter via perf at %u (%llu %e %lf)\n",
 4691					i, perf_data[pi], rci->scale[i], perf_data[pi] * rci->scale[i]);
 4692
 4693			rci->data[i] = perf_data[pi];
 4694
 4695			++pi;
 4696			break;
 4697
 4698		case COUNTER_SOURCE_MSR:
 4699			if (debug >= 2)
 4700				fprintf(stderr, "Reading rapl counter via msr at %u\n", i);
 4701
 4702			assert(!no_msr);
 4703			if (rci->flags[i] & RAPL_COUNTER_FLAG_USE_MSR_SUM) {
 4704				if (get_msr_sum(cpu, rci->msr[i], &rci->data[i]))
 4705					return -13 - i;
 4706			} else {
 4707				if (get_msr(cpu, rci->msr[i], &rci->data[i]))
 4708					return -13 - i;
 4709			}
 4710
 4711			rci->data[i] &= rci->msr_mask[i];
 4712			if (rci->msr_shift[i] >= 0)
 4713				rci->data[i] >>= abs(rci->msr_shift[i]);
 4714			else
 4715				rci->data[i] <<= abs(rci->msr_shift[i]);
 4716
 4717			break;
 4718		}
 4719	}
 4720
 4721	BUILD_BUG_ON(NUM_RAPL_COUNTERS != 8);
 4722	write_rapl_counter(&p->energy_pkg, rci, RAPL_RCI_INDEX_ENERGY_PKG);
 4723	write_rapl_counter(&p->energy_cores, rci, RAPL_RCI_INDEX_ENERGY_CORES);
 4724	write_rapl_counter(&p->energy_dram, rci, RAPL_RCI_INDEX_DRAM);
 4725	write_rapl_counter(&p->energy_gfx, rci, RAPL_RCI_INDEX_GFX);
 4726	write_rapl_counter(&p->rapl_pkg_perf_status, rci, RAPL_RCI_INDEX_PKG_PERF_STATUS);
 4727	write_rapl_counter(&p->rapl_dram_perf_status, rci, RAPL_RCI_INDEX_DRAM_PERF_STATUS);
 4728	write_rapl_counter(&c->core_energy, rci, RAPL_RCI_INDEX_CORE_ENERGY);
 4729	write_rapl_counter(&pplat_cnt->energy_psys, rci, RAPL_RCI_INDEX_ENERGY_PLATFORM);
 4730
 4731	return 0;
 4732}
 4733
 4734char *find_sysfs_path_by_id(struct sysfs_path *sp, int id)
 4735{
 4736	while (sp) {
 4737		if (sp->id == id)
 4738			return (sp->path);
 4739		sp = sp->next;
 4740	}
 4741	if (debug)
 4742		warnx("%s: id%d not found", __func__, id);
 4743	return NULL;
 4744}
 4745
 4746int get_cstate_counters(unsigned int cpu, PER_THREAD_PARAMS)
 4747{
 4748	/*
 4749	 * Overcommit memory a little bit here,
 4750	 * but skip calculating exact sizes for the buffers.
 4751	 */
 4752	unsigned long long perf_data[NUM_CSTATE_COUNTERS];
 4753	unsigned long long perf_data_core[NUM_CSTATE_COUNTERS + 1];
 4754	unsigned long long perf_data_pkg[NUM_CSTATE_COUNTERS + 1];
 4755
 4756	struct cstate_counter_info_t *cci;
 4757
 4758	if (debug >= 2)
 4759		fprintf(stderr, "%s: cpu%d\n", __func__, cpu);
 4760
 4761	assert(ccstate_counter_info);
 4762	assert(cpu <= ccstate_counter_info_size);
 4763
 4764	ZERO_ARRAY(perf_data);
 4765	ZERO_ARRAY(perf_data_core);
 4766	ZERO_ARRAY(perf_data_pkg);
 4767
 4768	cci = &ccstate_counter_info[cpu];
 4769
 4770	/*
 4771	 * If we have any perf counters to read, read them all now, in bulk
 4772	 */
 4773	const size_t num_perf_counters = cstate_counter_info_count_perf(cci);
 4774	ssize_t expected_read_size = num_perf_counters * sizeof(unsigned long long);
 4775	ssize_t actual_read_size_core = 0, actual_read_size_pkg = 0;
 4776
 4777	if (cci->fd_perf_core != -1) {
 4778		/* Each descriptor read begins with number of counters read. */
 4779		expected_read_size += sizeof(unsigned long long);
 4780
 4781		actual_read_size_core = read(cci->fd_perf_core, &perf_data_core[0], sizeof(perf_data_core));
 4782
 4783		if (actual_read_size_core <= 0)
 4784			err(-1, "%s: read perf %s: %ld", __func__, "core", actual_read_size_core);
 4785	}
 4786
 4787	if (cci->fd_perf_pkg != -1) {
 4788		/* Each descriptor read begins with number of counters read. */
 4789		expected_read_size += sizeof(unsigned long long);
 4790
 4791		actual_read_size_pkg = read(cci->fd_perf_pkg, &perf_data_pkg[0], sizeof(perf_data_pkg));
 4792
 4793		if (actual_read_size_pkg <= 0)
 4794			err(-1, "%s: read perf %s: %ld", __func__, "pkg", actual_read_size_pkg);
 4795	}
 4796
 4797	const ssize_t actual_read_size_total = actual_read_size_core + actual_read_size_pkg;
 4798
 4799	if (actual_read_size_total != expected_read_size)
 4800		err(-1, "%s: failed to read perf_data (%zu %zu)", __func__, expected_read_size, actual_read_size_total);
 4801
 4802	/*
 4803	 * Copy ccstate and pcstate data into unified buffer.
 4804	 *
 4805	 * Skip first element from core and pkg buffers.
 4806	 * Kernel puts there how many counters were read.
 4807	 */
 4808	const size_t num_core_counters = perf_data_core[0];
 4809	const size_t num_pkg_counters = perf_data_pkg[0];
 4810
 4811	assert(num_perf_counters == num_core_counters + num_pkg_counters);
 4812
 4813	/* Copy ccstate perf data */
 4814	memcpy(&perf_data[0], &perf_data_core[1], num_core_counters * sizeof(unsigned long long));
 4815
 4816	/* Copy pcstate perf data */
 4817	memcpy(&perf_data[num_core_counters], &perf_data_pkg[1], num_pkg_counters * sizeof(unsigned long long));
 4818
 4819	for (unsigned int i = 0, pi = 0; i < NUM_CSTATE_COUNTERS; ++i) {
 4820		switch (cci->source[i]) {
 4821		case COUNTER_SOURCE_NONE:
 4822			break;
 4823
 4824		case COUNTER_SOURCE_PERF:
 4825			assert(pi < ARRAY_SIZE(perf_data));
 4826			assert(cci->fd_perf_core != -1 || cci->fd_perf_pkg != -1);
 4827
 4828			if (debug >= 2)
 4829				fprintf(stderr, "cstate via %s %u: %llu\n", "perf", i, perf_data[pi]);
 4830
 4831			cci->data[i] = perf_data[pi];
 4832
 4833			++pi;
 4834			break;
 4835
 4836		case COUNTER_SOURCE_MSR:
 4837			assert(!no_msr);
 4838			if (get_msr(cpu, cci->msr[i], &cci->data[i]))
 4839				return -13 - i;
 4840
 4841			if (debug >= 2)
 4842				fprintf(stderr, "cstate via %s0x%llx %u: %llu\n", "msr", cci->msr[i], i, cci->data[i]);
 4843
 4844			break;
 4845		}
 4846	}
 4847
 4848	/*
 4849	 * Helper to write the data only if the source of
 4850	 * the counter for the current cpu is not none.
 4851	 *
 4852	 * Otherwise we would overwrite core data with 0 (default value),
 4853	 * when invoked for the thread sibling.
 4854	 */
 4855#define PERF_COUNTER_WRITE_DATA(out_counter, index) do {	\
 4856	if (cci->source[index] != COUNTER_SOURCE_NONE)		\
 4857		out_counter = cci->data[index];			\
 4858} while (0)
 4859
 4860	BUILD_BUG_ON(NUM_CSTATE_COUNTERS != 11);
 4861
 4862	PERF_COUNTER_WRITE_DATA(t->c1, CCSTATE_RCI_INDEX_C1_RESIDENCY);
 4863	PERF_COUNTER_WRITE_DATA(c->c3, CCSTATE_RCI_INDEX_C3_RESIDENCY);
 4864	PERF_COUNTER_WRITE_DATA(c->c6, CCSTATE_RCI_INDEX_C6_RESIDENCY);
 4865	PERF_COUNTER_WRITE_DATA(c->c7, CCSTATE_RCI_INDEX_C7_RESIDENCY);
 4866
 4867	PERF_COUNTER_WRITE_DATA(p->pc2, PCSTATE_RCI_INDEX_C2_RESIDENCY);
 4868	PERF_COUNTER_WRITE_DATA(p->pc3, PCSTATE_RCI_INDEX_C3_RESIDENCY);
 4869	PERF_COUNTER_WRITE_DATA(p->pc6, PCSTATE_RCI_INDEX_C6_RESIDENCY);
 4870	PERF_COUNTER_WRITE_DATA(p->pc7, PCSTATE_RCI_INDEX_C7_RESIDENCY);
 4871	PERF_COUNTER_WRITE_DATA(p->pc8, PCSTATE_RCI_INDEX_C8_RESIDENCY);
 4872	PERF_COUNTER_WRITE_DATA(p->pc9, PCSTATE_RCI_INDEX_C9_RESIDENCY);
 4873	PERF_COUNTER_WRITE_DATA(p->pc10, PCSTATE_RCI_INDEX_C10_RESIDENCY);
 4874
 4875#undef PERF_COUNTER_WRITE_DATA
 4876
 4877	return 0;
 4878}
 4879
 4880size_t msr_counter_info_count_perf(const struct msr_counter_info_t *mci)
 4881{
 4882	size_t ret = 0;
 4883
 4884	for (int i = 0; i < NUM_MSR_COUNTERS; ++i)
 4885		if (mci->source[i] == COUNTER_SOURCE_PERF)
 4886			++ret;
 4887
 4888	return ret;
 4889}
 4890
 4891int get_smi_aperf_mperf(unsigned int cpu, struct thread_data *t)
 4892{
 4893	unsigned long long perf_data[NUM_MSR_COUNTERS + 1];
 4894
 4895	struct msr_counter_info_t *mci;
 4896
 4897	if (debug >= 2)
 4898		fprintf(stderr, "%s: cpu%d\n", __func__, cpu);
 4899
 4900	assert(msr_counter_info);
 4901	assert(cpu <= msr_counter_info_size);
 4902
 4903	mci = &msr_counter_info[cpu];
 4904
 4905	ZERO_ARRAY(perf_data);
 4906	ZERO_ARRAY(mci->data);
 4907
 4908	if (mci->fd_perf != -1) {
 4909		const size_t num_perf_counters = msr_counter_info_count_perf(mci);
 4910		const ssize_t expected_read_size = (num_perf_counters + 1) * sizeof(unsigned long long);
 4911		const ssize_t actual_read_size = read(mci->fd_perf, &perf_data[0], sizeof(perf_data));
 4912
 4913		if (actual_read_size != expected_read_size)
 4914			err(-1, "%s: failed to read perf_data (%zu %zu)", __func__, expected_read_size, actual_read_size);
 4915	}
 4916
 4917	for (unsigned int i = 0, pi = 1; i < NUM_MSR_COUNTERS; ++i) {
 4918		switch (mci->source[i]) {
 4919		case COUNTER_SOURCE_NONE:
 4920			break;
 4921
 4922		case COUNTER_SOURCE_PERF:
 4923			assert(pi < ARRAY_SIZE(perf_data));
 4924			assert(mci->fd_perf != -1);
 4925
 4926			if (debug >= 2)
 4927				fprintf(stderr, "Reading msr counter via perf at %u: %llu\n", i, perf_data[pi]);
 4928
 4929			mci->data[i] = perf_data[pi];
 4930
 4931			++pi;
 4932			break;
 4933
 4934		case COUNTER_SOURCE_MSR:
 4935			assert(!no_msr);
 4936
 4937			if (get_msr(cpu, mci->msr[i], &mci->data[i]))
 4938				return -2 - i;
 4939
 4940			mci->data[i] &= mci->msr_mask[i];
 4941
 4942			if (debug >= 2)
 4943				fprintf(stderr, "Reading msr counter via msr at %u: %llu\n", i, mci->data[i]);
 4944
 4945			break;
 4946		}
 4947	}
 4948
 4949	BUILD_BUG_ON(NUM_MSR_COUNTERS != 3);
 4950	t->aperf = mci->data[MSR_RCI_INDEX_APERF];
 4951	t->mperf = mci->data[MSR_RCI_INDEX_MPERF];
 4952	t->smi_count = mci->data[MSR_RCI_INDEX_SMI];
 4953
 4954	return 0;
 4955}
 4956
 4957int perf_counter_info_read_values(struct perf_counter_info *pp, int cpu, unsigned long long *out, size_t out_size)
 4958{
 4959	unsigned int domain;
 4960	unsigned long long value;
 4961	int fd_counter;
 4962
 4963	for (size_t i = 0; pp; ++i, pp = pp->next) {
 4964		domain = cpu_to_domain(pp, cpu);
 4965		assert(domain < pp->num_domains);
 4966
 4967		fd_counter = pp->fd_perf_per_domain[domain];
 4968
 4969		if (fd_counter == -1)
 4970			continue;
 4971
 4972		if (read(fd_counter, &value, sizeof(value)) != sizeof(value))
 4973			return 1;
 4974
 4975		assert(i < out_size);
 4976		out[i] = value * pp->scale;
 4977	}
 4978
 4979	return 0;
 4980}
 4981
 4982unsigned long pmt_gen_value_mask(unsigned int lsb, unsigned int msb)
 4983{
 4984	unsigned long mask;
 4985
 4986	if (msb == 63)
 4987		mask = 0xffffffffffffffff;
 4988	else
 4989		mask = ((1 << (msb + 1)) - 1);
 4990
 4991	mask -= (1 << lsb) - 1;
 4992
 4993	return mask;
 4994}
 4995
 4996unsigned long pmt_read_counter(struct pmt_counter *ppmt, unsigned int domain_id)
 4997{
 4998	if (domain_id >= ppmt->num_domains)
 4999		return 0;
 5000
 5001	const unsigned long *pmmio = ppmt->domains[domain_id].pcounter;
 5002	const unsigned long value = pmmio ? *pmmio : 0;
 5003	const unsigned long value_mask = pmt_gen_value_mask(ppmt->lsb, ppmt->msb);
 5004	const unsigned long value_shift = ppmt->lsb;
 5005
 5006	return (value & value_mask) >> value_shift;
 5007}
 5008
 5009/* Rapl domain enumeration helpers */
 5010static inline int get_rapl_num_domains(void)
 5011{
 5012	int num_packages = topo.max_package_id + 1;
 5013	int num_cores_per_package;
 5014	int num_cores;
 5015
 5016	if (!platform->has_per_core_rapl)
 5017		return num_packages;
 5018
 5019	num_cores_per_package = topo.max_core_id + 1;
 5020	num_cores = num_cores_per_package * num_packages;
 5021
 5022	return num_cores;
 5023}
 5024
 5025static inline int get_rapl_domain_id(int cpu)
 5026{
 5027	int nr_cores_per_package = topo.max_core_id + 1;
 5028	int rapl_core_id;
 5029
 5030	if (!platform->has_per_core_rapl)
 5031		return cpus[cpu].physical_package_id;
 5032
 5033	/* Compute the system-wide unique core-id for @cpu */
 5034	rapl_core_id = cpus[cpu].physical_core_id;
 5035	rapl_core_id += cpus[cpu].physical_package_id * nr_cores_per_package;
 5036
 5037	return rapl_core_id;
 5038}
 5039
 5040/*
 5041 * get_counters(...)
 5042 * migrate to cpu
 5043 * acquire and record local counters for that cpu
 5044 */
 5045int get_counters(PER_THREAD_PARAMS)
 5046{
 5047	int cpu = t->cpu_id;
 5048	unsigned long long msr;
 5049	struct msr_counter *mp;
 5050	struct pmt_counter *pp;
 5051	int i;
 5052	int status;
 5053
 5054	if (cpu_migrate(cpu)) {
 5055		fprintf(outf, "%s: Could not migrate to CPU %d\n", __func__, cpu);
 5056		return -1;
 5057	}
 5058
 5059	gettimeofday(&t->tv_begin, (struct timezone *)NULL);
 5060
 5061	if (first_counter_read)
 5062		get_apic_id(t);
 5063
 5064	t->tsc = rdtsc();	/* we are running on local CPU of interest */
 5065
 5066	get_smi_aperf_mperf(cpu, t);
 5067
 5068	if (DO_BIC(BIC_LLC_RPS) || DO_BIC(BIC_LLC_HIT))
 5069		get_perf_llc_stats(cpu, &t->llc);
 5070
 5071	if (DO_BIC(BIC_IPC))
 5072		if (read(get_instr_count_fd(cpu), &t->instr_count, sizeof(long long)) != sizeof(long long))
 5073			return -4;
 5074
 5075	if (DO_BIC(BIC_IRQ))
 5076		t->irq_count = irqs_per_cpu[cpu];
 5077	if (DO_BIC(BIC_NMI))
 5078		t->nmi_count = nmi_per_cpu[cpu];
 5079
 5080	get_cstate_counters(cpu, t, c, p);
 5081
 5082	for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
 5083		if (get_mp(cpu, mp, &t->counter[i], mp->sp->path))
 5084			return -10;
 5085	}
 5086
 5087	if (perf_counter_info_read_values(sys.perf_tp, cpu, t->perf_counter, MAX_ADDED_THREAD_COUNTERS))
 5088		return -10;
 5089
 5090	for (i = 0, pp = sys.pmt_tp; pp; i++, pp = pp->next)
 5091		t->pmt_counter[i] = pmt_read_counter(pp, t->cpu_id);
 5092
 5093	/* collect core counters only for 1st thread in core */
 5094	if (!is_cpu_first_thread_in_core(t, c))
 5095		goto done;
 5096
 5097	if (platform->has_per_core_rapl) {
 5098		status = get_rapl_counters(cpu, get_rapl_domain_id(cpu), c, p);
 5099		if (status != 0)
 5100			return status;
 5101	}
 5102
 5103	if (DO_BIC(BIC_CPU_c7) && t->is_atom) {
 5104		/*
 5105		 * For Atom CPUs that has core cstate deeper than c6,
 5106		 * MSR_CORE_C6_RESIDENCY returns residency of cc6 and deeper.
 5107		 * Minus CC7 (and deeper cstates) residency to get
 5108		 * accturate cc6 residency.
 5109		 */
 5110		c->c6 -= c->c7;
 5111	}
 5112
 5113	if (DO_BIC(BIC_Mod_c6))
 5114		if (get_msr(cpu, MSR_MODULE_C6_RES_MS, &c->mc6_us))
 5115			return -8;
 5116
 5117	if (DO_BIC(BIC_CoreTmp)) {
 5118		if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
 5119			return -9;
 5120		c->core_temp_c = tj_max - ((msr >> 16) & 0x7F);
 5121	}
 5122
 5123	if (DO_BIC(BIC_CORE_THROT_CNT))
 5124		get_core_throt_cnt(cpu, &c->core_throt_cnt);
 5125
 5126	for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
 5127		if (get_mp(cpu, mp, &c->counter[i], mp->sp->path))
 5128			return -10;
 5129	}
 5130
 5131	if (perf_counter_info_read_values(sys.perf_cp, cpu, c->perf_counter, MAX_ADDED_CORE_COUNTERS))
 5132		return -10;
 5133
 5134	for (i = 0, pp = sys.pmt_cp; pp; i++, pp = pp->next)
 5135		c->pmt_counter[i] = pmt_read_counter(pp, c->core_id);
 5136
 5137	/* collect package counters only for 1st core in package */
 5138	if (!is_cpu_first_core_in_package(t, p))
 5139		goto done;
 5140
 5141	if (DO_BIC(BIC_Totl_c0)) {
 5142		if (get_msr(cpu, MSR_PKG_WEIGHTED_CORE_C0_RES, &p->pkg_wtd_core_c0))
 5143			return -10;
 5144	}
 5145	if (DO_BIC(BIC_Any_c0)) {
 5146		if (get_msr(cpu, MSR_PKG_ANY_CORE_C0_RES, &p->pkg_any_core_c0))
 5147			return -11;
 5148	}
 5149	if (DO_BIC(BIC_GFX_c0)) {
 5150		if (get_msr(cpu, MSR_PKG_ANY_GFXE_C0_RES, &p->pkg_any_gfxe_c0))
 5151			return -12;
 5152	}
 5153	if (DO_BIC(BIC_CPUGFX)) {
 5154		if (get_msr(cpu, MSR_PKG_BOTH_CORE_GFXE_C0_RES, &p->pkg_both_core_gfxe_c0))
 5155			return -13;
 5156	}
 5157
 5158	if (DO_BIC(BIC_CPU_LPI))
 5159		p->cpu_lpi = cpuidle_cur_cpu_lpi_us;
 5160	if (DO_BIC(BIC_SYS_LPI))
 5161		p->sys_lpi = cpuidle_cur_sys_lpi_us;
 5162
 5163	if (!platform->has_per_core_rapl) {
 5164		status = get_rapl_counters(cpu, get_rapl_domain_id(cpu), c, p);
 5165		if (status != 0)
 5166			return status;
 5167	}
 5168
 5169	if (DO_BIC(BIC_PkgTmp)) {
 5170		if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
 5171			return -17;
 5172		p->pkg_temp_c = tj_max - ((msr >> 16) & 0x7F);
 5173	}
 5174
 5175	if (DO_BIC(BIC_UNCORE_MHZ))
 5176		p->uncore_mhz = get_legacy_uncore_mhz(p->package_id);
 5177
 5178	if (DO_BIC(BIC_GFX_rc6))
 5179		p->gfx_rc6_ms = gfx_info[GFX_rc6].val_ull;
 5180
 5181	if (DO_BIC(BIC_GFXMHz))
 5182		p->gfx_mhz = gfx_info[GFX_MHz].val;
 5183
 5184	if (DO_BIC(BIC_GFXACTMHz))
 5185		p->gfx_act_mhz = gfx_info[GFX_ACTMHz].val;
 5186
 5187	if (DO_BIC(BIC_SAM_mc6))
 5188		p->sam_mc6_ms = gfx_info[SAM_mc6].val_ull;
 5189
 5190	if (DO_BIC(BIC_SAMMHz))
 5191		p->sam_mhz = gfx_info[SAM_MHz].val;
 5192
 5193	if (DO_BIC(BIC_SAMACTMHz))
 5194		p->sam_act_mhz = gfx_info[SAM_ACTMHz].val;
 5195
 5196	for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
 5197		char *path = NULL;
 5198
 5199		if (mp->msr_num == 0) {
 5200			path = find_sysfs_path_by_id(mp->sp, p->package_id);
 5201			if (path == NULL) {
 5202				warnx("%s: package_id %d not found", __func__, p->package_id);
 5203				return -10;
 5204			}
 5205		}
 5206		if (get_mp(cpu, mp, &p->counter[i], path))
 5207			return -10;
 5208	}
 5209
 5210	if (perf_counter_info_read_values(sys.perf_pp, cpu, p->perf_counter, MAX_ADDED_PACKAGE_COUNTERS))
 5211		return -10;
 5212
 5213	for (i = 0, pp = sys.pmt_pp; pp; i++, pp = pp->next)
 5214		p->pmt_counter[i] = pmt_read_counter(pp, p->package_id);
 5215
 5216done:
 5217	gettimeofday(&t->tv_end, (struct timezone *)NULL);
 5218
 5219	return 0;
 5220}
 5221
 5222int pkg_cstate_limit = PCLUKN;
 5223char *pkg_cstate_limit_strings[] = { "unknown", "reserved", "pc0", "pc1", "pc2",
 5224	"pc3", "pc4", "pc6", "pc6n", "pc6r", "pc7", "pc7s", "pc8", "pc9", "pc10", "unlimited"
 5225};
 5226
 5227int nhm_pkg_cstate_limits[16] = { PCL__0, PCL__1, PCL__3, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
 5228	PCLRSV, PCLRSV
 5229};
 5230
 5231int 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,
 5232	PCLRSV, PCLRSV
 5233};
 5234
 5235int 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,
 5236	PCLRSV, PCLRSV
 5237};
 5238
 5239int slv_pkg_cstate_limits[16] = { PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
 5240	PCL__6, PCL__7
 5241};
 5242
 5243int amt_pkg_cstate_limits[16] = { PCLUNL, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
 5244	PCLRSV, PCLRSV
 5245};
 5246
 5247int phi_pkg_cstate_limits[16] = { PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
 5248	PCLRSV, PCLRSV
 5249};
 5250
 5251int 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,
 5252	PCLRSV, PCLRSV
 5253};
 5254
 5255int skx_pkg_cstate_limits[16] = { PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
 5256	PCLRSV, PCLRSV
 5257};
 5258
 5259int icx_pkg_cstate_limits[16] = { PCL__0, PCL__2, PCL__6, PCL__6, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
 5260	PCLRSV, PCLRSV
 5261};
 5262
 5263void probe_cst_limit(void)
 5264{
 5265	unsigned long long msr;
 5266	int *pkg_cstate_limits;
 5267
 5268	if (!platform->has_nhm_msrs || no_msr)
 5269		return;
 5270
 5271	switch (platform->cst_limit) {
 5272	case CST_LIMIT_NHM:
 5273		pkg_cstate_limits = nhm_pkg_cstate_limits;
 5274		break;
 5275	case CST_LIMIT_SNB:
 5276		pkg_cstate_limits = snb_pkg_cstate_limits;
 5277		break;
 5278	case CST_LIMIT_HSW:
 5279		pkg_cstate_limits = hsw_pkg_cstate_limits;
 5280		break;
 5281	case CST_LIMIT_SKX:
 5282		pkg_cstate_limits = skx_pkg_cstate_limits;
 5283		break;
 5284	case CST_LIMIT_ICX:
 5285		pkg_cstate_limits = icx_pkg_cstate_limits;
 5286		break;
 5287	case CST_LIMIT_SLV:
 5288		pkg_cstate_limits = slv_pkg_cstate_limits;
 5289		break;
 5290	case CST_LIMIT_AMT:
 5291		pkg_cstate_limits = amt_pkg_cstate_limits;
 5292		break;
 5293	case CST_LIMIT_KNL:
 5294		pkg_cstate_limits = phi_pkg_cstate_limits;
 5295		break;
 5296	case CST_LIMIT_GMT:
 5297		pkg_cstate_limits = glm_pkg_cstate_limits;
 5298		break;
 5299	default:
 5300		return;
 5301	}
 5302
 5303	get_msr(base_cpu, MSR_PKG_CST_CONFIG_CONTROL, &msr);
 5304	pkg_cstate_limit = pkg_cstate_limits[msr & 0xF];
 5305}
 5306
 5307static void dump_platform_info(void)
 5308{
 5309	unsigned long long msr;
 5310	unsigned int ratio;
 5311
 5312	if (!platform->has_nhm_msrs || no_msr)
 5313		return;
 5314
 5315	get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
 5316
 5317	fprintf(outf, "cpu%d: MSR_PLATFORM_INFO: 0x%08llx\n", base_cpu, msr);
 5318
 5319	ratio = (msr >> 40) & 0xFF;
 5320	fprintf(outf, "%d * %.1f = %.1f MHz max efficiency frequency\n", ratio, bclk, ratio * bclk);
 5321
 5322	ratio = (msr >> 8) & 0xFF;
 5323	fprintf(outf, "%d * %.1f = %.1f MHz base frequency\n", ratio, bclk, ratio * bclk);
 5324}
 5325
 5326static void dump_power_ctl(void)
 5327{
 5328	unsigned long long msr;
 5329
 5330	if (!platform->has_nhm_msrs || no_msr)
 5331		return;
 5332
 5333	get_msr(base_cpu, MSR_IA32_POWER_CTL, &msr);
 5334	fprintf(outf, "cpu%d: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n", base_cpu, msr, msr & 0x2 ? "EN" : "DIS");
 5335
 5336	/* C-state Pre-wake Disable (CSTATE_PREWAKE_DISABLE) */
 5337	if (platform->has_cst_prewake_bit)
 5338		fprintf(outf, "C-state Pre-wake: %sabled\n", msr & 0x40000000 ? "DIS" : "EN");
 5339
 5340	return;
 5341}
 5342
 5343static void dump_turbo_ratio_limit2(void)
 5344{
 5345	unsigned long long msr;
 5346	unsigned int ratio;
 5347
 5348	get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT2, &msr);
 5349
 5350	fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT2: 0x%08llx\n", base_cpu, msr);
 5351
 5352	ratio = (msr >> 8) & 0xFF;
 5353	if (ratio)
 5354		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 18 active cores\n", ratio, bclk, ratio * bclk);
 5355
 5356	ratio = (msr >> 0) & 0xFF;
 5357	if (ratio)
 5358		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 17 active cores\n", ratio, bclk, ratio * bclk);
 5359	return;
 5360}
 5361
 5362static void dump_turbo_ratio_limit1(void)
 5363{
 5364	unsigned long long msr;
 5365	unsigned int ratio;
 5366
 5367	get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &msr);
 5368
 5369	fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, msr);
 5370
 5371	ratio = (msr >> 56) & 0xFF;
 5372	if (ratio)
 5373		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 16 active cores\n", ratio, bclk, ratio * bclk);
 5374
 5375	ratio = (msr >> 48) & 0xFF;
 5376	if (ratio)
 5377		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 15 active cores\n", ratio, bclk, ratio * bclk);
 5378
 5379	ratio = (msr >> 40) & 0xFF;
 5380	if (ratio)
 5381		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 14 active cores\n", ratio, bclk, ratio * bclk);
 5382
 5383	ratio = (msr >> 32) & 0xFF;
 5384	if (ratio)
 5385		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 13 active cores\n", ratio, bclk, ratio * bclk);
 5386
 5387	ratio = (msr >> 24) & 0xFF;
 5388	if (ratio)
 5389		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 12 active cores\n", ratio, bclk, ratio * bclk);
 5390
 5391	ratio = (msr >> 16) & 0xFF;
 5392	if (ratio)
 5393		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 11 active cores\n", ratio, bclk, ratio * bclk);
 5394
 5395	ratio = (msr >> 8) & 0xFF;
 5396	if (ratio)
 5397		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 10 active cores\n", ratio, bclk, ratio * bclk);
 5398
 5399	ratio = (msr >> 0) & 0xFF;
 5400	if (ratio)
 5401		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 9 active cores\n", ratio, bclk, ratio * bclk);
 5402	return;
 5403}
 5404
 5405static void dump_turbo_ratio_limits(int trl_msr_offset)
 5406{
 5407	unsigned long long msr, core_counts;
 5408	int shift;
 5409
 5410	get_msr(base_cpu, trl_msr_offset, &msr);
 5411	fprintf(outf, "cpu%d: MSR_%sTURBO_RATIO_LIMIT: 0x%08llx\n",
 5412		base_cpu, trl_msr_offset == MSR_SECONDARY_TURBO_RATIO_LIMIT ? "SECONDARY_" : "", msr);
 5413
 5414	if (platform->trl_msrs & TRL_CORECOUNT) {
 5415		get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &core_counts);
 5416		fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, core_counts);
 5417	} else {
 5418		core_counts = 0x0807060504030201;
 5419	}
 5420
 5421	for (shift = 56; shift >= 0; shift -= 8) {
 5422		unsigned int ratio, group_size;
 5423
 5424		ratio = (msr >> shift) & 0xFF;
 5425		group_size = (core_counts >> shift) & 0xFF;
 5426		if (ratio)
 5427			fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n", ratio, bclk, ratio * bclk, group_size);
 5428	}
 5429
 5430	return;
 5431}
 5432
 5433static void dump_atom_turbo_ratio_limits(void)
 5434{
 5435	unsigned long long msr;
 5436	unsigned int ratio;
 5437
 5438	get_msr(base_cpu, MSR_ATOM_CORE_RATIOS, &msr);
 5439	fprintf(outf, "cpu%d: MSR_ATOM_CORE_RATIOS: 0x%08llx\n", base_cpu, msr & 0xFFFFFFFF);
 5440
 5441	ratio = (msr >> 0) & 0x3F;
 5442	if (ratio)
 5443		fprintf(outf, "%d * %.1f = %.1f MHz minimum operating frequency\n", ratio, bclk, ratio * bclk);
 5444
 5445	ratio = (msr >> 8) & 0x3F;
 5446	if (ratio)
 5447		fprintf(outf, "%d * %.1f = %.1f MHz low frequency mode (LFM)\n", ratio, bclk, ratio * bclk);
 5448
 5449	ratio = (msr >> 16) & 0x3F;
 5450	if (ratio)
 5451		fprintf(outf, "%d * %.1f = %.1f MHz base frequency\n", ratio, bclk, ratio * bclk);
 5452
 5453	get_msr(base_cpu, MSR_ATOM_CORE_TURBO_RATIOS, &msr);
 5454	fprintf(outf, "cpu%d: MSR_ATOM_CORE_TURBO_RATIOS: 0x%08llx\n", base_cpu, msr & 0xFFFFFFFF);
 5455
 5456	ratio = (msr >> 24) & 0x3F;
 5457	if (ratio)
 5458		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 4 active cores\n", ratio, bclk, ratio * bclk);
 5459
 5460	ratio = (msr >> 16) & 0x3F;
 5461	if (ratio)
 5462		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 3 active cores\n", ratio, bclk, ratio * bclk);
 5463
 5464	ratio = (msr >> 8) & 0x3F;
 5465	if (ratio)
 5466		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 2 active cores\n", ratio, bclk, ratio * bclk);
 5467
 5468	ratio = (msr >> 0) & 0x3F;
 5469	if (ratio)
 5470		fprintf(outf, "%d * %.1f = %.1f MHz max turbo 1 active core\n", ratio, bclk, ratio * bclk);
 5471}
 5472
 5473static void dump_knl_turbo_ratio_limits(void)
 5474{
 5475	const unsigned int buckets_no = 7;
 5476
 5477	unsigned long long msr;
 5478	int delta_cores, delta_ratio;
 5479	int i, b_nr;
 5480	unsigned int cores[buckets_no];
 5481	unsigned int ratio[buckets_no];
 5482
 5483	get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
 5484
 5485	fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", base_cpu, msr);
 5486
 5487	/*
 5488	 * Turbo encoding in KNL is as follows:
 5489	 * [0] -- Reserved
 5490	 * [7:1] -- Base value of number of active cores of bucket 1.
 5491	 * [15:8] -- Base value of freq ratio of bucket 1.
 5492	 * [20:16] -- +ve delta of number of active cores of bucket 2.
 5493	 * i.e. active cores of bucket 2 =
 5494	 * active cores of bucket 1 + delta
 5495	 * [23:21] -- Negative delta of freq ratio of bucket 2.
 5496	 * i.e. freq ratio of bucket 2 =
 5497	 * freq ratio of bucket 1 - delta
 5498	 * [28:24]-- +ve delta of number of active cores of bucket 3.
 5499	 * [31:29]-- -ve delta of freq ratio of bucket 3.
 5500	 * [36:32]-- +ve delta of number of active cores of bucket 4.
 5501	 * [39:37]-- -ve delta of freq ratio of bucket 4.
 5502	 * [44:40]-- +ve delta of number of active cores of bucket 5.
 5503	 * [47:45]-- -ve delta of freq ratio of bucket 5.
 5504	 * [52:48]-- +ve delta of number of active cores of bucket 6.
 5505	 * [55:53]-- -ve delta of freq ratio of bucket 6.
 5506	 * [60:56]-- +ve delta of number of active cores of bucket 7.
 5507	 * [63:61]-- -ve delta of freq ratio of bucket 7.
 5508	 */
 5509
 5510	b_nr = 0;
 5511	cores[b_nr] = (msr & 0xFF) >> 1;
 5512	ratio[b_nr] = (msr >> 8) & 0xFF;
 5513
 5514	for (i = 16; i < 64; i += 8) {
 5515		delta_cores = (msr >> i) & 0x1F;
 5516		delta_ratio = (msr >> (i + 5)) & 0x7;
 5517
 5518		cores[b_nr + 1] = cores[b_nr] + delta_cores;
 5519		ratio[b_nr + 1] = ratio[b_nr] - delta_ratio;
 5520		b_nr++;
 5521	}
 5522
 5523	for (i = buckets_no - 1; i >= 0; i--)
 5524		if (i > 0 ? ratio[i] != ratio[i - 1] : 1)
 5525			fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n", ratio[i], bclk, ratio[i] * bclk, cores[i]);
 5526}
 5527
 5528static void dump_cst_cfg(void)
 5529{
 5530	unsigned long long msr;
 5531
 5532	if (!platform->has_nhm_msrs || no_msr)
 5533		return;
 5534
 5535	get_msr(base_cpu, MSR_PKG_CST_CONFIG_CONTROL, &msr);
 5536
 5537	fprintf(outf, "cpu%d: MSR_PKG_CST_CONFIG_CONTROL: 0x%08llx", base_cpu, msr);
 5538
 5539	fprintf(outf, " (%s%s%s%s%slocked, pkg-cstate-limit=%d (%s)",
 5540		(msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "",
 5541		(msr & SNB_C1_AUTO_UNDEMOTE) ? "UNdemote-C1, " : "",
 5542		(msr & NHM_C3_AUTO_DEMOTE) ? "demote-C3, " : "",
 5543		(msr & NHM_C1_AUTO_DEMOTE) ? "demote-C1, " : "",
 5544		(msr & (1 << 15)) ? "" : "UN", (unsigned int)msr & 0xF, pkg_cstate_limit_strings[pkg_cstate_limit]);
 5545
 5546#define AUTOMATIC_CSTATE_CONVERSION		(1UL << 16)
 5547	if (platform->has_cst_auto_convension) {
 5548		fprintf(outf, ", automatic c-state conversion=%s", (msr & AUTOMATIC_CSTATE_CONVERSION) ? "on" : "off");
 5549	}
 5550
 5551	fprintf(outf, ")\n");
 5552
 5553	return;
 5554}
 5555
 5556static void dump_config_tdp(void)
 5557{
 5558	unsigned long long msr;
 5559
 5560	get_msr(base_cpu, MSR_CONFIG_TDP_NOMINAL, &msr);
 5561	fprintf(outf, "cpu%d: MSR_CONFIG_TDP_NOMINAL: 0x%08llx", base_cpu, msr);
 5562	fprintf(outf, " (base_ratio=%d)\n", (unsigned int)msr & 0xFF);
 5563
 5564	get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_1, &msr);
 5565	fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_1: 0x%08llx (", base_cpu, msr);
 5566	if (msr) {
 5567		fprintf(outf, "PKG_MIN_PWR_LVL1=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
 5568		fprintf(outf, "PKG_MAX_PWR_LVL1=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
 5569		fprintf(outf, "LVL1_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
 5570		fprintf(outf, "PKG_TDP_LVL1=%d", (unsigned int)(msr) & 0x7FFF);
 5571	}
 5572	fprintf(outf, ")\n");
 5573
 5574	get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_2, &msr);
 5575	fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_2: 0x%08llx (", base_cpu, msr);
 5576	if (msr) {
 5577		fprintf(outf, "PKG_MIN_PWR_LVL2=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
 5578		fprintf(outf, "PKG_MAX_PWR_LVL2=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
 5579		fprintf(outf, "LVL2_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
 5580		fprintf(outf, "PKG_TDP_LVL2=%d", (unsigned int)(msr) & 0x7FFF);
 5581	}
 5582	fprintf(outf, ")\n");
 5583
 5584	get_msr(base_cpu, MSR_CONFIG_TDP_CONTROL, &msr);
 5585	fprintf(outf, "cpu%d: MSR_CONFIG_TDP_CONTROL: 0x%08llx (", base_cpu, msr);
 5586	if ((msr) & 0x3)
 5587		fprintf(outf, "TDP_LEVEL=%d ", (unsigned int)(msr) & 0x3);
 5588	fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
 5589	fprintf(outf, ")\n");
 5590
 5591	get_msr(base_cpu, MSR_TURBO_ACTIVATION_RATIO, &msr);
 5592	fprintf(outf, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu, msr);
 5593	fprintf(outf, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0xFF);
 5594	fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
 5595	fprintf(outf, ")\n");
 5596}
 5597
 5598unsigned int irtl_time_units[] = { 1, 32, 1024, 32768, 1048576, 33554432, 0, 0 };
 5599
 5600void print_irtl(void)
 5601{
 5602	unsigned long long msr;
 5603
 5604	if (!platform->has_irtl_msrs || no_msr)
 5605		return;
 5606
 5607	if (platform->supported_cstates & PC3) {
 5608		get_msr(base_cpu, MSR_PKGC3_IRTL, &msr);
 5609		fprintf(outf, "cpu%d: MSR_PKGC3_IRTL: 0x%08llx (", base_cpu, msr);
 5610		fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT", (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
 5611	}
 5612
 5613	if (platform->supported_cstates & PC6) {
 5614		get_msr(base_cpu, MSR_PKGC6_IRTL, &msr);
 5615		fprintf(outf, "cpu%d: MSR_PKGC6_IRTL: 0x%08llx (", base_cpu, msr);
 5616		fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT", (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
 5617	}
 5618
 5619	if (platform->supported_cstates & PC7) {
 5620		get_msr(base_cpu, MSR_PKGC7_IRTL, &msr);
 5621		fprintf(outf, "cpu%d: MSR_PKGC7_IRTL: 0x%08llx (", base_cpu, msr);
 5622		fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT", (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
 5623	}
 5624
 5625	if (platform->supported_cstates & PC8) {
 5626		get_msr(base_cpu, MSR_PKGC8_IRTL, &msr);
 5627		fprintf(outf, "cpu%d: MSR_PKGC8_IRTL: 0x%08llx (", base_cpu, msr);
 5628		fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT", (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
 5629	}
 5630
 5631	if (platform->supported_cstates & PC9) {
 5632		get_msr(base_cpu, MSR_PKGC9_IRTL, &msr);
 5633		fprintf(outf, "cpu%d: MSR_PKGC9_IRTL: 0x%08llx (", base_cpu, msr);
 5634		fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT", (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
 5635	}
 5636
 5637	if (platform->supported_cstates & PC10) {
 5638		get_msr(base_cpu, MSR_PKGC10_IRTL, &msr);
 5639		fprintf(outf, "cpu%d: MSR_PKGC10_IRTL: 0x%08llx (", base_cpu, msr);
 5640		fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT", (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
 5641	}
 5642}
 5643
 5644void free_fd_percpu(void)
 5645{
 5646	int i;
 5647
 5648	if (!fd_percpu)
 5649		return;
 5650
 5651	for (i = 0; i < topo.max_cpu_num + 1; ++i) {
 5652		if (fd_percpu[i] != 0)
 5653			close(fd_percpu[i]);
 5654	}
 5655
 5656	free(fd_percpu);
 5657	fd_percpu = NULL;
 5658}
 5659
 5660void free_fd_instr_count_percpu(void)
 5661{
 5662	if (!fd_instr_count_percpu)
 5663		return;
 5664
 5665	for (int i = 0; i < topo.max_cpu_num + 1; ++i) {
 5666		if (fd_instr_count_percpu[i] != 0)
 5667			close(fd_instr_count_percpu[i]);
 5668	}
 5669
 5670	free(fd_instr_count_percpu);
 5671	fd_instr_count_percpu = NULL;
 5672}
 5673
 5674void free_fd_llc_percpu(void)
 5675{
 5676	if (!fd_llc_percpu)
 5677		return;
 5678
 5679	for (int i = 0; i < topo.max_cpu_num + 1; ++i) {
 5680		if (fd_llc_percpu[i] != 0)
 5681			close(fd_llc_percpu[i]);
 5682	}
 5683
 5684	free(fd_llc_percpu);
 5685	fd_llc_percpu = NULL;
 5686}
 5687
 5688void free_fd_cstate(void)
 5689{
 5690	if (!ccstate_counter_info)
 5691		return;
 5692
 5693	const int counter_info_num = ccstate_counter_info_size;
 5694
 5695	for (int counter_id = 0; counter_id < counter_info_num; ++counter_id) {
 5696		if (ccstate_counter_info[counter_id].fd_perf_core != -1)
 5697			close(ccstate_counter_info[counter_id].fd_perf_core);
 5698
 5699		if (ccstate_counter_info[counter_id].fd_perf_pkg != -1)
 5700			close(ccstate_counter_info[counter_id].fd_perf_pkg);
 5701	}
 5702
 5703	free(ccstate_counter_info);
 5704	ccstate_counter_info = NULL;
 5705	ccstate_counter_info_size = 0;
 5706}
 5707
 5708void free_fd_msr(void)
 5709{
 5710	if (!msr_counter_info)
 5711		return;
 5712
 5713	for (int cpu = 0; cpu < topo.max_cpu_num; ++cpu) {
 5714		if (msr_counter_info[cpu].fd_perf != -1)
 5715			close(msr_counter_info[cpu].fd_perf);
 5716	}
 5717
 5718	free(msr_counter_info);
 5719	msr_counter_info = NULL;
 5720	msr_counter_info_size = 0;
 5721}
 5722
 5723void free_fd_rapl_percpu(void)
 5724{
 5725	if (!rapl_counter_info_perdomain)
 5726		return;
 5727
 5728	const int num_domains = rapl_counter_info_perdomain_size;
 5729
 5730	for (int domain_id = 0; domain_id < num_domains; ++domain_id) {
 5731		if (rapl_counter_info_perdomain[domain_id].fd_perf != -1)
 5732			close(rapl_counter_info_perdomain[domain_id].fd_perf);
 5733	}
 5734
 5735	free(rapl_counter_info_perdomain);
 5736	rapl_counter_info_perdomain = NULL;
 5737	rapl_counter_info_perdomain_size = 0;
 5738}
 5739
 5740void free_fd_added_perf_counters_(struct perf_counter_info *pp)
 5741{
 5742	if (!pp)
 5743		return;
 5744
 5745	if (!pp->fd_perf_per_domain)
 5746		return;
 5747
 5748	while (pp) {
 5749		for (size_t domain = 0; domain < pp->num_domains; ++domain) {
 5750			if (pp->fd_perf_per_domain[domain] != -1) {
 5751				close(pp->fd_perf_per_domain[domain]);
 5752				pp->fd_perf_per_domain[domain] = -1;
 5753			}
 5754		}
 5755
 5756		free(pp->fd_perf_per_domain);
 5757		pp->fd_perf_per_domain = NULL;
 5758
 5759		pp = pp->next;
 5760	}
 5761}
 5762
 5763void free_fd_added_perf_counters(void)
 5764{
 5765	free_fd_added_perf_counters_(sys.perf_tp);
 5766	free_fd_added_perf_counters_(sys.perf_cp);
 5767	free_fd_added_perf_counters_(sys.perf_pp);
 5768}
 5769
 5770void free_all_buffers(void)
 5771{
 5772	int i;
 5773
 5774	CPU_FREE(cpu_present_set);
 5775	cpu_present_set = NULL;
 5776	cpu_present_setsize = 0;
 5777
 5778	CPU_FREE(cpu_effective_set);
 5779	cpu_effective_set = NULL;
 5780	cpu_effective_setsize = 0;
 5781
 5782	CPU_FREE(cpu_allowed_set);
 5783	cpu_allowed_set = NULL;
 5784	cpu_allowed_setsize = 0;
 5785
 5786	CPU_FREE(cpu_affinity_set);
 5787	cpu_affinity_set = NULL;
 5788	cpu_affinity_setsize = 0;
 5789
 5790	free(thread_even);
 5791	free(core_even);
 5792	free(package_even);
 5793
 5794	thread_even = NULL;
 5795	core_even = NULL;
 5796	package_even = NULL;
 5797
 5798	free(thread_odd);
 5799	free(core_odd);
 5800	free(package_odd);
 5801
 5802	thread_odd = NULL;
 5803	core_odd = NULL;
 5804	package_odd = NULL;
 5805
 5806	free(output_buffer);
 5807	output_buffer = NULL;
 5808	outp = NULL;
 5809
 5810	free_fd_percpu();
 5811	free_fd_instr_count_percpu();
 5812	free_fd_llc_percpu();
 5813	free_fd_msr();
 5814	free_fd_rapl_percpu();
 5815	free_fd_cstate();
 5816	free_fd_added_perf_counters();
 5817
 5818	free(irq_column_2_cpu);
 5819	free(irqs_per_cpu);
 5820	free(nmi_per_cpu);
 5821
 5822	for (i = 0; i <= topo.max_cpu_num; ++i) {
 5823		if (cpus[i].put_ids)
 5824			CPU_FREE(cpus[i].put_ids);
 5825	}
 5826	free(cpus);
 5827}
 5828
 5829/*
 5830 * Parse a file containing a single int.
 5831 * Return 0 if file can not be opened
 5832 * Exit if file can be opened, but can not be parsed
 5833 */
 5834int parse_int_file(const char *fmt, ...)
 5835{
 5836	va_list args;
 5837	char path[PATH_MAX];
 5838	FILE *filep;
 5839	int value;
 5840
 5841	va_start(args, fmt);
 5842	vsnprintf(path, sizeof(path), fmt, args);
 5843	va_end(args);
 5844	filep = fopen(path, "r");
 5845	if (!filep)
 5846		return 0;
 5847	if (fscanf(filep, "%d", &value) != 1)
 5848		err(1, "%s: failed to parse number from file", path);
 5849	fclose(filep);
 5850	return value;
 5851}
 5852
 5853/*
 5854 * cpu_is_first_core_in_package(cpu)
 5855 * return 1 if given CPU is 1st core in package
 5856 */
 5857int cpu_is_first_core_in_package(int cpu)
 5858{
 5859	return cpu == parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_siblings_list", cpu);
 5860}
 5861
 5862int get_physical_package_id(int cpu)
 5863{
 5864	return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu);
 5865}
 5866
 5867int get_die_id(int cpu)
 5868{
 5869	return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/die_id", cpu);
 5870}
 5871
 5872int get_l3_id(int cpu)
 5873{
 5874	return parse_int_file("/sys/devices/system/cpu/cpu%d/cache/index3/id", cpu);
 5875}
 5876
 5877int get_core_id(int cpu)
 5878{
 5879	return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", cpu);
 5880}
 5881
 5882void set_node_data(void)
 5883{
 5884	int pkg, node, lnode, cpu, cpux;
 5885	int cpu_count;
 5886
 5887	/* initialize logical_node_id */
 5888	for (cpu = 0; cpu <= topo.max_cpu_num; ++cpu)
 5889		cpus[cpu].logical_node_id = -1;
 5890
 5891	cpu_count = 0;
 5892	for (pkg = 0; pkg < topo.num_packages; pkg++) {
 5893		lnode = 0;
 5894		for (cpu = 0; cpu <= topo.max_cpu_num; ++cpu) {
 5895			if (cpus[cpu].physical_package_id != pkg)
 5896				continue;
 5897			/* find a cpu with an unset logical_node_id */
 5898			if (cpus[cpu].logical_node_id != -1)
 5899				continue;
 5900			cpus[cpu].logical_node_id = lnode;
 5901			node = cpus[cpu].physical_node_id;
 5902			cpu_count++;
 5903			/*
 5904			 * find all matching cpus on this pkg and set
 5905			 * the logical_node_id
 5906			 */
 5907			for (cpux = cpu; cpux <= topo.max_cpu_num; cpux++) {
 5908				if ((cpus[cpux].physical_package_id == pkg) && (cpus[cpux].physical_node_id == node)) {
 5909					cpus[cpux].logical_node_id = lnode;
 5910					cpu_count++;
 5911				}
 5912			}
 5913			lnode++;
 5914			if (lnode > topo.nodes_per_pkg)
 5915				topo.nodes_per_pkg = lnode;
 5916		}
 5917		if (cpu_count >= topo.max_cpu_num)
 5918			break;
 5919	}
 5920}
 5921
 5922int get_physical_node_id(struct cpu_topology *thiscpu)
 5923{
 5924	char path[80];
 5925	FILE *filep;
 5926	int i;
 5927	int cpu = thiscpu->logical_cpu_id;
 5928
 5929	for (i = 0; i <= topo.max_cpu_num; i++) {
 5930		sprintf(path, "/sys/devices/system/cpu/cpu%d/node%i/cpulist", cpu, i);
 5931		filep = fopen(path, "r");
 5932		if (!filep)
 5933			continue;
 5934		fclose(filep);
 5935		return i;
 5936	}
 5937	return -1;
 5938}
 5939
 5940static int parse_cpu_str(char *cpu_str, cpu_set_t *cpu_set, int cpu_set_size)
 5941{
 5942	unsigned int start, end;
 5943	char *next = cpu_str;
 5944
 5945	while (next && *next) {
 5946
 5947		if (*next == '-')	/* no negative cpu numbers */
 5948			return 1;
 5949
 5950		if (*next == '\0' || *next == '\n')
 5951			break;
 5952
 5953		start = strtoul(next, &next, 10);
 5954
 5955		if (start >= CPU_SUBSET_MAXCPUS)
 5956			return 1;
 5957		CPU_SET_S(start, cpu_set_size, cpu_set);
 5958
 5959		if (*next == '\0' || *next == '\n')
 5960			break;
 5961
 5962		if (*next == ',') {
 5963			next += 1;
 5964			continue;
 5965		}
 5966
 5967		if (*next == '-') {
 5968			next += 1;	/* start range */
 5969		} else if (*next == '.') {
 5970			next += 1;
 5971			if (*next == '.')
 5972				next += 1;	/* start range */
 5973			else
 5974				return 1;
 5975		}
 5976
 5977		end = strtoul(next, &next, 10);
 5978		if (end <= start)
 5979			return 1;
 5980
 5981		while (++start <= end) {
 5982			if (start >= CPU_SUBSET_MAXCPUS)
 5983				return 1;
 5984			CPU_SET_S(start, cpu_set_size, cpu_set);
 5985		}
 5986
 5987		if (*next == ',')
 5988			next += 1;
 5989		else if (*next != '\0' && *next != '\n')
 5990			return 1;
 5991	}
 5992
 5993	return 0;
 5994}
 5995
 5996int get_thread_siblings(struct cpu_topology *thiscpu)
 5997{
 5998	char path[80], character;
 5999	FILE *filep;
 6000	unsigned long map;
 6001	int so, shift, sib_core;
 6002	int cpu = thiscpu->logical_cpu_id;
 6003	int offset = topo.max_cpu_num + 1;
 6004	size_t size;
 6005	int thread_id = 0;
 6006
 6007	thiscpu->put_ids = CPU_ALLOC((topo.max_cpu_num + 1));
 6008	if (thiscpu->thread_id < 0)
 6009		thiscpu->thread_id = thread_id++;
 6010	if (!thiscpu->put_ids)
 6011		return -1;
 6012
 6013	size = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
 6014	CPU_ZERO_S(size, thiscpu->put_ids);
 6015
 6016	sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", cpu);
 6017	filep = fopen(path, "r");
 6018
 6019	if (!filep) {
 6020		warnx("%s: open failed", path);
 6021		return -1;
 6022	}
 6023	do {
 6024		offset -= BITMASK_SIZE;
 6025		if (fscanf(filep, "%lx%c", &map, &character) != 2)
 6026			err(1, "%s: failed to parse file", path);
 6027		for (shift = 0; shift < BITMASK_SIZE; shift++) {
 6028			if ((map >> shift) & 0x1) {
 6029				so = shift + offset;
 6030				sib_core = get_core_id(so);
 6031				if (sib_core == thiscpu->physical_core_id) {
 6032					CPU_SET_S(so, size, thiscpu->put_ids);
 6033					if ((so != cpu) && (cpus[so].thread_id < 0))
 6034						cpus[so].thread_id = thread_id++;
 6035				}
 6036			}
 6037		}
 6038	} while (character == ',');
 6039	fclose(filep);
 6040
 6041	return CPU_COUNT_S(size, thiscpu->put_ids);
 6042}
 6043
 6044/*
 6045 * run func(thread, core, package) in topology order
 6046 * skip non-present cpus
 6047 */
 6048
 6049int for_all_cpus_2(int (func) (struct thread_data *, struct core_data *,
 6050			       struct pkg_data *, struct thread_data *, struct core_data *,
 6051			       struct pkg_data *), struct thread_data *thread_base,
 6052		   struct core_data *core_base, struct pkg_data *pkg_base,
 6053		   struct thread_data *thread_base2, struct core_data *core_base2, struct pkg_data *pkg_base2)
 6054{
 6055	int retval, pkg_no, node_no, core_no, thread_no;
 6056
 6057	retval = 0;
 6058
 6059	for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) {
 6060		for (node_no = 0; node_no < topo.nodes_per_pkg; ++node_no) {
 6061			for (core_no = 0; core_no < topo.cores_per_node; ++core_no) {
 6062				for (thread_no = 0; thread_no < topo.threads_per_core; ++thread_no) {
 6063					struct thread_data *t, *t2;
 6064					struct core_data *c, *c2;
 6065
 6066					t = GET_THREAD(thread_base, thread_no, core_no, node_no, pkg_no);
 6067
 6068					if (cpu_is_not_allowed(t->cpu_id))
 6069						continue;
 6070
 6071					t2 = GET_THREAD(thread_base2, thread_no, core_no, node_no, pkg_no);
 6072
 6073					c = GET_CORE(core_base, core_no, node_no, pkg_no);
 6074					c2 = GET_CORE(core_base2, core_no, node_no, pkg_no);
 6075
 6076					retval |= func(t, c, &pkg_base[pkg_no], t2, c2, &pkg_base2[pkg_no]);
 6077				}
 6078			}
 6079		}
 6080	}
 6081	return retval;
 6082}
 6083
 6084/*
 6085 * run func(cpu) on every cpu in /proc/stat
 6086 * return max_cpu number
 6087 */
 6088int for_all_proc_cpus(int (func) (int))
 6089{
 6090	FILE *fp;
 6091	int cpu_num;
 6092	int retval;
 6093
 6094	fp = fopen_or_die(proc_stat, "r");
 6095
 6096	retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n");
 6097	if (retval != 0)
 6098		err(1, "%s: failed to parse format", proc_stat);
 6099
 6100	while (1) {
 6101		retval = fscanf(fp, "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n", &cpu_num);
 6102		if (retval != 1)
 6103			break;
 6104
 6105		retval = func(cpu_num);
 6106		if (retval) {
 6107			fclose(fp);
 6108			return (retval);
 6109		}
 6110	}
 6111	fclose(fp);
 6112	return 0;
 6113}
 6114
 6115#define PATH_EFFECTIVE_CPUS	"/sys/fs/cgroup/cpuset.cpus.effective"
 6116
 6117static char cpu_effective_str[1024];
 6118
 6119static int update_effective_str(bool startup)
 6120{
 6121	FILE *fp;
 6122	char *pos;
 6123	char buf[1024];
 6124	int ret;
 6125
 6126	if (cpu_effective_str[0] == '\0' && !startup)
 6127		return 0;
 6128
 6129	fp = fopen(PATH_EFFECTIVE_CPUS, "r");
 6130	if (!fp)
 6131		return 0;
 6132
 6133	pos = fgets(buf, 1024, fp);
 6134	if (!pos)
 6135		err(1, "%s: file read failed\n", PATH_EFFECTIVE_CPUS);
 6136
 6137	fclose(fp);
 6138
 6139	ret = strncmp(cpu_effective_str, buf, 1024);
 6140	if (!ret)
 6141		return 0;
 6142
 6143	strncpy(cpu_effective_str, buf, 1024);
 6144	return 1;
 6145}
 6146
 6147static void update_effective_set(bool startup)
 6148{
 6149	update_effective_str(startup);
 6150
 6151	if (parse_cpu_str(cpu_effective_str, cpu_effective_set, cpu_effective_setsize))
 6152		err(1, "%s: cpu str malformat %s\n", PATH_EFFECTIVE_CPUS, cpu_effective_str);
 6153}
 6154
 6155void linux_perf_init(void);
 6156void msr_perf_init(void);
 6157void rapl_perf_init(void);
 6158void cstate_perf_init(void);
 6159void perf_llc_init(void);
 6160void added_perf_counters_init(void);
 6161void pmt_init(void);
 6162
 6163void re_initialize(void)
 6164{
 6165	free_all_buffers();
 6166	setup_all_buffers(false);
 6167	linux_perf_init();
 6168	msr_perf_init();
 6169	rapl_perf_init();
 6170	cstate_perf_init();
 6171	perf_llc_init();
 6172	added_perf_counters_init();
 6173	pmt_init();
 6174	fprintf(outf, "turbostat: re-initialized with num_cpus %d, allowed_cpus %d\n", topo.num_cpus, topo.allowed_cpus);
 6175}
 6176
 6177void set_max_cpu_num(void)
 6178{
 6179	FILE *filep;
 6180	int base_cpu;
 6181	unsigned long dummy;
 6182	char pathname[64];
 6183
 6184	base_cpu = sched_getcpu();
 6185	if (base_cpu < 0)
 6186		err(1, "cannot find calling cpu ID");
 6187	sprintf(pathname, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", base_cpu);
 6188
 6189	filep = fopen_or_die(pathname, "r");
 6190	topo.max_cpu_num = 0;
 6191	while (fscanf(filep, "%lx,", &dummy) == 1)
 6192		topo.max_cpu_num += BITMASK_SIZE;
 6193	fclose(filep);
 6194	topo.max_cpu_num--;	/* 0 based */
 6195}
 6196
 6197/*
 6198 * count_cpus()
 6199 * remember the last one seen, it will be the max
 6200 */
 6201int count_cpus(int cpu)
 6202{
 6203	UNUSED(cpu);
 6204
 6205	topo.num_cpus++;
 6206	return 0;
 6207}
 6208
 6209int mark_cpu_present(int cpu)
 6210{
 6211	CPU_SET_S(cpu, cpu_present_setsize, cpu_present_set);
 6212	return 0;
 6213}
 6214
 6215int init_thread_id(int cpu)
 6216{
 6217	cpus[cpu].thread_id = -1;
 6218	return 0;
 6219}
 6220
 6221int set_my_cpu_type(void)
 6222{
 6223	unsigned int eax, ebx, ecx, edx;
 6224	unsigned int max_level;
 6225
 6226	__cpuid(0, max_level, ebx, ecx, edx);
 6227
 6228	if (max_level < CPUID_LEAF_MODEL_ID)
 6229		return 0;
 6230
 6231	__cpuid(CPUID_LEAF_MODEL_ID, eax, ebx, ecx, edx);
 6232
 6233	return (eax >> CPUID_LEAF_MODEL_ID_CORE_TYPE_SHIFT);
 6234}
 6235
 6236int set_cpu_hybrid_type(int cpu)
 6237{
 6238	if (cpu_migrate(cpu))
 6239		return -1;
 6240
 6241	int type = set_my_cpu_type();
 6242
 6243	cpus[cpu].type = type;
 6244	return 0;
 6245}
 6246
 6247/*
 6248 * snapshot_proc_interrupts()
 6249 *
 6250 * read and record summary of /proc/interrupts
 6251 *
 6252 * return 1 if config change requires a restart, else return 0
 6253 */
 6254int snapshot_proc_interrupts(void)
 6255{
 6256	static FILE *fp;
 6257	int column, retval;
 6258
 6259	if (fp == NULL)
 6260		fp = fopen_or_die("/proc/interrupts", "r");
 6261	else
 6262		rewind(fp);
 6263
 6264	/* read 1st line of /proc/interrupts to get cpu* name for each column */
 6265	for (column = 0; column < topo.num_cpus; ++column) {
 6266		int cpu_number;
 6267
 6268		retval = fscanf(fp, " CPU%d", &cpu_number);
 6269		if (retval != 1)
 6270			break;
 6271
 6272		if (cpu_number > topo.max_cpu_num) {
 6273			warn("/proc/interrupts: cpu%d: > %d", cpu_number, topo.max_cpu_num);
 6274			return 1;
 6275		}
 6276
 6277		irq_column_2_cpu[column] = cpu_number;
 6278		irqs_per_cpu[cpu_number] = 0;
 6279		nmi_per_cpu[cpu_number] = 0;
 6280	}
 6281
 6282	/* read /proc/interrupt count lines and sum up irqs per cpu */
 6283	while (1) {
 6284		int column;
 6285		char buf[64];
 6286		int this_row_is_nmi = 0;
 6287
 6288		retval = fscanf(fp, " %s:", buf);	/* irq# "N:" */
 6289		if (retval != 1)
 6290			break;
 6291
 6292		if (strncmp(buf, "NMI", strlen("NMI")) == 0)
 6293			this_row_is_nmi = 1;
 6294
 6295		/* read the count per cpu */
 6296		for (column = 0; column < topo.num_cpus; ++column) {
 6297
 6298			int cpu_number, irq_count;
 6299
 6300			retval = fscanf(fp, " %d", &irq_count);
 6301
 6302			if (retval != 1)
 6303				break;
 6304
 6305			cpu_number = irq_column_2_cpu[column];
 6306			irqs_per_cpu[cpu_number] += irq_count;
 6307			if (this_row_is_nmi)
 6308				nmi_per_cpu[cpu_number] += irq_count;
 6309		}
 6310		while (getc(fp) != '\n') ;	/* flush interrupt description */
 6311
 6312	}
 6313	return 0;
 6314}
 6315
 6316/*
 6317 * snapshot_graphics()
 6318 *
 6319 * record snapshot of specified graphics sysfs knob
 6320 *
 6321 * return 1 if config change requires a restart, else return 0
 6322 */
 6323int snapshot_graphics(int idx)
 6324{
 6325	int retval;
 6326
 6327	rewind(gfx_info[idx].fp);
 6328	fflush(gfx_info[idx].fp);
 6329
 6330	switch (idx) {
 6331	case GFX_rc6:
 6332	case SAM_mc6:
 6333		retval = fscanf(gfx_info[idx].fp, "%lld", &gfx_info[idx].val_ull);
 6334		if (retval != 1)
 6335			err(1, "rc6");
 6336		return 0;
 6337	case GFX_MHz:
 6338	case GFX_ACTMHz:
 6339	case SAM_MHz:
 6340	case SAM_ACTMHz:
 6341		retval = fscanf(gfx_info[idx].fp, "%d", &gfx_info[idx].val);
 6342		if (retval != 1)
 6343			err(1, "MHz");
 6344		return 0;
 6345	default:
 6346		return -EINVAL;
 6347	}
 6348}
 6349
 6350/*
 6351 * snapshot_cpu_lpi()
 6352 *
 6353 * record snapshot of
 6354 * /sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us
 6355 */
 6356int snapshot_cpu_lpi_us(void)
 6357{
 6358	FILE *fp;
 6359	int retval;
 6360
 6361	fp = fopen_or_die("/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us", "r");
 6362
 6363	retval = fscanf(fp, "%lld", &cpuidle_cur_cpu_lpi_us);
 6364	if (retval != 1) {
 6365		fprintf(stderr, "Disabling Low Power Idle CPU output\n");
 6366		BIC_NOT_PRESENT(BIC_CPU_LPI);
 6367		fclose(fp);
 6368		return -1;
 6369	}
 6370
 6371	fclose(fp);
 6372
 6373	return 0;
 6374}
 6375
 6376/*
 6377 * snapshot_sys_lpi()
 6378 *
 6379 * record snapshot of sys_lpi_file
 6380 */
 6381int snapshot_sys_lpi_us(void)
 6382{
 6383	FILE *fp;
 6384	int retval;
 6385
 6386	fp = fopen_or_die(sys_lpi_file, "r");
 6387
 6388	retval = fscanf(fp, "%lld", &cpuidle_cur_sys_lpi_us);
 6389	if (retval != 1) {
 6390		fprintf(stderr, "Disabling Low Power Idle System output\n");
 6391		BIC_NOT_PRESENT(BIC_SYS_LPI);
 6392		fclose(fp);
 6393		return -1;
 6394	}
 6395	fclose(fp);
 6396
 6397	return 0;
 6398}
 6399
 6400/*
 6401 * snapshot /proc and /sys files
 6402 *
 6403 * return 1 if configuration restart needed, else return 0
 6404 */
 6405int snapshot_proc_sysfs_files(void)
 6406{
 6407	gettimeofday(&procsysfs_tv_begin, (struct timezone *)NULL);
 6408
 6409	if (DO_BIC(BIC_IRQ) || DO_BIC(BIC_NMI))
 6410		if (snapshot_proc_interrupts())
 6411			return 1;
 6412
 6413	if (DO_BIC(BIC_GFX_rc6))
 6414		snapshot_graphics(GFX_rc6);
 6415
 6416	if (DO_BIC(BIC_GFXMHz))
 6417		snapshot_graphics(GFX_MHz);
 6418
 6419	if (DO_BIC(BIC_GFXACTMHz))
 6420		snapshot_graphics(GFX_ACTMHz);
 6421
 6422	if (DO_BIC(BIC_SAM_mc6))
 6423		snapshot_graphics(SAM_mc6);
 6424
 6425	if (DO_BIC(BIC_SAMMHz))
 6426		snapshot_graphics(SAM_MHz);
 6427
 6428	if (DO_BIC(BIC_SAMACTMHz))
 6429		snapshot_graphics(SAM_ACTMHz);
 6430
 6431	if (DO_BIC(BIC_CPU_LPI))
 6432		snapshot_cpu_lpi_us();
 6433
 6434	if (DO_BIC(BIC_SYS_LPI))
 6435		snapshot_sys_lpi_us();
 6436
 6437	return 0;
 6438}
 6439
 6440int exit_requested;
 6441
 6442static void signal_handler(int signal)
 6443{
 6444	switch (signal) {
 6445	case SIGINT:
 6446		exit_requested = 1;
 6447		if (debug)
 6448			fprintf(stderr, " SIGINT\n");
 6449		break;
 6450	case SIGUSR1:
 6451		if (debug > 1)
 6452			fprintf(stderr, "SIGUSR1\n");
 6453		break;
 6454	}
 6455}
 6456
 6457void setup_signal_handler(void)
 6458{
 6459	struct sigaction sa;
 6460
 6461	memset(&sa, 0, sizeof(sa));
 6462
 6463	sa.sa_handler = &signal_handler;
 6464
 6465	if (sigaction(SIGINT, &sa, NULL) < 0)
 6466		err(1, "sigaction SIGINT");
 6467	if (sigaction(SIGUSR1, &sa, NULL) < 0)
 6468		err(1, "sigaction SIGUSR1");
 6469}
 6470
 6471void do_sleep(void)
 6472{
 6473	struct timeval tout;
 6474	struct timespec rest;
 6475	fd_set readfds;
 6476	int retval;
 6477
 6478	FD_ZERO(&readfds);
 6479	FD_SET(0, &readfds);
 6480
 6481	if (ignore_stdin) {
 6482		nanosleep(&interval_ts, NULL);
 6483		return;
 6484	}
 6485
 6486	tout = interval_tv;
 6487	retval = select(1, &readfds, NULL, NULL, &tout);
 6488
 6489	if (retval == 1) {
 6490		switch (getc(stdin)) {
 6491		case 'q':
 6492			exit_requested = 1;
 6493			break;
 6494		case EOF:
 6495			/*
 6496			 * 'stdin' is a pipe closed on the other end. There
 6497			 * won't be any further input.
 6498			 */
 6499			ignore_stdin = 1;
 6500			/* Sleep the rest of the time */
 6501			rest.tv_sec = (tout.tv_sec + tout.tv_usec / 1000000);
 6502			rest.tv_nsec = (tout.tv_usec % 1000000) * 1000;
 6503			nanosleep(&rest, NULL);
 6504		}
 6505	}
 6506}
 6507
 6508int get_msr_sum(int cpu, off_t offset, unsigned long long *msr)
 6509{
 6510	int ret, idx;
 6511	unsigned long long msr_cur, msr_last;
 6512
 6513	assert(!no_msr);
 6514
 6515	if (!per_cpu_msr_sum)
 6516		return 1;
 6517
 6518	idx = offset_to_idx(offset);
 6519	if (idx < 0)
 6520		return idx;
 6521	/* get_msr_sum() = sum + (get_msr() - last) */
 6522	ret = get_msr(cpu, offset, &msr_cur);
 6523	if (ret)
 6524		return ret;
 6525	msr_last = per_cpu_msr_sum[cpu].entries[idx].last;
 6526	DELTA_WRAP32(msr_cur, msr_last);
 6527	*msr = msr_last + per_cpu_msr_sum[cpu].entries[idx].sum;
 6528
 6529	return 0;
 6530}
 6531
 6532timer_t timerid;
 6533
 6534/* Timer callback, update the sum of MSRs periodically. */
 6535static int update_msr_sum(PER_THREAD_PARAMS)
 6536{
 6537	int i, ret;
 6538	int cpu = t->cpu_id;
 6539
 6540	UNUSED(c);
 6541	UNUSED(p);
 6542
 6543	assert(!no_msr);
 6544
 6545	for (i = IDX_PKG_ENERGY; i < IDX_COUNT; i++) {
 6546		unsigned long long msr_cur, msr_last;
 6547		off_t offset;
 6548
 6549		if (!idx_valid(i))
 6550			continue;
 6551		offset = idx_to_offset(i);
 6552		if (offset < 0)
 6553			continue;
 6554		ret = get_msr(cpu, offset, &msr_cur);
 6555		if (ret) {
 6556			fprintf(outf, "Can not update msr(0x%llx)\n", (unsigned long long)offset);
 6557			continue;
 6558		}
 6559
 6560		msr_last = per_cpu_msr_sum[cpu].entries[i].last;
 6561		per_cpu_msr_sum[cpu].entries[i].last = msr_cur & 0xffffffff;
 6562
 6563		DELTA_WRAP32(msr_cur, msr_last);
 6564		per_cpu_msr_sum[cpu].entries[i].sum += msr_last;
 6565	}
 6566	return 0;
 6567}
 6568
 6569static void msr_record_handler(union sigval v)
 6570{
 6571	UNUSED(v);
 6572
 6573	for_all_cpus(update_msr_sum, EVEN_COUNTERS);
 6574}
 6575
 6576void msr_sum_record(void)
 6577{
 6578	struct itimerspec its;
 6579	struct sigevent sev;
 6580
 6581	per_cpu_msr_sum = calloc(topo.max_cpu_num + 1, sizeof(struct msr_sum_array));
 6582	if (!per_cpu_msr_sum) {
 6583		fprintf(outf, "Can not allocate memory for long time MSR.\n");
 6584		return;
 6585	}
 6586	/*
 6587	 * Signal handler might be restricted, so use thread notifier instead.
 6588	 */
 6589	memset(&sev, 0, sizeof(struct sigevent));
 6590	sev.sigev_notify = SIGEV_THREAD;
 6591	sev.sigev_notify_function = msr_record_handler;
 6592
 6593	sev.sigev_value.sival_ptr = &timerid;
 6594	if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) {
 6595		fprintf(outf, "Can not create timer.\n");
 6596		goto release_msr;
 6597	}
 6598
 6599	its.it_value.tv_sec = 0;
 6600	its.it_value.tv_nsec = 1;
 6601	/*
 6602	 * A wraparound time has been calculated early.
 6603	 * Some sources state that the peak power for a
 6604	 * microprocessor is usually 1.5 times the TDP rating,
 6605	 * use 2 * TDP for safety.
 6606	 */
 6607	its.it_interval.tv_sec = rapl_joule_counter_range / 2;
 6608	its.it_interval.tv_nsec = 0;
 6609
 6610	if (timer_settime(timerid, 0, &its, NULL) == -1) {
 6611		fprintf(outf, "Can not set timer.\n");
 6612		goto release_timer;
 6613	}
 6614	return;
 6615
 6616release_timer:
 6617	timer_delete(timerid);
 6618release_msr:
 6619	free(per_cpu_msr_sum);
 6620	per_cpu_msr_sum = NULL;
 6621}
 6622
 6623/*
 6624 * set_my_sched_priority(pri)
 6625 * return previous priority on success
 6626 * return value < -20 on failure
 6627 */
 6628int set_my_sched_priority(int priority)
 6629{
 6630	int retval;
 6631	int original_priority;
 6632
 6633	errno = 0;
 6634	original_priority = getpriority(PRIO_PROCESS, 0);
 6635	if (errno && (original_priority == -1))
 6636		return -21;
 6637
 6638	retval = setpriority(PRIO_PROCESS, 0, priority);
 6639	if (retval)
 6640		return -21;
 6641
 6642	errno = 0;
 6643	retval = getpriority(PRIO_PROCESS, 0);
 6644	if (retval != priority)
 6645		return -21;
 6646
 6647	return original_priority;
 6648}
 6649
 6650void turbostat_loop()
 6651{
 6652	int retval;
 6653	int restarted = 0;
 6654	unsigned int done_iters = 0;
 6655
 6656	setup_signal_handler();
 6657
 6658	/*
 6659	 * elevate own priority for interval mode
 6660	 *
 6661	 * ignore on error - we probably don't have permission to set it, but
 6662	 * it's not a big deal
 6663	 */
 6664	set_my_sched_priority(-20);
 6665
 6666restart:
 6667	restarted++;
 6668
 6669	snapshot_proc_sysfs_files();
 6670	retval = for_all_cpus(get_counters, EVEN_COUNTERS);
 6671	first_counter_read = 0;
 6672	if (retval < -1) {
 6673		exit(retval);
 6674	} else if (retval == -1) {
 6675		if (restarted > 10) {
 6676			exit(retval);
 6677		}
 6678		re_initialize();
 6679		goto restart;
 6680	}
 6681	restarted = 0;
 6682	done_iters = 0;
 6683	gettimeofday(&tv_even, (struct timezone *)NULL);
 6684
 6685	while (1) {
 6686		if (for_all_proc_cpus(cpu_is_not_present)) {
 6687			re_initialize();
 6688			goto restart;
 6689		}
 6690		if (update_effective_str(false)) {
 6691			re_initialize();
 6692			goto restart;
 6693		}
 6694		do_sleep();
 6695		if (snapshot_proc_sysfs_files())
 6696			goto restart;
 6697		retval = for_all_cpus(get_counters, ODD_COUNTERS);
 6698		if (retval < -1) {
 6699			exit(retval);
 6700		} else if (retval == -1) {
 6701			re_initialize();
 6702			goto restart;
 6703		}
 6704		gettimeofday(&tv_odd, (struct timezone *)NULL);
 6705		timersub(&tv_odd, &tv_even, &tv_delta);
 6706		if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS)) {
 6707			re_initialize();
 6708			goto restart;
 6709		}
 6710		delta_platform(&platform_counters_odd, &platform_counters_even);
 6711		compute_average(EVEN_COUNTERS);
 6712		format_all_counters(EVEN_COUNTERS);
 6713		flush_output_stdout();
 6714		if (exit_requested)
 6715			break;
 6716		if (num_iterations && ++done_iters >= num_iterations)
 6717			break;
 6718		do_sleep();
 6719		if (snapshot_proc_sysfs_files())
 6720			goto restart;
 6721		retval = for_all_cpus(get_counters, EVEN_COUNTERS);
 6722		if (retval < -1) {
 6723			exit(retval);
 6724		} else if (retval == -1) {
 6725			re_initialize();
 6726			goto restart;
 6727		}
 6728		gettimeofday(&tv_even, (struct timezone *)NULL);
 6729		timersub(&tv_even, &tv_odd, &tv_delta);
 6730		if (for_all_cpus_2(delta_cpu, EVEN_COUNTERS, ODD_COUNTERS)) {
 6731			re_initialize();
 6732			goto restart;
 6733		}
 6734		delta_platform(&platform_counters_even, &platform_counters_odd);
 6735		compute_average(ODD_COUNTERS);
 6736		format_all_counters(ODD_COUNTERS);
 6737		flush_output_stdout();
 6738		if (exit_requested)
 6739			break;
 6740		if (num_iterations && ++done_iters >= num_iterations)
 6741			break;
 6742	}
 6743}
 6744
 6745int probe_dev_msr(void)
 6746{
 6747	struct stat sb;
 6748	char pathname[32];
 6749
 6750	sprintf(pathname, "/dev/msr%d", base_cpu);
 6751	return !stat(pathname, &sb);
 6752}
 6753
 6754int probe_dev_cpu_msr(void)
 6755{
 6756	struct stat sb;
 6757	char pathname[32];
 6758
 6759	sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
 6760	return !stat(pathname, &sb);
 6761}
 6762
 6763int probe_msr_driver(void)
 6764{
 6765	if (probe_dev_msr()) {
 6766		use_android_msr_path = 1;
 6767		return 1;
 6768	}
 6769	return probe_dev_cpu_msr();
 6770}
 6771
 6772void check_msr_driver(void)
 6773{
 6774	if (probe_msr_driver())
 6775		return;
 6776
 6777	if (system("/sbin/modprobe msr > /dev/null 2>&1"))
 6778		no_msr = 1;
 6779
 6780	if (!probe_msr_driver())
 6781		no_msr = 1;
 6782}
 6783
 6784/*
 6785 * check for CAP_SYS_RAWIO
 6786 * return 0 on success
 6787 * return 1 on fail
 6788 */
 6789int check_for_cap_sys_rawio(void)
 6790{
 6791	cap_t caps;
 6792	cap_flag_value_t cap_flag_value;
 6793	int ret = 0;
 6794
 6795	caps = cap_get_proc();
 6796	if (caps == NULL) {
 6797		/*
 6798		 * CONFIG_MULTIUSER=n kernels have no cap_get_proc()
 6799		 * Allow them to continue and attempt to access MSRs
 6800		 */
 6801		if (errno == ENOSYS)
 6802			return 0;
 6803
 6804		return 1;
 6805	}
 6806
 6807	if (cap_get_flag(caps, CAP_SYS_RAWIO, CAP_EFFECTIVE, &cap_flag_value)) {
 6808		ret = 1;
 6809		goto free_and_exit;
 6810	}
 6811
 6812	if (cap_flag_value != CAP_SET) {
 6813		ret = 1;
 6814		goto free_and_exit;
 6815	}
 6816
 6817free_and_exit:
 6818	if (cap_free(caps) == -1)
 6819		err(-6, "cap_free\n");
 6820
 6821	return ret;
 6822}
 6823
 6824void check_msr_permission(void)
 6825{
 6826	int failed = 0;
 6827	char pathname[32];
 6828
 6829	if (no_msr)
 6830		return;
 6831
 6832	/* check for CAP_SYS_RAWIO */
 6833	failed += check_for_cap_sys_rawio();
 6834
 6835	/* test file permissions */
 6836	sprintf(pathname, use_android_msr_path ? "/dev/msr%d" : "/dev/cpu/%d/msr", base_cpu);
 6837	if (euidaccess(pathname, R_OK)) {
 6838		failed++;
 6839	}
 6840
 6841	if (failed) {
 6842		warnx("Failed to access %s. Some of the counters may not be available\n"
 6843		      "\tRun as root to enable them or use %s to disable the access explicitly", pathname, "--no-msr");
 6844		no_msr = 1;
 6845	}
 6846}
 6847
 6848void probe_bclk(void)
 6849{
 6850	unsigned long long msr;
 6851	unsigned int base_ratio;
 6852
 6853	if (!platform->has_nhm_msrs || no_msr)
 6854		return;
 6855
 6856	if (platform->bclk_freq == BCLK_100MHZ)
 6857		bclk = 100.00;
 6858	else if (platform->bclk_freq == BCLK_133MHZ)
 6859		bclk = 133.33;
 6860	else if (platform->bclk_freq == BCLK_SLV)
 6861		bclk = slm_bclk();
 6862	else
 6863		return;
 6864
 6865	get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
 6866	base_ratio = (msr >> 8) & 0xFF;
 6867
 6868	base_hz = base_ratio * bclk * 1000000;
 6869	has_base_hz = 1;
 6870
 6871	if (platform->enable_tsc_tweak)
 6872		tsc_tweak = base_hz / tsc_hz;
 6873}
 6874
 6875static void remove_underbar(char *s)
 6876{
 6877	char *to = s;
 6878
 6879	while (*s) {
 6880		if (*s != '_')
 6881			*to++ = *s;
 6882		s++;
 6883	}
 6884
 6885	*to = 0;
 6886}
 6887
 6888static void dump_turbo_ratio_info(void)
 6889{
 6890	if (!has_turbo)
 6891		return;
 6892
 6893	if (!platform->has_nhm_msrs || no_msr)
 6894		return;
 6895
 6896	if (platform->trl_msrs & TRL_LIMIT2)
 6897		dump_turbo_ratio_limit2();
 6898
 6899	if (platform->trl_msrs & TRL_LIMIT1)
 6900		dump_turbo_ratio_limit1();
 6901
 6902	if (platform->trl_msrs & TRL_BASE) {
 6903		dump_turbo_ratio_limits(MSR_TURBO_RATIO_LIMIT);
 6904
 6905		if (is_hybrid)
 6906			dump_turbo_ratio_limits(MSR_SECONDARY_TURBO_RATIO_LIMIT);
 6907	}
 6908
 6909	if (platform->trl_msrs & TRL_ATOM)
 6910		dump_atom_turbo_ratio_limits();
 6911
 6912	if (platform->trl_msrs & TRL_KNL)
 6913		dump_knl_turbo_ratio_limits();
 6914
 6915	if (platform->has_config_tdp)
 6916		dump_config_tdp();
 6917}
 6918
 6919static int read_sysfs_int(char *path)
 6920{
 6921	FILE *input;
 6922	int retval = -1;
 6923
 6924	input = fopen(path, "r");
 6925	if (input == NULL) {
 6926		if (debug)
 6927			fprintf(outf, "NSFOD %s\n", path);
 6928		return (-1);
 6929	}
 6930	if (fscanf(input, "%d", &retval) != 1)
 6931		err(1, "%s: failed to read int from file", path);
 6932	fclose(input);
 6933
 6934	return (retval);
 6935}
 6936
 6937static void dump_sysfs_file(char *path)
 6938{
 6939	FILE *input;
 6940	char cpuidle_buf[64];
 6941
 6942	input = fopen(path, "r");
 6943	if (input == NULL) {
 6944		if (debug)
 6945			fprintf(outf, "NSFOD %s\n", path);
 6946		return;
 6947	}
 6948	if (!fgets(cpuidle_buf, sizeof(cpuidle_buf), input))
 6949		err(1, "%s: failed to read file", path);
 6950	fclose(input);
 6951
 6952	fprintf(outf, "%s: %s", strrchr(path, '/') + 1, cpuidle_buf);
 6953}
 6954
 6955static void probe_intel_uncore_frequency_legacy(void)
 6956{
 6957	int i, j;
 6958	char path[256];
 6959
 6960	for (i = 0; i < topo.num_packages; ++i) {
 6961		for (j = 0; j <= topo.max_die_id; ++j) {
 6962			int k, l;
 6963			char path_base[128];
 6964
 6965			sprintf(path_base, "/sys/devices/system/cpu/intel_uncore_frequency/package_%02d_die_%02d", i, j);
 6966
 6967			sprintf(path, "%s/current_freq_khz", path_base);
 6968			if (access(path, R_OK))
 6969				continue;
 6970
 6971			BIC_PRESENT(BIC_UNCORE_MHZ);
 6972
 6973			if (quiet)
 6974				return;
 6975
 6976			sprintf(path, "%s/min_freq_khz", path_base);
 6977			k = read_sysfs_int(path);
 6978			sprintf(path, "%s/max_freq_khz", path_base);
 6979			l = read_sysfs_int(path);
 6980			fprintf(outf, "Uncore Frequency package%d die%d: %d - %d MHz ", i, j, k / 1000, l / 1000);
 6981
 6982			sprintf(path, "%s/initial_min_freq_khz", path_base);
 6983			k = read_sysfs_int(path);
 6984			sprintf(path, "%s/initial_max_freq_khz", path_base);
 6985			l = read_sysfs_int(path);
 6986			fprintf(outf, "(%d - %d MHz)", k / 1000, l / 1000);
 6987
 6988			sprintf(path, "%s/current_freq_khz", path_base);
 6989			k = read_sysfs_int(path);
 6990			fprintf(outf, " %d MHz\n", k / 1000);
 6991		}
 6992	}
 6993}
 6994
 6995static void probe_intel_uncore_frequency_cluster(void)
 6996{
 6997	int i, uncore_max_id;
 6998	char path[256];
 6999	char path_base[128];
 7000
 7001	if (access("/sys/devices/system/cpu/intel_uncore_frequency/uncore00/current_freq_khz", R_OK))
 7002		return;
 7003
 7004	for (uncore_max_id = 0;; ++uncore_max_id) {
 7005
 7006		sprintf(path_base, "/sys/devices/system/cpu/intel_uncore_frequency/uncore%02d", uncore_max_id);
 7007
 7008		/* uncore## start at 00 and skips no numbers, so stop upon first missing */
 7009		if (access(path_base, R_OK)) {
 7010			uncore_max_id -= 1;
 7011			break;
 7012		}
 7013	}
 7014	for (i = uncore_max_id; i >= 0; --i) {
 7015		int k, l;
 7016		int package_id, domain_id, cluster_id;
 7017		char name_buf[16];
 7018
 7019		sprintf(path_base, "/sys/devices/system/cpu/intel_uncore_frequency/uncore%02d", i);
 7020
 7021		if (access(path_base, R_OK))
 7022			err(1, "%s: %s\n", __func__, path_base);
 7023
 7024		sprintf(path, "%s/package_id", path_base);
 7025		package_id = read_sysfs_int(path);
 7026
 7027		sprintf(path, "%s/domain_id", path_base);
 7028		domain_id = read_sysfs_int(path);
 7029
 7030		sprintf(path, "%s/fabric_cluster_id", path_base);
 7031		cluster_id = read_sysfs_int(path);
 7032
 7033		sprintf(path, "%s/current_freq_khz", path_base);
 7034		sprintf(name_buf, "UMHz%d.%d", domain_id, cluster_id);
 7035
 7036		/*
 7037		 * Once add_couter() is called, that counter is always read
 7038		 * and reported -- So it is effectively (enabled & present).
 7039		 * Only call add_counter() here if legacy BIC_UNCORE_MHZ (UncMHz)
 7040		 * is (enabled).  Since we are in this routine, we
 7041		 * know we will not probe and set (present) the legacy counter.
 7042		 *
 7043		 * This allows "--show/--hide UncMHz" to be effective for
 7044		 * the clustered MHz counters, as a group.
 7045		 */
 7046		if BIC_IS_ENABLED
 7047			(BIC_UNCORE_MHZ)
 7048			    add_counter(0, path, name_buf, 0, SCOPE_PACKAGE, COUNTER_K2M, FORMAT_AVERAGE, 0, package_id);
 7049
 7050		if (quiet)
 7051			continue;
 7052
 7053		sprintf(path, "%s/min_freq_khz", path_base);
 7054		k = read_sysfs_int(path);
 7055		sprintf(path, "%s/max_freq_khz", path_base);
 7056		l = read_sysfs_int(path);
 7057		fprintf(outf, "Uncore Frequency package%d domain%d cluster%d: %d - %d MHz ", package_id, domain_id, cluster_id, k / 1000, l / 1000);
 7058
 7059		sprintf(path, "%s/initial_min_freq_khz", path_base);
 7060		k = read_sysfs_int(path);
 7061		sprintf(path, "%s/initial_max_freq_khz", path_base);
 7062		l = read_sysfs_int(path);
 7063		fprintf(outf, "(%d - %d MHz)", k / 1000, l / 1000);
 7064
 7065		sprintf(path, "%s/current_freq_khz", path_base);
 7066		k = read_sysfs_int(path);
 7067		fprintf(outf, " %d MHz\n", k / 1000);
 7068	}
 7069}
 7070
 7071static void probe_intel_uncore_frequency(void)
 7072{
 7073	if (!genuine_intel)
 7074		return;
 7075
 7076	if (access("/sys/devices/system/cpu/intel_uncore_frequency/uncore00", R_OK) == 0)
 7077		probe_intel_uncore_frequency_cluster();
 7078	else
 7079		probe_intel_uncore_frequency_legacy();
 7080}
 7081
 7082static void set_graphics_fp(char *path, int idx)
 7083{
 7084	if (!access(path, R_OK))
 7085		gfx_info[idx].fp = fopen_or_die(path, "r");
 7086}
 7087
 7088/* Enlarge this if there are /sys/class/drm/card2 ... */
 7089#define GFX_MAX_CARDS	2
 7090
 7091static void probe_graphics(void)
 7092{
 7093	char path[PATH_MAX];
 7094	int i;
 7095
 7096	/* Xe graphics sysfs knobs */
 7097	if (!access("/sys/class/drm/card0/device/tile0/gt0/gtidle/idle_residency_ms", R_OK)) {
 7098		FILE *fp;
 7099		char buf[8];
 7100		bool gt0_is_gt;
 7101
 7102		fp = fopen("/sys/class/drm/card0/device/tile0/gt0/gtidle/name", "r");
 7103		if (!fp)
 7104			goto next;
 7105
 7106		if (!fread(buf, sizeof(char), 7, fp)) {
 7107			fclose(fp);
 7108			goto next;
 7109		}
 7110		fclose(fp);
 7111
 7112		if (!strncmp(buf, "gt0-rc", strlen("gt0-rc")))
 7113			gt0_is_gt = true;
 7114		else if (!strncmp(buf, "gt0-mc", strlen("gt0-mc")))
 7115			gt0_is_gt = false;
 7116		else
 7117			goto next;
 7118
 7119		set_graphics_fp("/sys/class/drm/card0/device/tile0/gt0/gtidle/idle_residency_ms", gt0_is_gt ? GFX_rc6 : SAM_mc6);
 7120
 7121		set_graphics_fp("/sys/class/drm/card0/device/tile0/gt0/freq0/cur_freq", gt0_is_gt ? GFX_MHz : SAM_MHz);
 7122
 7123		set_graphics_fp("/sys/class/drm/card0/device/tile0/gt0/freq0/act_freq", gt0_is_gt ? GFX_ACTMHz : SAM_ACTMHz);
 7124
 7125		set_graphics_fp("/sys/class/drm/card0/device/tile0/gt1/gtidle/idle_residency_ms", gt0_is_gt ? SAM_mc6 : GFX_rc6);
 7126
 7127		set_graphics_fp("/sys/class/drm/card0/device/tile0/gt1/freq0/cur_freq", gt0_is_gt ? SAM_MHz : GFX_MHz);
 7128
 7129		set_graphics_fp("/sys/class/drm/card0/device/tile0/gt1/freq0/act_freq", gt0_is_gt ? SAM_ACTMHz : GFX_ACTMHz);
 7130
 7131		goto end;
 7132	}
 7133
 7134next:
 7135	/* New i915 graphics sysfs knobs */
 7136	for (i = 0; i < GFX_MAX_CARDS; i++) {
 7137		snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt0/rc6_residency_ms", i);
 7138		if (!access(path, R_OK))
 7139			break;
 7140	}
 7141
 7142	if (i == GFX_MAX_CARDS)
 7143		goto legacy_i915;
 7144
 7145	snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt0/rc6_residency_ms", i);
 7146	set_graphics_fp(path, GFX_rc6);
 7147
 7148	snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt0/rps_cur_freq_mhz", i);
 7149	set_graphics_fp(path, GFX_MHz);
 7150
 7151	snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt0/rps_act_freq_mhz", i);
 7152	set_graphics_fp(path, GFX_ACTMHz);
 7153
 7154	snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt1/rc6_residency_ms", i);
 7155	set_graphics_fp(path, SAM_mc6);
 7156
 7157	snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt1/rps_cur_freq_mhz", i);
 7158	set_graphics_fp(path, SAM_MHz);
 7159
 7160	snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt1/rps_act_freq_mhz", i);
 7161	set_graphics_fp(path, SAM_ACTMHz);
 7162
 7163	goto end;
 7164
 7165legacy_i915:
 7166	/* Fall back to traditional i915 graphics sysfs knobs */
 7167	set_graphics_fp("/sys/class/drm/card0/power/rc6_residency_ms", GFX_rc6);
 7168
 7169	set_graphics_fp("/sys/class/drm/card0/gt_cur_freq_mhz", GFX_MHz);
 7170	if (!gfx_info[GFX_MHz].fp)
 7171		set_graphics_fp("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", GFX_MHz);
 7172
 7173	set_graphics_fp("/sys/class/drm/card0/gt_act_freq_mhz", GFX_ACTMHz);
 7174	if (!gfx_info[GFX_ACTMHz].fp)
 7175		set_graphics_fp("/sys/class/graphics/fb0/device/drm/card0/gt_act_freq_mhz", GFX_ACTMHz);
 7176
 7177end:
 7178	if (gfx_info[GFX_rc6].fp)
 7179		BIC_PRESENT(BIC_GFX_rc6);
 7180	if (gfx_info[GFX_MHz].fp)
 7181		BIC_PRESENT(BIC_GFXMHz);
 7182	if (gfx_info[GFX_ACTMHz].fp)
 7183		BIC_PRESENT(BIC_GFXACTMHz);
 7184	if (gfx_info[SAM_mc6].fp)
 7185		BIC_PRESENT(BIC_SAM_mc6);
 7186	if (gfx_info[SAM_MHz].fp)
 7187		BIC_PRESENT(BIC_SAMMHz);
 7188	if (gfx_info[SAM_ACTMHz].fp)
 7189		BIC_PRESENT(BIC_SAMACTMHz);
 7190}
 7191
 7192static void dump_sysfs_cstate_config(void)
 7193{
 7194	char path[64];
 7195	char name_buf[16];
 7196	char desc[64];
 7197	FILE *input;
 7198	int state;
 7199	char *sp;
 7200
 7201	if (access("/sys/devices/system/cpu/cpuidle", R_OK)) {
 7202		fprintf(outf, "cpuidle not loaded\n");
 7203		return;
 7204	}
 7205
 7206	dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_driver");
 7207	dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_governor");
 7208	dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_governor_ro");
 7209
 7210	for (state = 0; state < 10; ++state) {
 7211
 7212		sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", base_cpu, state);
 7213		input = fopen(path, "r");
 7214		if (input == NULL)
 7215			continue;
 7216		if (!fgets(name_buf, sizeof(name_buf), input))
 7217			err(1, "%s: failed to read file", path);
 7218
 7219		/* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
 7220		sp = strchr(name_buf, '-');
 7221		if (!sp)
 7222			sp = strchrnul(name_buf, '\n');
 7223		*sp = '\0';
 7224		fclose(input);
 7225
 7226		remove_underbar(name_buf);
 7227
 7228		sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/desc", base_cpu, state);
 7229		input = fopen(path, "r");
 7230		if (input == NULL)
 7231			continue;
 7232		if (!fgets(desc, sizeof(desc), input))
 7233			err(1, "%s: failed to read file", path);
 7234
 7235		fprintf(outf, "cpu%d: %s: %s", base_cpu, name_buf, desc);
 7236		fclose(input);
 7237	}
 7238}
 7239
 7240static void dump_sysfs_pstate_config(void)
 7241{
 7242	char path[64];
 7243	char driver_buf[64];
 7244	char governor_buf[64];
 7245	FILE *input;
 7246	int turbo;
 7247
 7248	sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_driver", base_cpu);
 7249	input = fopen(path, "r");
 7250	if (input == NULL) {
 7251		fprintf(outf, "NSFOD %s\n", path);
 7252		return;
 7253	}
 7254	if (!fgets(driver_buf, sizeof(driver_buf), input))
 7255		err(1, "%s: failed to read file", path);
 7256	fclose(input);
 7257
 7258	sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", base_cpu);
 7259	input = fopen(path, "r");
 7260	if (input == NULL) {
 7261		fprintf(outf, "NSFOD %s\n", path);
 7262		return;
 7263	}
 7264	if (!fgets(governor_buf, sizeof(governor_buf), input))
 7265		err(1, "%s: failed to read file", path);
 7266	fclose(input);
 7267
 7268	fprintf(outf, "cpu%d: cpufreq driver: %s", base_cpu, driver_buf);
 7269	fprintf(outf, "cpu%d: cpufreq governor: %s", base_cpu, governor_buf);
 7270
 7271	sprintf(path, "/sys/devices/system/cpu/cpufreq/boost");
 7272	input = fopen(path, "r");
 7273	if (input != NULL) {
 7274		if (fscanf(input, "%d", &turbo) != 1)
 7275			err(1, "%s: failed to parse number from file", path);
 7276		fprintf(outf, "cpufreq boost: %d\n", turbo);
 7277		fclose(input);
 7278	}
 7279
 7280	sprintf(path, "/sys/devices/system/cpu/intel_pstate/no_turbo");
 7281	input = fopen(path, "r");
 7282	if (input != NULL) {
 7283		if (fscanf(input, "%d", &turbo) != 1)
 7284			err(1, "%s: failed to parse number from file", path);
 7285		fprintf(outf, "cpufreq intel_pstate no_turbo: %d\n", turbo);
 7286		fclose(input);
 7287	}
 7288}
 7289
 7290/*
 7291 * print_epb()
 7292 * Decode the ENERGY_PERF_BIAS MSR
 7293 */
 7294int print_epb(PER_THREAD_PARAMS)
 7295{
 7296	char *epb_string;
 7297	int cpu, epb;
 7298
 7299	UNUSED(c);
 7300	UNUSED(p);
 7301
 7302	if (!has_epb)
 7303		return 0;
 7304
 7305	cpu = t->cpu_id;
 7306
 7307	/* EPB is per-package */
 7308	if (!is_cpu_first_thread_in_package(t, c, p))
 7309		return 0;
 7310
 7311	if (cpu_migrate(cpu)) {
 7312		fprintf(outf, "print_epb: Could not migrate to CPU %d\n", cpu);
 7313		return -1;
 7314	}
 7315
 7316	epb = get_epb(cpu);
 7317	if (epb < 0)
 7318		return 0;
 7319
 7320	switch (epb) {
 7321	case ENERGY_PERF_BIAS_PERFORMANCE:
 7322		epb_string = "performance";
 7323		break;
 7324	case ENERGY_PERF_BIAS_NORMAL:
 7325		epb_string = "balanced";
 7326		break;
 7327	case ENERGY_PERF_BIAS_POWERSAVE:
 7328		epb_string = "powersave";
 7329		break;
 7330	default:
 7331		epb_string = "custom";
 7332		break;
 7333	}
 7334	fprintf(outf, "cpu%d: EPB: %d (%s)\n", cpu, epb, epb_string);
 7335
 7336	return 0;
 7337}
 7338
 7339/*
 7340 * print_hwp()
 7341 * Decode the MSR_HWP_CAPABILITIES
 7342 */
 7343int print_hwp(PER_THREAD_PARAMS)
 7344{
 7345	unsigned long long msr;
 7346	int cpu;
 7347
 7348	UNUSED(c);
 7349	UNUSED(p);
 7350
 7351	if (no_msr)
 7352		return 0;
 7353
 7354	if (!has_hwp)
 7355		return 0;
 7356
 7357	cpu = t->cpu_id;
 7358
 7359	/* MSR_HWP_CAPABILITIES is per-package */
 7360	if (!is_cpu_first_thread_in_package(t, c, p))
 7361		return 0;
 7362
 7363	if (cpu_migrate(cpu)) {
 7364		fprintf(outf, "print_hwp: Could not migrate to CPU %d\n", cpu);
 7365		return -1;
 7366	}
 7367
 7368	if (get_msr(cpu, MSR_PM_ENABLE, &msr))
 7369		return 0;
 7370
 7371	fprintf(outf, "cpu%d: MSR_PM_ENABLE: 0x%08llx (%sHWP)\n", cpu, msr, (msr & (1 << 0)) ? "" : "No-");
 7372
 7373	/* MSR_PM_ENABLE[1] == 1 if HWP is enabled and MSRs visible */
 7374	if ((msr & (1 << 0)) == 0)
 7375		return 0;
 7376
 7377	if (get_msr(cpu, MSR_HWP_CAPABILITIES, &msr))
 7378		return 0;
 7379
 7380	fprintf(outf, "cpu%d: MSR_HWP_CAPABILITIES: 0x%08llx "
 7381		"(high %d guar %d eff %d low %d)\n",
 7382		cpu, msr,
 7383		(unsigned int)HWP_HIGHEST_PERF(msr),
 7384		(unsigned int)HWP_GUARANTEED_PERF(msr), (unsigned int)HWP_MOSTEFFICIENT_PERF(msr), (unsigned int)HWP_LOWEST_PERF(msr));
 7385
 7386	if (get_msr(cpu, MSR_HWP_REQUEST, &msr))
 7387		return 0;
 7388
 7389	fprintf(outf, "cpu%d: MSR_HWP_REQUEST: 0x%08llx "
 7390		"(min %d max %d des %d epp 0x%x window 0x%x pkg 0x%x)\n",
 7391		cpu, msr,
 7392		(unsigned int)(((msr) >> 0) & 0xff),
 7393		(unsigned int)(((msr) >> 8) & 0xff),
 7394		(unsigned int)(((msr) >> 16) & 0xff),
 7395		(unsigned int)(((msr) >> 24) & 0xff), (unsigned int)(((msr) >> 32) & 0xff3), (unsigned int)(((msr) >> 42) & 0x1));
 7396
 7397	if (has_hwp_pkg) {
 7398		if (get_msr(cpu, MSR_HWP_REQUEST_PKG, &msr))
 7399			return 0;
 7400
 7401		fprintf(outf, "cpu%d: MSR_HWP_REQUEST_PKG: 0x%08llx "
 7402			"(min %d max %d des %d epp 0x%x window 0x%x)\n",
 7403			cpu, msr,
 7404			(unsigned int)(((msr) >> 0) & 0xff),
 7405			(unsigned int)(((msr) >> 8) & 0xff),
 7406			(unsigned int)(((msr) >> 16) & 0xff), (unsigned int)(((msr) >> 24) & 0xff), (unsigned int)(((msr) >> 32) & 0xff3));
 7407	}
 7408	if (has_hwp_notify) {
 7409		if (get_msr(cpu, MSR_HWP_INTERRUPT, &msr))
 7410			return 0;
 7411
 7412		fprintf(outf, "cpu%d: MSR_HWP_INTERRUPT: 0x%08llx "
 7413			"(%s_Guaranteed_Perf_Change, %s_Excursion_Min)\n", cpu, msr, ((msr) & 0x1) ? "EN" : "Dis", ((msr) & 0x2) ? "EN" : "Dis");
 7414	}
 7415	if (get_msr(cpu, MSR_HWP_STATUS, &msr))
 7416		return 0;
 7417
 7418	fprintf(outf, "cpu%d: MSR_HWP_STATUS: 0x%08llx "
 7419		"(%sGuaranteed_Perf_Change, %sExcursion_Min)\n", cpu, msr, ((msr) & 0x1) ? "" : "No-", ((msr) & 0x4) ? "" : "No-");
 7420
 7421	return 0;
 7422}
 7423
 7424/*
 7425 * print_perf_limit()
 7426 */
 7427int print_perf_limit(PER_THREAD_PARAMS)
 7428{
 7429	unsigned long long msr;
 7430	int cpu;
 7431
 7432	UNUSED(c);
 7433	UNUSED(p);
 7434
 7435	if (no_msr)
 7436		return 0;
 7437
 7438	cpu = t->cpu_id;
 7439
 7440	/* per-package */
 7441	if (!is_cpu_first_thread_in_package(t, c, p))
 7442		return 0;
 7443
 7444	if (cpu_migrate(cpu)) {
 7445		fprintf(outf, "print_perf_limit: Could not migrate to CPU %d\n", cpu);
 7446		return -1;
 7447	}
 7448
 7449	if (platform->plr_msrs & PLR_CORE) {
 7450		get_msr(cpu, MSR_CORE_PERF_LIMIT_REASONS, &msr);
 7451		fprintf(outf, "cpu%d: MSR_CORE_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
 7452		fprintf(outf, " (Active: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)",
 7453			(msr & 1 << 15) ? "bit15, " : "",
 7454			(msr & 1 << 14) ? "bit14, " : "",
 7455			(msr & 1 << 13) ? "Transitions, " : "",
 7456			(msr & 1 << 12) ? "MultiCoreTurbo, " : "",
 7457			(msr & 1 << 11) ? "PkgPwrL2, " : "",
 7458			(msr & 1 << 10) ? "PkgPwrL1, " : "",
 7459			(msr & 1 << 9) ? "CorePwr, " : "",
 7460			(msr & 1 << 8) ? "Amps, " : "",
 7461			(msr & 1 << 6) ? "VR-Therm, " : "",
 7462			(msr & 1 << 5) ? "Auto-HWP, " : "",
 7463			(msr & 1 << 4) ? "Graphics, " : "",
 7464			(msr & 1 << 2) ? "bit2, " : "", (msr & 1 << 1) ? "ThermStatus, " : "", (msr & 1 << 0) ? "PROCHOT, " : "");
 7465		fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n",
 7466			(msr & 1 << 31) ? "bit31, " : "",
 7467			(msr & 1 << 30) ? "bit30, " : "",
 7468			(msr & 1 << 29) ? "Transitions, " : "",
 7469			(msr & 1 << 28) ? "MultiCoreTurbo, " : "",
 7470			(msr & 1 << 27) ? "PkgPwrL2, " : "",
 7471			(msr & 1 << 26) ? "PkgPwrL1, " : "",
 7472			(msr & 1 << 25) ? "CorePwr, " : "",
 7473			(msr & 1 << 24) ? "Amps, " : "",
 7474			(msr & 1 << 22) ? "VR-Therm, " : "",
 7475			(msr & 1 << 21) ? "Auto-HWP, " : "",
 7476			(msr & 1 << 20) ? "Graphics, " : "",
 7477			(msr & 1 << 18) ? "bit18, " : "", (msr & 1 << 17) ? "ThermStatus, " : "", (msr & 1 << 16) ? "PROCHOT, " : "");
 7478
 7479	}
 7480	if (platform->plr_msrs & PLR_GFX) {
 7481		get_msr(cpu, MSR_GFX_PERF_LIMIT_REASONS, &msr);
 7482		fprintf(outf, "cpu%d: MSR_GFX_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
 7483		fprintf(outf, " (Active: %s%s%s%s%s%s%s%s)",
 7484			(msr & 1 << 0) ? "PROCHOT, " : "",
 7485			(msr & 1 << 1) ? "ThermStatus, " : "",
 7486			(msr & 1 << 4) ? "Graphics, " : "",
 7487			(msr & 1 << 6) ? "VR-Therm, " : "",
 7488			(msr & 1 << 8) ? "Amps, " : "",
 7489			(msr & 1 << 9) ? "GFXPwr, " : "", (msr & 1 << 10) ? "PkgPwrL1, " : "", (msr & 1 << 11) ? "PkgPwrL2, " : "");
 7490		fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s)\n",
 7491			(msr & 1 << 16) ? "PROCHOT, " : "",
 7492			(msr & 1 << 17) ? "ThermStatus, " : "",
 7493			(msr & 1 << 20) ? "Graphics, " : "",
 7494			(msr & 1 << 22) ? "VR-Therm, " : "",
 7495			(msr & 1 << 24) ? "Amps, " : "",
 7496			(msr & 1 << 25) ? "GFXPwr, " : "", (msr & 1 << 26) ? "PkgPwrL1, " : "", (msr & 1 << 27) ? "PkgPwrL2, " : "");
 7497	}
 7498	if (platform->plr_msrs & PLR_RING) {
 7499		get_msr(cpu, MSR_RING_PERF_LIMIT_REASONS, &msr);
 7500		fprintf(outf, "cpu%d: MSR_RING_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
 7501		fprintf(outf, " (Active: %s%s%s%s%s%s)",
 7502			(msr & 1 << 0) ? "PROCHOT, " : "",
 7503			(msr & 1 << 1) ? "ThermStatus, " : "",
 7504			(msr & 1 << 6) ? "VR-Therm, " : "",
 7505			(msr & 1 << 8) ? "Amps, " : "", (msr & 1 << 10) ? "PkgPwrL1, " : "", (msr & 1 << 11) ? "PkgPwrL2, " : "");
 7506		fprintf(outf, " (Logged: %s%s%s%s%s%s)\n",
 7507			(msr & 1 << 16) ? "PROCHOT, " : "",
 7508			(msr & 1 << 17) ? "ThermStatus, " : "",
 7509			(msr & 1 << 22) ? "VR-Therm, " : "",
 7510			(msr & 1 << 24) ? "Amps, " : "", (msr & 1 << 26) ? "PkgPwrL1, " : "", (msr & 1 << 27) ? "PkgPwrL2, " : "");
 7511	}
 7512	return 0;
 7513}
 7514
 7515#define	RAPL_POWER_GRANULARITY	0x7FFF	/* 15 bit power granularity */
 7516#define	RAPL_TIME_GRANULARITY	0x3F	/* 6 bit time granularity */
 7517
 7518double get_quirk_tdp(void)
 7519{
 7520	if (platform->rapl_quirk_tdp)
 7521		return platform->rapl_quirk_tdp;
 7522
 7523	return 135.0;
 7524}
 7525
 7526double get_tdp_intel(void)
 7527{
 7528	unsigned long long msr;
 7529
 7530	if (valid_rapl_msrs & RAPL_PKG_POWER_INFO)
 7531		if (!get_msr(base_cpu, MSR_PKG_POWER_INFO, &msr))
 7532			return ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units;
 7533	return get_quirk_tdp();
 7534}
 7535
 7536double get_tdp_amd(void)
 7537{
 7538	return get_quirk_tdp();
 7539}
 7540
 7541void rapl_probe_intel(void)
 7542{
 7543	unsigned long long msr;
 7544	unsigned int time_unit;
 7545	double tdp;
 7546
 7547	if (rapl_joules) {
 7548		CLR_BIC(BIC_SysWatt, &bic_enabled);
 7549		CLR_BIC(BIC_PkgWatt, &bic_enabled);
 7550		CLR_BIC(BIC_CorWatt, &bic_enabled);
 7551		CLR_BIC(BIC_RAMWatt, &bic_enabled);
 7552		CLR_BIC(BIC_GFXWatt, &bic_enabled);
 7553	} else {
 7554		CLR_BIC(BIC_Sys_J, &bic_enabled);
 7555		CLR_BIC(BIC_Pkg_J, &bic_enabled);
 7556		CLR_BIC(BIC_Cor_J, &bic_enabled);
 7557		CLR_BIC(BIC_RAM_J, &bic_enabled);
 7558		CLR_BIC(BIC_GFX_J, &bic_enabled);
 7559	}
 7560
 7561	if (!valid_rapl_msrs || no_msr)
 7562		return;
 7563
 7564	if (!(valid_rapl_msrs & RAPL_PKG_PERF_STATUS))
 7565		CLR_BIC(BIC_PKG__, &bic_enabled);
 7566	if (!(valid_rapl_msrs & RAPL_DRAM_PERF_STATUS))
 7567		CLR_BIC(BIC_RAM__, &bic_enabled);
 7568
 7569	/* units on package 0, verify later other packages match */
 7570	if (get_msr(base_cpu, MSR_RAPL_POWER_UNIT, &msr))
 7571		return;
 7572
 7573	rapl_power_units = 1.0 / (1 << (msr & 0xF));
 7574	if (platform->has_rapl_divisor)
 7575		rapl_energy_units = 1.0 * (1 << (msr >> 8 & 0x1F)) / 1000000;
 7576	else
 7577		rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F));
 7578
 7579	if (platform->has_fixed_rapl_unit)
 7580		rapl_dram_energy_units = (15.3 / 1000000);
 7581	else
 7582		rapl_dram_energy_units = rapl_energy_units;
 7583
 7584	if (platform->has_fixed_rapl_psys_unit)
 7585		rapl_psys_energy_units = 1.0;
 7586	else
 7587		rapl_psys_energy_units = rapl_energy_units;
 7588
 7589	time_unit = msr >> 16 & 0xF;
 7590	if (time_unit == 0)
 7591		time_unit = 0xA;
 7592
 7593	rapl_time_units = 1.0 / (1 << (time_unit));
 7594
 7595	tdp = get_tdp_intel();
 7596
 7597	rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
 7598	if (!quiet)
 7599		fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
 7600}
 7601
 7602void rapl_probe_amd(void)
 7603{
 7604	unsigned long long msr;
 7605	double tdp;
 7606
 7607	if (rapl_joules) {
 7608		CLR_BIC(BIC_SysWatt, &bic_enabled);
 7609		CLR_BIC(BIC_CorWatt, &bic_enabled);
 7610	} else {
 7611		CLR_BIC(BIC_Pkg_J, &bic_enabled);
 7612		CLR_BIC(BIC_Cor_J, &bic_enabled);
 7613	}
 7614
 7615	if (!valid_rapl_msrs || no_msr)
 7616		return;
 7617
 7618	if (get_msr(base_cpu, MSR_RAPL_PWR_UNIT, &msr))
 7619		return;
 7620
 7621	rapl_time_units = ldexp(1.0, -(msr >> 16 & 0xf));
 7622	rapl_energy_units = ldexp(1.0, -(msr >> 8 & 0x1f));
 7623	rapl_power_units = ldexp(1.0, -(msr & 0xf));
 7624
 7625	tdp = get_tdp_amd();
 7626
 7627	rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
 7628	if (!quiet)
 7629		fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
 7630}
 7631
 7632void print_power_limit_msr(int cpu, unsigned long long msr, char *label)
 7633{
 7634	fprintf(outf, "cpu%d: %s: %sabled (%0.3f Watts, %f sec, clamp %sabled)\n",
 7635		cpu, label,
 7636		((msr >> 15) & 1) ? "EN" : "DIS",
 7637		((msr >> 0) & 0x7FFF) * rapl_power_units,
 7638		(1.0 + (((msr >> 22) & 0x3) / 4.0)) * (1 << ((msr >> 17) & 0x1F)) * rapl_time_units, (((msr >> 16) & 1) ? "EN" : "DIS"));
 7639
 7640	return;
 7641}
 7642
 7643static int fread_int(char *path, int *val)
 7644{
 7645	FILE *filep;
 7646	int ret;
 7647
 7648	filep = fopen(path, "r");
 7649	if (!filep)
 7650		return -1;
 7651
 7652	ret = fscanf(filep, "%d", val);
 7653	fclose(filep);
 7654	return ret;
 7655}
 7656
 7657static int fread_ull(char *path, unsigned long long *val)
 7658{
 7659	FILE *filep;
 7660	int ret;
 7661
 7662	filep = fopen(path, "r");
 7663	if (!filep)
 7664		return -1;
 7665
 7666	ret = fscanf(filep, "%llu", val);
 7667	fclose(filep);
 7668	return ret;
 7669}
 7670
 7671static int fread_str(char *path, char *buf, int size)
 7672{
 7673	FILE *filep;
 7674	int ret;
 7675	char *cp;
 7676
 7677	filep = fopen(path, "r");
 7678	if (!filep)
 7679		return -1;
 7680
 7681	ret = fread(buf, 1, size, filep);
 7682	fclose(filep);
 7683
 7684	/* replace '\n' with '\0' */
 7685	cp = strchr(buf, '\n');
 7686	if (cp != NULL)
 7687		*cp = '\0';
 7688
 7689	return ret;
 7690}
 7691
 7692#define PATH_RAPL_SYSFS	"/sys/class/powercap"
 7693
 7694static int dump_one_domain(char *domain_path)
 7695{
 7696	char path[PATH_MAX];
 7697	char str[PATH_MAX];
 7698	unsigned long long val;
 7699	int constraint;
 7700	int enable;
 7701	int ret;
 7702
 7703	snprintf(path, PATH_MAX, "%s/name", domain_path);
 7704	ret = fread_str(path, str, PATH_MAX);
 7705	if (ret <= 0)
 7706		return -1;
 7707
 7708	fprintf(outf, "%s: %s", domain_path + strlen(PATH_RAPL_SYSFS) + 1, str);
 7709
 7710	snprintf(path, PATH_MAX, "%s/enabled", domain_path);
 7711	ret = fread_int(path, &enable);
 7712	if (ret <= 0)
 7713		return -1;
 7714
 7715	if (!enable) {
 7716		fputs(" disabled\n", outf);
 7717		return 0;
 7718	}
 7719
 7720	for (constraint = 0;; constraint++) {
 7721		snprintf(path, PATH_MAX, "%s/constraint_%d_time_window_us", domain_path, constraint);
 7722		ret = fread_ull(path, &val);
 7723		if (ret <= 0)
 7724			break;
 7725
 7726		if (val > 1000000)
 7727			fprintf(outf, " %0.1fs", (double)val / 1000000);
 7728		else if (val > 1000)
 7729			fprintf(outf, " %0.1fms", (double)val / 1000);
 7730		else
 7731			fprintf(outf, " %0.1fus", (double)val);
 7732
 7733		snprintf(path, PATH_MAX, "%s/constraint_%d_power_limit_uw", domain_path, constraint);
 7734		ret = fread_ull(path, &val);
 7735		if (ret > 0 && val)
 7736			fprintf(outf, ":%lluW", val / 1000000);
 7737
 7738		snprintf(path, PATH_MAX, "%s/constraint_%d_max_power_uw", domain_path, constraint);
 7739		ret = fread_ull(path, &val);
 7740		if (ret > 0 && val)
 7741			fprintf(outf, ",max:%lluW", val / 1000000);
 7742	}
 7743	fputc('\n', outf);
 7744
 7745	return 0;
 7746}
 7747
 7748static int print_rapl_sysfs(void)
 7749{
 7750	DIR *dir, *cdir;
 7751	struct dirent *entry, *centry;
 7752	char path[PATH_MAX];
 7753	char str[PATH_MAX];
 7754
 7755	if ((dir = opendir(PATH_RAPL_SYSFS)) == NULL) {
 7756		warn("open %s failed", PATH_RAPL_SYSFS);
 7757		return 1;
 7758	}
 7759
 7760	while ((entry = readdir(dir)) != NULL) {
 7761		if (strlen(entry->d_name) > 100)
 7762			continue;
 7763
 7764		if (strncmp(entry->d_name, "intel-rapl", strlen("intel-rapl")))
 7765			continue;
 7766
 7767		snprintf(path, PATH_MAX, "%s/%s/name", PATH_RAPL_SYSFS, entry->d_name);
 7768
 7769		/* Parse top level domains first, including package and psys */
 7770		fread_str(path, str, PATH_MAX);
 7771		if (strncmp(str, "package", strlen("package")) && strncmp(str, "psys", strlen("psys")))
 7772			continue;
 7773
 7774		snprintf(path, PATH_MAX, "%s/%s", PATH_RAPL_SYSFS, entry->d_name);
 7775		if ((cdir = opendir(path)) == NULL) {
 7776			perror("opendir() error");
 7777			return 1;
 7778		}
 7779
 7780		dump_one_domain(path);
 7781
 7782		while ((centry = readdir(cdir)) != NULL) {
 7783			if (strncmp(centry->d_name, "intel-rapl", strlen("intel-rapl")))
 7784				continue;
 7785			snprintf(path, PATH_MAX, "%s/%s/%s", PATH_RAPL_SYSFS, entry->d_name, centry->d_name);
 7786			dump_one_domain(path);
 7787		}
 7788		closedir(cdir);
 7789	}
 7790
 7791	closedir(dir);
 7792	return 0;
 7793}
 7794
 7795int print_rapl(PER_THREAD_PARAMS)
 7796{
 7797	unsigned long long msr;
 7798	const char *msr_name;
 7799	int cpu;
 7800
 7801	UNUSED(c);
 7802	UNUSED(p);
 7803
 7804	if (!valid_rapl_msrs)
 7805		return 0;
 7806
 7807	/* RAPL counters are per package, so print only for 1st thread/package */
 7808	if (!is_cpu_first_thread_in_package(t, c, p))
 7809		return 0;
 7810
 7811	cpu = t->cpu_id;
 7812	if (cpu_migrate(cpu)) {
 7813		fprintf(outf, "print_rapl: Could not migrate to CPU %d\n", cpu);
 7814		return -1;
 7815	}
 7816
 7817	if (valid_rapl_msrs & RAPL_AMD_F17H) {
 7818		msr_name = "MSR_RAPL_PWR_UNIT";
 7819		if (get_msr(cpu, MSR_RAPL_PWR_UNIT, &msr))
 7820			return -1;
 7821	} else {
 7822		msr_name = "MSR_RAPL_POWER_UNIT";
 7823		if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr))
 7824			return -1;
 7825	}
 7826
 7827	fprintf(outf, "cpu%d: %s: 0x%08llx (%f Watts, %f Joules, %f sec.)\n", cpu, msr_name, msr,
 7828		rapl_power_units, rapl_energy_units, rapl_time_units);
 7829
 7830	if (valid_rapl_msrs & RAPL_PKG_POWER_INFO) {
 7831
 7832		if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr))
 7833			return -5;
 7834
 7835		fprintf(outf, "cpu%d: MSR_PKG_POWER_INFO: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
 7836			cpu, msr,
 7837			((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
 7838			((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
 7839			((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units, ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
 7840
 7841	}
 7842	if (valid_rapl_msrs & RAPL_PKG) {
 7843
 7844		if (get_msr(cpu, MSR_PKG_POWER_LIMIT, &msr))
 7845			return -9;
 7846
 7847		fprintf(outf, "cpu%d: MSR_PKG_POWER_LIMIT: 0x%08llx (%slocked)\n", cpu, msr, (msr >> 63) & 1 ? "" : "UN");
 7848
 7849		print_power_limit_msr(cpu, msr, "PKG Limit #1");
 7850		fprintf(outf, "cpu%d: PKG Limit #2: %sabled (%0.3f Watts, %f* sec, clamp %sabled)\n",
 7851			cpu,
 7852			((msr >> 47) & 1) ? "EN" : "DIS",
 7853			((msr >> 32) & 0x7FFF) * rapl_power_units,
 7854			(1.0 + (((msr >> 54) & 0x3) / 4.0)) * (1 << ((msr >> 49) & 0x1F)) * rapl_time_units, ((msr >> 48) & 1) ? "EN" : "DIS");
 7855
 7856		if (get_msr(cpu, MSR_VR_CURRENT_CONFIG, &msr))
 7857			return -9;
 7858
 7859		fprintf(outf, "cpu%d: MSR_VR_CURRENT_CONFIG: 0x%08llx\n", cpu, msr);
 7860		fprintf(outf, "cpu%d: PKG Limit #4: %f Watts (%slocked)\n",
 7861			cpu, ((msr >> 0) & 0x1FFF) * rapl_power_units, (msr >> 31) & 1 ? "" : "UN");
 7862	}
 7863
 7864	if (valid_rapl_msrs & RAPL_DRAM_POWER_INFO) {
 7865		if (get_msr(cpu, MSR_DRAM_POWER_INFO, &msr))
 7866			return -6;
 7867
 7868		fprintf(outf, "cpu%d: MSR_DRAM_POWER_INFO,: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
 7869			cpu, msr,
 7870			((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
 7871			((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
 7872			((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units, ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
 7873	}
 7874	if (valid_rapl_msrs & RAPL_DRAM) {
 7875		if (get_msr(cpu, MSR_DRAM_POWER_LIMIT, &msr))
 7876			return -9;
 7877		fprintf(outf, "cpu%d: MSR_DRAM_POWER_LIMIT: 0x%08llx (%slocked)\n", cpu, msr, (msr >> 31) & 1 ? "" : "UN");
 7878
 7879		print_power_limit_msr(cpu, msr, "DRAM Limit");
 7880	}
 7881	if (valid_rapl_msrs & RAPL_CORE_POLICY) {
 7882		if (get_msr(cpu, MSR_PP0_POLICY, &msr))
 7883			return -7;
 7884
 7885		fprintf(outf, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF);
 7886	}
 7887	if (valid_rapl_msrs & RAPL_CORE_POWER_LIMIT) {
 7888		if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr))
 7889			return -9;
 7890		fprintf(outf, "cpu%d: MSR_PP0_POWER_LIMIT: 0x%08llx (%slocked)\n", cpu, msr, (msr >> 31) & 1 ? "" : "UN");
 7891		print_power_limit_msr(cpu, msr, "Cores Limit");
 7892	}
 7893	if (valid_rapl_msrs & RAPL_GFX) {
 7894		if (get_msr(cpu, MSR_PP1_POLICY, &msr))
 7895			return -8;
 7896
 7897		fprintf(outf, "cpu%d: MSR_PP1_POLICY: %lld\n", cpu, msr & 0xF);
 7898
 7899		if (get_msr(cpu, MSR_PP1_POWER_LIMIT, &msr))
 7900			return -9;
 7901		fprintf(outf, "cpu%d: MSR_PP1_POWER_LIMIT: 0x%08llx (%slocked)\n", cpu, msr, (msr >> 31) & 1 ? "" : "UN");
 7902		print_power_limit_msr(cpu, msr, "GFX Limit");
 7903	}
 7904	return 0;
 7905}
 7906
 7907/*
 7908 * probe_rapl_msrs
 7909 *
 7910 * initialize global valid_rapl_msrs to platform->plat_rapl_msrs
 7911 * only if PKG_ENERGY counter is enumerated and reads non-zero
 7912 */
 7913void probe_rapl_msrs(void)
 7914{
 7915	int ret;
 7916	off_t offset;
 7917	unsigned long long msr_value;
 7918
 7919	if (no_msr)
 7920		return;
 7921
 7922	if ((platform->plat_rapl_msrs & (RAPL_PKG | RAPL_AMD_F17H)) == 0)
 7923		return;
 7924
 7925	offset = idx_to_offset(IDX_PKG_ENERGY);
 7926	if (offset < 0)
 7927		return;
 7928
 7929	ret = get_msr(base_cpu, offset, &msr_value);
 7930	if (ret) {
 7931		if (debug)
 7932			fprintf(outf, "Can not read RAPL_PKG_ENERGY MSR(0x%llx)\n", (unsigned long long)offset);
 7933		return;
 7934	}
 7935	if (msr_value == 0) {
 7936		if (debug)
 7937			fprintf(outf, "RAPL_PKG_ENERGY MSR(0x%llx) == ZERO: disabling all RAPL MSRs\n", (unsigned long long)offset);
 7938		return;
 7939	}
 7940
 7941	valid_rapl_msrs = platform->plat_rapl_msrs;	/* success */
 7942}
 7943
 7944/*
 7945 * probe_rapl()
 7946 *
 7947 * sets rapl_power_units, rapl_energy_units, rapl_time_units
 7948 */
 7949void probe_rapl(void)
 7950{
 7951	probe_rapl_msrs();
 7952
 7953	if (genuine_intel)
 7954		rapl_probe_intel();
 7955	if (authentic_amd || hygon_genuine)
 7956		rapl_probe_amd();
 7957
 7958	if (quiet)
 7959		return;
 7960
 7961	print_rapl_sysfs();
 7962
 7963	if (!valid_rapl_msrs || no_msr)
 7964		return;
 7965
 7966	for_all_cpus(print_rapl, ODD_COUNTERS);
 7967}
 7968
 7969/*
 7970 * MSR_IA32_TEMPERATURE_TARGET indicates the temperature where
 7971 * the Thermal Control Circuit (TCC) activates.
 7972 * This is usually equal to tjMax.
 7973 *
 7974 * Older processors do not have this MSR, so there we guess,
 7975 * but also allow cmdline over-ride with -T.
 7976 *
 7977 * Several MSR temperature values are in units of degrees-C
 7978 * below this value, including the Digital Thermal Sensor (DTS),
 7979 * Package Thermal Management Sensor (PTM), and thermal event thresholds.
 7980 */
 7981int set_temperature_target(PER_THREAD_PARAMS)
 7982{
 7983	unsigned long long msr;
 7984	unsigned int tcc_default, tcc_offset;
 7985	int cpu;
 7986
 7987	UNUSED(c);
 7988	UNUSED(p);
 7989
 7990	/* tj_max is used only for dts or ptm */
 7991	if (!(do_dts || do_ptm))
 7992		return 0;
 7993
 7994	/* this is a per-package concept */
 7995	if (!is_cpu_first_thread_in_package(t, c, p))
 7996		return 0;
 7997
 7998	cpu = t->cpu_id;
 7999	if (cpu_migrate(cpu)) {
 8000		fprintf(outf, "Could not migrate to CPU %d\n", cpu);
 8001		return -1;
 8002	}
 8003
 8004	if (tj_max_override != 0) {
 8005		tj_max = tj_max_override;
 8006		fprintf(outf, "cpu%d: Using cmdline TCC Target (%d C)\n", cpu, tj_max);
 8007		return 0;
 8008	}
 8009
 8010	/* Temperature Target MSR is Nehalem and newer only */
 8011	if (!platform->has_nhm_msrs || no_msr)
 8012		goto guess;
 8013
 8014	if (get_msr(base_cpu, MSR_IA32_TEMPERATURE_TARGET, &msr))
 8015		goto guess;
 8016
 8017	tcc_default = (msr >> 16) & 0xFF;
 8018
 8019	if (!quiet) {
 8020		int bits = platform->tcc_offset_bits;
 8021		unsigned long long enabled = 0;
 8022
 8023		if (bits && !get_msr(base_cpu, MSR_PLATFORM_INFO, &enabled))
 8024			enabled = (enabled >> 30) & 1;
 8025
 8026		if (bits && enabled) {
 8027			tcc_offset = (msr >> 24) & GENMASK(bits - 1, 0);
 8028			fprintf(outf, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C) (%d default - %d offset)\n",
 8029				cpu, msr, tcc_default - tcc_offset, tcc_default, tcc_offset);
 8030		} else {
 8031			fprintf(outf, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n", cpu, msr, tcc_default);
 8032		}
 8033	}
 8034
 8035	if (!tcc_default)
 8036		goto guess;
 8037
 8038	tj_max = tcc_default;
 8039
 8040	return 0;
 8041
 8042guess:
 8043	tj_max = TJMAX_DEFAULT;
 8044	fprintf(outf, "cpu%d: Guessing tjMax %d C, Please use -T to specify\n", cpu, tj_max);
 8045
 8046	return 0;
 8047}
 8048
 8049int print_thermal(PER_THREAD_PARAMS)
 8050{
 8051	unsigned long long msr;
 8052	unsigned int dts, dts2;
 8053	int cpu;
 8054
 8055	UNUSED(c);
 8056	UNUSED(p);
 8057
 8058	if (no_msr)
 8059		return 0;
 8060
 8061	if (!(do_dts || do_ptm))
 8062		return 0;
 8063
 8064	cpu = t->cpu_id;
 8065
 8066	/* DTS is per-core, no need to print for each thread */
 8067	if (!is_cpu_first_thread_in_core(t, c))
 8068		return 0;
 8069
 8070	if (cpu_migrate(cpu)) {
 8071		fprintf(outf, "print_thermal: Could not migrate to CPU %d\n", cpu);
 8072		return -1;
 8073	}
 8074
 8075	if (do_ptm && is_cpu_first_core_in_package(t, p)) {
 8076		if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
 8077			return 0;
 8078
 8079		dts = (msr >> 16) & 0x7F;
 8080		fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_STATUS: 0x%08llx (%d C)\n", cpu, msr, tj_max - dts);
 8081
 8082		if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, &msr))
 8083			return 0;
 8084
 8085		dts = (msr >> 16) & 0x7F;
 8086		dts2 = (msr >> 8) & 0x7F;
 8087		fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n", cpu, msr, tj_max - dts, tj_max - dts2);
 8088	}
 8089
 8090	if (do_dts && debug) {
 8091		unsigned int resolution;
 8092
 8093		if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
 8094			return 0;
 8095
 8096		dts = (msr >> 16) & 0x7F;
 8097		resolution = (msr >> 27) & 0xF;
 8098		fprintf(outf, "cpu%d: MSR_IA32_THERM_STATUS: 0x%08llx (%d C +/- %d)\n", cpu, msr, tj_max - dts, resolution);
 8099
 8100		if (get_msr(cpu, MSR_IA32_THERM_INTERRUPT, &msr))
 8101			return 0;
 8102
 8103		dts = (msr >> 16) & 0x7F;
 8104		dts2 = (msr >> 8) & 0x7F;
 8105		fprintf(outf, "cpu%d: MSR_IA32_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n", cpu, msr, tj_max - dts, tj_max - dts2);
 8106	}
 8107
 8108	return 0;
 8109}
 8110
 8111void probe_thermal(void)
 8112{
 8113	if (!access("/sys/devices/system/cpu/cpu0/thermal_throttle/core_throttle_count", R_OK))
 8114		BIC_PRESENT(BIC_CORE_THROT_CNT);
 8115	else
 8116		BIC_NOT_PRESENT(BIC_CORE_THROT_CNT);
 8117
 8118	for_all_cpus(set_temperature_target, ODD_COUNTERS);
 8119
 8120	if (quiet)
 8121		return;
 8122
 8123	for_all_cpus(print_thermal, ODD_COUNTERS);
 8124}
 8125
 8126int get_cpu_type(PER_THREAD_PARAMS)
 8127{
 8128	unsigned int eax, ebx, ecx, edx;
 8129
 8130	UNUSED(c);
 8131	UNUSED(p);
 8132
 8133	if (!genuine_intel)
 8134		return 0;
 8135
 8136	if (cpu_migrate(t->cpu_id)) {
 8137		fprintf(outf, "Could not migrate to CPU %d\n", t->cpu_id);
 8138		return -1;
 8139	}
 8140
 8141	if (max_level < 0x1a)
 8142		return 0;
 8143
 8144	__cpuid(0x1a, eax, ebx, ecx, edx);
 8145	eax = (eax >> 24) & 0xFF;
 8146	if (eax == 0x20)
 8147		t->is_atom = true;
 8148	return 0;
 8149}
 8150
 8151void decode_feature_control_msr(void)
 8152{
 8153	unsigned long long msr;
 8154
 8155	if (no_msr)
 8156		return;
 8157
 8158	if (!get_msr(base_cpu, MSR_IA32_FEAT_CTL, &msr))
 8159		fprintf(outf, "cpu%d: MSR_IA32_FEATURE_CONTROL: 0x%08llx (%sLocked %s)\n",
 8160			base_cpu, msr, msr & FEAT_CTL_LOCKED ? "" : "UN-", msr & (1 << 18) ? "SGX" : "");
 8161}
 8162
 8163void decode_misc_enable_msr(void)
 8164{
 8165	unsigned long long msr;
 8166
 8167	if (no_msr)
 8168		return;
 8169
 8170	if (!genuine_intel)
 8171		return;
 8172
 8173	if (!get_msr(base_cpu, MSR_IA32_MISC_ENABLE, &msr))
 8174		fprintf(outf, "cpu%d: MSR_IA32_MISC_ENABLE: 0x%08llx (%sTCC %sEIST %sMWAIT %sPREFETCH %sTURBO)\n",
 8175			base_cpu, msr,
 8176			msr & MSR_IA32_MISC_ENABLE_TM1 ? "" : "No-",
 8177			msr & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP ? "" : "No-",
 8178			msr & MSR_IA32_MISC_ENABLE_MWAIT ? "" : "No-",
 8179			msr & MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE ? "No-" : "", msr & MSR_IA32_MISC_ENABLE_TURBO_DISABLE ? "No-" : "");
 8180}
 8181
 8182void decode_misc_feature_control(void)
 8183{
 8184	unsigned long long msr;
 8185
 8186	if (no_msr)
 8187		return;
 8188
 8189	if (!platform->has_msr_misc_feature_control)
 8190		return;
 8191
 8192	if (!get_msr(base_cpu, MSR_MISC_FEATURE_CONTROL, &msr))
 8193		fprintf(outf,
 8194			"cpu%d: MSR_MISC_FEATURE_CONTROL: 0x%08llx (%sL2-Prefetch %sL2-Prefetch-pair %sL1-Prefetch %sL1-IP-Prefetch)\n",
 8195			base_cpu, msr, msr & (0 << 0) ? "No-" : "", msr & (1 << 0) ? "No-" : "",
 8196			msr & (2 << 0) ? "No-" : "", msr & (3 << 0) ? "No-" : "");
 8197}
 8198
 8199/*
 8200 * Decode MSR_MISC_PWR_MGMT
 8201 *
 8202 * Decode the bits according to the Nehalem documentation
 8203 * bit[0] seems to continue to have same meaning going forward
 8204 * bit[1] less so...
 8205 */
 8206void decode_misc_pwr_mgmt_msr(void)
 8207{
 8208	unsigned long long msr;
 8209
 8210	if (no_msr)
 8211		return;
 8212
 8213	if (!platform->has_msr_misc_pwr_mgmt)
 8214		return;
 8215
 8216	if (!get_msr(base_cpu, MSR_MISC_PWR_MGMT, &msr))
 8217		fprintf(outf, "cpu%d: MSR_MISC_PWR_MGMT: 0x%08llx (%sable-EIST_Coordination %sable-EPB %sable-OOB)\n",
 8218			base_cpu, msr, msr & (1 << 0) ? "DIS" : "EN", msr & (1 << 1) ? "EN" : "DIS", msr & (1 << 8) ? "EN" : "DIS");
 8219}
 8220
 8221/*
 8222 * Decode MSR_CC6_DEMOTION_POLICY_CONFIG, MSR_MC6_DEMOTION_POLICY_CONFIG
 8223 *
 8224 * This MSRs are present on Silvermont processors,
 8225 * Intel Atom processor E3000 series (Baytrail), and friends.
 8226 */
 8227void decode_c6_demotion_policy_msr(void)
 8228{
 8229	unsigned long long msr;
 8230
 8231	if (no_msr)
 8232		return;
 8233
 8234	if (!platform->has_msr_c6_demotion_policy_config)
 8235		return;
 8236
 8237	if (!get_msr(base_cpu, MSR_CC6_DEMOTION_POLICY_CONFIG, &msr))
 8238		fprintf(outf, "cpu%d: MSR_CC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-CC6-Demotion)\n",
 8239			base_cpu, msr, msr & (1 << 0) ? "EN" : "DIS");
 8240
 8241	if (!get_msr(base_cpu, MSR_MC6_DEMOTION_POLICY_CONFIG, &msr))
 8242		fprintf(outf, "cpu%d: MSR_MC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-MC6-Demotion)\n",
 8243			base_cpu, msr, msr & (1 << 0) ? "EN" : "DIS");
 8244}
 8245
 8246void print_dev_latency(void)
 8247{
 8248	char *path = "/dev/cpu_dma_latency";
 8249	int fd;
 8250	int value;
 8251	int retval;
 8252
 8253	fd = open(path, O_RDONLY);
 8254	if (fd < 0) {
 8255		if (debug)
 8256			warnx("Read %s failed", path);
 8257		return;
 8258	}
 8259
 8260	retval = read(fd, (void *)&value, sizeof(int));
 8261	if (retval != sizeof(int)) {
 8262		warn("read failed %s", path);
 8263		close(fd);
 8264		return;
 8265	}
 8266	fprintf(outf, "/dev/cpu_dma_latency: %d usec (%s)\n", value, value == 2000000000 ? "default" : "constrained");
 8267
 8268	close(fd);
 8269}
 8270
 8271static int has_perf_instr_count_access(void)
 8272{
 8273	int fd;
 8274
 8275	if (no_perf)
 8276		return 0;
 8277
 8278	fd = open_perf_counter(base_cpu, PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS, -1, 0);
 8279	if (fd != -1)
 8280		close(fd);
 8281
 8282	if (fd == -1)
 8283		warnx("Failed to access %s. Some of the counters may not be available\n"
 8284		      "\tRun as root to enable them or use %s to disable the access explicitly", "perf instructions retired counter",
 8285		      "'--hide IPC' or '--no-perf'");
 8286
 8287	return (fd != -1);
 8288}
 8289
 8290int add_rapl_perf_counter(int cpu, struct rapl_counter_info_t *rci, const struct rapl_counter_arch_info *cai, double *scale_, enum rapl_unit *unit_)
 8291{
 8292	int ret = -1;
 8293
 8294	if (no_perf)
 8295		return -1;
 8296
 8297	if (!cai->perf_name)
 8298		return -1;
 8299
 8300	const double scale = read_perf_scale(cai->perf_subsys, cai->perf_name);
 8301
 8302	if (scale == 0.0)
 8303		goto end;
 8304
 8305	const enum rapl_unit unit = read_perf_rapl_unit(cai->perf_subsys, cai->perf_name);
 8306
 8307	if (unit == RAPL_UNIT_INVALID)
 8308		goto end;
 8309
 8310	const unsigned int rapl_type = read_perf_type(cai->perf_subsys);
 8311	const unsigned int rapl_energy_pkg_config = read_perf_config(cai->perf_subsys, cai->perf_name);
 8312
 8313	ret = open_perf_counter(cpu, rapl_type, rapl_energy_pkg_config, rci->fd_perf, PERF_FORMAT_GROUP);
 8314	if (ret == -1)
 8315		goto end;
 8316
 8317	/* If it's the first counter opened, make it a group descriptor */
 8318	if (rci->fd_perf == -1)
 8319		rci->fd_perf = ret;
 8320
 8321	*scale_ = scale;
 8322	*unit_ = unit;
 8323
 8324end:
 8325	if (debug >= 2)
 8326		fprintf(stderr, "%s: %d (cpu: %d)\n", __func__, ret, cpu);
 8327
 8328	return ret;
 8329}
 8330
 8331/*
 8332 * Linux-perf manages the HW instructions-retired counter
 8333 * by enabling when requested, and hiding rollover
 8334 */
 8335void linux_perf_init(void)
 8336{
 8337	if (access("/proc/sys/kernel/perf_event_paranoid", F_OK))
 8338		return;
 8339
 8340	if (BIC_IS_ENABLED(BIC_IPC) && cpuid_has_aperf_mperf) {
 8341		fd_instr_count_percpu = calloc(topo.max_cpu_num + 1, sizeof(int));
 8342		if (fd_instr_count_percpu == NULL)
 8343			err(-1, "calloc fd_instr_count_percpu");
 8344	}
 8345	if (BIC_IS_ENABLED(BIC_LLC_RPS)) {
 8346		fd_llc_percpu = calloc(topo.max_cpu_num + 1, sizeof(int));
 8347		if (fd_llc_percpu == NULL)
 8348			err(-1, "calloc fd_llc_percpu");
 8349	}
 8350}
 8351
 8352void rapl_perf_init(void)
 8353{
 8354	const unsigned int num_domains = get_rapl_num_domains();
 8355	bool *domain_visited = calloc(num_domains, sizeof(bool));
 8356
 8357	rapl_counter_info_perdomain = calloc(num_domains, sizeof(*rapl_counter_info_perdomain));
 8358	if (rapl_counter_info_perdomain == NULL)
 8359		err(-1, "calloc rapl_counter_info_percpu");
 8360	rapl_counter_info_perdomain_size = num_domains;
 8361
 8362	/*
 8363	 * Initialize rapl_counter_info_percpu
 8364	 */
 8365	for (unsigned int domain_id = 0; domain_id < num_domains; ++domain_id) {
 8366		struct rapl_counter_info_t *rci = &rapl_counter_info_perdomain[domain_id];
 8367
 8368		rci->fd_perf = -1;
 8369		for (size_t i = 0; i < NUM_RAPL_COUNTERS; ++i) {
 8370			rci->data[i] = 0;
 8371			rci->source[i] = COUNTER_SOURCE_NONE;
 8372		}
 8373	}
 8374
 8375	/*
 8376	 * Open/probe the counters
 8377	 * If can't get it via perf, fallback to MSR
 8378	 */
 8379	for (size_t i = 0; i < ARRAY_SIZE(rapl_counter_arch_infos); ++i) {
 8380
 8381		const struct rapl_counter_arch_info *const cai = &rapl_counter_arch_infos[i];
 8382		bool has_counter = 0;
 8383		double scale;
 8384		enum rapl_unit unit;
 8385		unsigned int next_domain;
 8386
 8387		if (!BIC_IS_ENABLED(cai->bic_number))
 8388			continue;
 8389
 8390		memset(domain_visited, 0, num_domains * sizeof(*domain_visited));
 8391
 8392		for (int cpu = 0; cpu < topo.max_cpu_num + 1; ++cpu) {
 8393
 8394			if (cpu_is_not_allowed(cpu))
 8395				continue;
 8396
 8397			/* Skip already seen and handled RAPL domains */
 8398			next_domain = get_rapl_domain_id(cpu);
 8399
 8400			assert(next_domain < num_domains);
 8401
 8402			if (domain_visited[next_domain])
 8403				continue;
 8404
 8405			domain_visited[next_domain] = 1;
 8406
 8407			if ((cai->flags & RAPL_COUNTER_FLAG_PLATFORM_COUNTER) && (cpu != base_cpu))
 8408				continue;
 8409
 8410			struct rapl_counter_info_t *rci = &rapl_counter_info_perdomain[next_domain];
 8411
 8412			/*
 8413			 * rapl_counter_arch_infos[] can have multiple entries describing the same
 8414			 * counter, due to the difference from different platforms/Vendors.
 8415			 * E.g. rapl_counter_arch_infos[0] and rapl_counter_arch_infos[1] share the
 8416			 * same perf_subsys and perf_name, but with different MSR address.
 8417			 * rapl_counter_arch_infos[0] is for Intel and rapl_counter_arch_infos[1]
 8418			 * is for AMD.
 8419			 * In this case, it is possible that multiple rapl_counter_arch_infos[]
 8420			 * entries are probed just because their perf/msr is duplicate and valid.
 8421			 *
 8422			 * Thus need a check to avoid re-probe the same counters.
 8423			 */
 8424			if (rci->source[cai->rci_index] != COUNTER_SOURCE_NONE)
 8425				break;
 8426
 8427			/* Use perf API for this counter */
 8428			if (add_rapl_perf_counter(cpu, rci, cai, &scale, &unit) != -1) {
 8429				rci->source[cai->rci_index] = COUNTER_SOURCE_PERF;
 8430				rci->scale[cai->rci_index] = scale * cai->compat_scale;
 8431				rci->unit[cai->rci_index] = unit;
 8432				rci->flags[cai->rci_index] = cai->flags;
 8433
 8434				/* Use MSR for this counter */
 8435			} else if (add_rapl_msr_counter(cpu, cai) >= 0) {
 8436				rci->source[cai->rci_index] = COUNTER_SOURCE_MSR;
 8437				rci->msr[cai->rci_index] = cai->msr;
 8438				rci->msr_mask[cai->rci_index] = cai->msr_mask;
 8439				rci->msr_shift[cai->rci_index] = cai->msr_shift;
 8440				rci->unit[cai->rci_index] = RAPL_UNIT_JOULES;
 8441				rci->scale[cai->rci_index] = *cai->platform_rapl_msr_scale * cai->compat_scale;
 8442				rci->flags[cai->rci_index] = cai->flags;
 8443			}
 8444
 8445			if (rci->source[cai->rci_index] != COUNTER_SOURCE_NONE)
 8446				has_counter = 1;
 8447		}
 8448
 8449		/* If any CPU has access to the counter, make it present */
 8450		if (has_counter)
 8451			BIC_PRESENT(cai->bic_number);
 8452	}
 8453
 8454	free(domain_visited);
 8455}
 8456
 8457/* Assumes msr_counter_info is populated */
 8458static int has_amperf_access(void)
 8459{
 8460	return cpuid_has_aperf_mperf && msr_counter_arch_infos[MSR_ARCH_INFO_APERF_INDEX].present &&
 8461	    msr_counter_arch_infos[MSR_ARCH_INFO_MPERF_INDEX].present;
 8462}
 8463
 8464int *get_cstate_perf_group_fd(struct cstate_counter_info_t *cci, const char *group_name)
 8465{
 8466	if (strcmp(group_name, "cstate_core") == 0)
 8467		return &cci->fd_perf_core;
 8468
 8469	if (strcmp(group_name, "cstate_pkg") == 0)
 8470		return &cci->fd_perf_pkg;
 8471
 8472	return NULL;
 8473}
 8474
 8475int add_cstate_perf_counter(int cpu, struct cstate_counter_info_t *cci, const struct cstate_counter_arch_info *cai)
 8476{
 8477	int ret = -1;
 8478
 8479	if (no_perf)
 8480		return -1;
 8481
 8482	if (!cai->perf_name)
 8483		return -1;
 8484
 8485	int *pfd_group = get_cstate_perf_group_fd(cci, cai->perf_subsys);
 8486
 8487	if (pfd_group == NULL)
 8488		goto end;
 8489
 8490	const unsigned int type = read_perf_type(cai->perf_subsys);
 8491	const unsigned int config = read_perf_config(cai->perf_subsys, cai->perf_name);
 8492
 8493	ret = open_perf_counter(cpu, type, config, *pfd_group, PERF_FORMAT_GROUP);
 8494
 8495	if (ret == -1)
 8496		goto end;
 8497
 8498	/* If it's the first counter opened, make it a group descriptor */
 8499	if (*pfd_group == -1)
 8500		*pfd_group = ret;
 8501
 8502end:
 8503	if (debug >= 2)
 8504		fprintf(stderr, "%s: %d (cpu: %d)\n", __func__, ret, cpu);
 8505
 8506	return ret;
 8507}
 8508
 8509int add_msr_perf_counter(int cpu, struct msr_counter_info_t *cci, const struct msr_counter_arch_info *cai)
 8510{
 8511	int ret = -1;
 8512
 8513	if (no_perf)
 8514		return -1;
 8515
 8516	if (!cai->perf_name)
 8517		return -1;
 8518
 8519	const unsigned int type = read_perf_type(cai->perf_subsys);
 8520	const unsigned int config = read_perf_config(cai->perf_subsys, cai->perf_name);
 8521
 8522	ret = open_perf_counter(cpu, type, config, cci->fd_perf, PERF_FORMAT_GROUP);
 8523
 8524	if (ret == -1)
 8525		goto end;
 8526
 8527	/* If it's the first counter opened, make it a group descriptor */
 8528	if (cci->fd_perf == -1)
 8529		cci->fd_perf = ret;
 8530
 8531end:
 8532	if (debug)
 8533		fprintf(stderr, "%s: %s/%s: %d (cpu: %d)\n", __func__, cai->perf_subsys, cai->perf_name, ret, cpu);
 8534
 8535	return ret;
 8536}
 8537
 8538void msr_perf_init_(void)
 8539{
 8540	const int mci_num = topo.max_cpu_num + 1;
 8541
 8542	msr_counter_info = calloc(mci_num, sizeof(*msr_counter_info));
 8543	if (!msr_counter_info)
 8544		err(1, "calloc msr_counter_info");
 8545	msr_counter_info_size = mci_num;
 8546
 8547	for (int cpu = 0; cpu < mci_num; ++cpu)
 8548		msr_counter_info[cpu].fd_perf = -1;
 8549
 8550	for (int cidx = 0; cidx < NUM_MSR_COUNTERS; ++cidx) {
 8551
 8552		struct msr_counter_arch_info *cai = &msr_counter_arch_infos[cidx];
 8553
 8554		cai->present = false;
 8555
 8556		for (int cpu = 0; cpu < mci_num; ++cpu) {
 8557
 8558			struct msr_counter_info_t *const cci = &msr_counter_info[cpu];
 8559
 8560			if (cpu_is_not_allowed(cpu))
 8561				continue;
 8562
 8563			if (cai->needed) {
 8564				/* Use perf API for this counter */
 8565				if (add_msr_perf_counter(cpu, cci, cai) != -1) {
 8566					cci->source[cai->rci_index] = COUNTER_SOURCE_PERF;
 8567					cai->present = true;
 8568
 8569					/* User MSR for this counter */
 8570				} else if (add_msr_counter(cpu, cai->msr) >= 0) {
 8571					cci->source[cai->rci_index] = COUNTER_SOURCE_MSR;
 8572					cci->msr[cai->rci_index] = cai->msr;
 8573					cci->msr_mask[cai->rci_index] = cai->msr_mask;
 8574					cai->present = true;
 8575				}
 8576			}
 8577		}
 8578	}
 8579}
 8580
 8581/* Initialize data for reading perf counters from the MSR group. */
 8582void msr_perf_init(void)
 8583{
 8584	bool need_amperf = false, need_smi = false;
 8585	const bool need_soft_c1 = (!platform->has_msr_core_c1_res) && (platform->supported_cstates & CC1);
 8586
 8587	need_amperf = BIC_IS_ENABLED(BIC_Avg_MHz) || BIC_IS_ENABLED(BIC_Busy) || BIC_IS_ENABLED(BIC_Bzy_MHz)
 8588	    || BIC_IS_ENABLED(BIC_IPC) || need_soft_c1;
 8589
 8590	if (BIC_IS_ENABLED(BIC_SMI))
 8591		need_smi = true;
 8592
 8593	/* Enable needed counters */
 8594	msr_counter_arch_infos[MSR_ARCH_INFO_APERF_INDEX].needed = need_amperf;
 8595	msr_counter_arch_infos[MSR_ARCH_INFO_MPERF_INDEX].needed = need_amperf;
 8596	msr_counter_arch_infos[MSR_ARCH_INFO_SMI_INDEX].needed = need_smi;
 8597
 8598	msr_perf_init_();
 8599
 8600	const bool has_amperf = has_amperf_access();
 8601	const bool has_smi = msr_counter_arch_infos[MSR_ARCH_INFO_SMI_INDEX].present;
 8602
 8603	has_aperf_access = has_amperf;
 8604
 8605	if (has_amperf) {
 8606		BIC_PRESENT(BIC_Avg_MHz);
 8607		BIC_PRESENT(BIC_Busy);
 8608		BIC_PRESENT(BIC_Bzy_MHz);
 8609		BIC_PRESENT(BIC_SMI);
 8610	}
 8611
 8612	if (has_smi)
 8613		BIC_PRESENT(BIC_SMI);
 8614}
 8615
 8616void cstate_perf_init_(bool soft_c1)
 8617{
 8618	bool has_counter;
 8619	bool *cores_visited = NULL, *pkg_visited = NULL;
 8620	const int cores_visited_elems = topo.max_core_id + 1;
 8621	const int pkg_visited_elems = topo.max_package_id + 1;
 8622	const int cci_num = topo.max_cpu_num + 1;
 8623
 8624	ccstate_counter_info = calloc(cci_num, sizeof(*ccstate_counter_info));
 8625	if (!ccstate_counter_info)
 8626		err(1, "calloc ccstate_counter_arch_info");
 8627	ccstate_counter_info_size = cci_num;
 8628
 8629	cores_visited = calloc(cores_visited_elems, sizeof(*cores_visited));
 8630	if (!cores_visited)
 8631		err(1, "calloc cores_visited");
 8632
 8633	pkg_visited = calloc(pkg_visited_elems, sizeof(*pkg_visited));
 8634	if (!pkg_visited)
 8635		err(1, "calloc pkg_visited");
 8636
 8637	/* Initialize cstate_counter_info_percpu */
 8638	for (int cpu = 0; cpu < cci_num; ++cpu) {
 8639		ccstate_counter_info[cpu].fd_perf_core = -1;
 8640		ccstate_counter_info[cpu].fd_perf_pkg = -1;
 8641	}
 8642
 8643	for (int cidx = 0; cidx < NUM_CSTATE_COUNTERS; ++cidx) {
 8644		has_counter = false;
 8645		memset(cores_visited, 0, cores_visited_elems * sizeof(*cores_visited));
 8646		memset(pkg_visited, 0, pkg_visited_elems * sizeof(*pkg_visited));
 8647
 8648		const struct cstate_counter_arch_info *cai = &ccstate_counter_arch_infos[cidx];
 8649
 8650		for (int cpu = 0; cpu < cci_num; ++cpu) {
 8651
 8652			struct cstate_counter_info_t *const cci = &ccstate_counter_info[cpu];
 8653
 8654			if (cpu_is_not_allowed(cpu))
 8655				continue;
 8656
 8657			const int core_id = cpus[cpu].physical_core_id;
 8658			const int pkg_id = cpus[cpu].physical_package_id;
 8659
 8660			assert(core_id < cores_visited_elems);
 8661			assert(pkg_id < pkg_visited_elems);
 8662
 8663			const bool per_thread = cai->flags & CSTATE_COUNTER_FLAG_COLLECT_PER_THREAD;
 8664			const bool per_core = cai->flags & CSTATE_COUNTER_FLAG_COLLECT_PER_CORE;
 8665
 8666			if (!per_thread && cores_visited[core_id])
 8667				continue;
 8668
 8669			if (!per_core && pkg_visited[pkg_id])
 8670				continue;
 8671
 8672			const bool counter_needed = BIC_IS_ENABLED(cai->bic_number) ||
 8673			    (soft_c1 && (cai->flags & CSTATE_COUNTER_FLAG_SOFT_C1_DEPENDENCY));
 8674			const bool counter_supported = (platform->supported_cstates & cai->feature_mask);
 8675
 8676			if (counter_needed && counter_supported) {
 8677				/* Use perf API for this counter */
 8678				if (add_cstate_perf_counter(cpu, cci, cai) != -1) {
 8679
 8680					cci->source[cai->rci_index] = COUNTER_SOURCE_PERF;
 8681
 8682					/* User MSR for this counter */
 8683				} else if (pkg_cstate_limit >= cai->pkg_cstate_limit && add_msr_counter(cpu, cai->msr) >= 0) {
 8684					cci->source[cai->rci_index] = COUNTER_SOURCE_MSR;
 8685					cci->msr[cai->rci_index] = cai->msr;
 8686				}
 8687			}
 8688
 8689			if (cci->source[cai->rci_index] != COUNTER_SOURCE_NONE) {
 8690				has_counter = true;
 8691				cores_visited[core_id] = true;
 8692				pkg_visited[pkg_id] = true;
 8693			}
 8694		}
 8695
 8696		/* If any CPU has access to the counter, make it present */
 8697		if (has_counter)
 8698			BIC_PRESENT(cai->bic_number);
 8699	}
 8700
 8701	free(cores_visited);
 8702	free(pkg_visited);
 8703}
 8704
 8705void cstate_perf_init(void)
 8706{
 8707	/*
 8708	 * If we don't have a C1 residency MSR, we calculate it "in software",
 8709	 * but we need APERF, MPERF too.
 8710	 */
 8711	const bool soft_c1 = !platform->has_msr_core_c1_res && has_amperf_access()
 8712	    && platform->supported_cstates & CC1;
 8713
 8714	if (soft_c1)
 8715		BIC_PRESENT(BIC_CPU_c1);
 8716
 8717	cstate_perf_init_(soft_c1);
 8718}
 8719
 8720void probe_cstates(void)
 8721{
 8722	probe_cst_limit();
 8723
 8724	if (platform->has_msr_module_c6_res_ms)
 8725		BIC_PRESENT(BIC_Mod_c6);
 8726
 8727	if (platform->has_ext_cst_msrs && !no_msr) {
 8728		BIC_PRESENT(BIC_Totl_c0);
 8729		BIC_PRESENT(BIC_Any_c0);
 8730		BIC_PRESENT(BIC_GFX_c0);
 8731		BIC_PRESENT(BIC_CPUGFX);
 8732	}
 8733
 8734	if (quiet)
 8735		return;
 8736
 8737	dump_power_ctl();
 8738	dump_cst_cfg();
 8739	decode_c6_demotion_policy_msr();
 8740	print_dev_latency();
 8741	dump_sysfs_cstate_config();
 8742	print_irtl();
 8743}
 8744
 8745void probe_lpi(void)
 8746{
 8747	if (!access("/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us", R_OK))
 8748		BIC_PRESENT(BIC_CPU_LPI);
 8749	else
 8750		BIC_NOT_PRESENT(BIC_CPU_LPI);
 8751
 8752	if (!access(sys_lpi_file_sysfs, R_OK)) {
 8753		sys_lpi_file = sys_lpi_file_sysfs;
 8754		BIC_PRESENT(BIC_SYS_LPI);
 8755	} else if (!access(sys_lpi_file_debugfs, R_OK)) {
 8756		sys_lpi_file = sys_lpi_file_debugfs;
 8757		BIC_PRESENT(BIC_SYS_LPI);
 8758	} else {
 8759		sys_lpi_file_sysfs = NULL;
 8760		BIC_NOT_PRESENT(BIC_SYS_LPI);
 8761	}
 8762
 8763}
 8764
 8765void probe_pstates(void)
 8766{
 8767	probe_bclk();
 8768
 8769	if (quiet)
 8770		return;
 8771
 8772	dump_platform_info();
 8773	dump_turbo_ratio_info();
 8774	dump_sysfs_pstate_config();
 8775	decode_misc_pwr_mgmt_msr();
 8776
 8777	for_all_cpus(print_hwp, ODD_COUNTERS);
 8778	for_all_cpus(print_epb, ODD_COUNTERS);
 8779	for_all_cpus(print_perf_limit, ODD_COUNTERS);
 8780}
 8781
 8782void process_cpuid()
 8783{
 8784	unsigned int eax, ebx, ecx, edx;
 8785	unsigned int fms, family, model, stepping, ecx_flags, edx_flags;
 8786	unsigned long long ucode_patch = 0;
 8787	bool ucode_patch_valid = false;
 8788
 8789	eax = ebx = ecx = edx = 0;
 8790
 8791	__cpuid(0, max_level, ebx, ecx, edx);
 8792
 8793	if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69)
 8794		genuine_intel = 1;
 8795	else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65)
 8796		authentic_amd = 1;
 8797	else if (ebx == 0x6f677948 && ecx == 0x656e6975 && edx == 0x6e65476e)
 8798		hygon_genuine = 1;
 8799
 8800	if (!quiet)
 8801		fprintf(outf, "CPUID(0): %.4s%.4s%.4s 0x%x CPUID levels\n", (char *)&ebx, (char *)&edx, (char *)&ecx, max_level);
 8802
 8803	__cpuid(1, fms, ebx, ecx, edx);
 8804	family = (fms >> 8) & 0xf;
 8805	model = (fms >> 4) & 0xf;
 8806	stepping = fms & 0xf;
 8807	if (family == 0xf)
 8808		family += (fms >> 20) & 0xff;
 8809	if (family >= 6)
 8810		model += ((fms >> 16) & 0xf) << 4;
 8811	ecx_flags = ecx;
 8812	edx_flags = edx;
 8813
 8814	if (!no_msr) {
 8815		if (get_msr(sched_getcpu(), MSR_IA32_UCODE_REV, &ucode_patch)) {
 8816			warnx("get_msr(UCODE)");
 8817		} else {
 8818			ucode_patch_valid = true;
 8819			if (!authentic_amd && !hygon_genuine)
 8820				ucode_patch >>= 32;
 8821		}
 8822	}
 8823
 8824	/*
 8825	 * check max extended function levels of CPUID.
 8826	 * This is needed to check for invariant TSC.
 8827	 * This check is valid for both Intel and AMD.
 8828	 */
 8829	ebx = ecx = edx = 0;
 8830	__cpuid(0x80000000, max_extended_level, ebx, ecx, edx);
 8831
 8832	if (!quiet) {
 8833		fprintf(outf, "CPUID(1): family:model:stepping 0x%x:%x:%x (%d:%d:%d)", family, model, stepping, family, model, stepping);
 8834		if (ucode_patch_valid)
 8835			fprintf(outf, " microcode 0x%x", (unsigned int)ucode_patch);
 8836		fputc('\n', outf);
 8837
 8838		fprintf(outf, "CPUID(0x80000000): max_extended_levels: 0x%x\n", max_extended_level);
 8839		fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s %s\n",
 8840			ecx_flags & (1 << 0) ? "SSE3" : "-",
 8841			ecx_flags & (1 << 3) ? "MONITOR" : "-",
 8842			ecx_flags & (1 << 6) ? "SMX" : "-",
 8843			ecx_flags & (1 << 7) ? "EIST" : "-",
 8844			ecx_flags & (1 << 8) ? "TM2" : "-",
 8845			edx_flags & (1 << 4) ? "TSC" : "-",
 8846			edx_flags & (1 << 5) ? "MSR" : "-",
 8847			edx_flags & (1 << 22) ? "ACPI-TM" : "-", edx_flags & (1 << 28) ? "HT" : "-", edx_flags & (1 << 29) ? "TM" : "-");
 8848	}
 8849
 8850	probe_platform_features(family, model);
 8851
 8852	if (!(edx_flags & (1 << 5)))
 8853		errx(1, "CPUID: no MSR");
 8854
 8855	if (max_extended_level >= 0x80000007) {
 8856
 8857		/*
 8858		 * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8
 8859		 * this check is valid for both Intel and AMD
 8860		 */
 8861		__cpuid(0x80000007, eax, ebx, ecx, edx);
 8862		has_invariant_tsc = edx & (1 << 8);
 8863	}
 8864
 8865	/*
 8866	 * APERF/MPERF is advertised by CPUID.EAX=0x6: ECX.bit0
 8867	 * this check is valid for both Intel and AMD
 8868	 */
 8869
 8870	__cpuid(0x6, eax, ebx, ecx, edx);
 8871	cpuid_has_aperf_mperf = ecx & (1 << 0);
 8872	do_dts = eax & (1 << 0);
 8873	if (do_dts)
 8874		BIC_PRESENT(BIC_CoreTmp);
 8875	has_turbo = eax & (1 << 1);
 8876	do_ptm = eax & (1 << 6);
 8877	if (do_ptm)
 8878		BIC_PRESENT(BIC_PkgTmp);
 8879	has_hwp = eax & (1 << 7);
 8880	has_hwp_notify = eax & (1 << 8);
 8881	has_hwp_activity_window = eax & (1 << 9);
 8882	has_hwp_epp = eax & (1 << 10);
 8883	has_hwp_pkg = eax & (1 << 11);
 8884	has_epb = ecx & (1 << 3);
 8885
 8886	if (!quiet)
 8887		fprintf(outf, "CPUID(6): %sAPERF, %sTURBO, %sDTS, %sPTM, %sHWP, "
 8888			"%sHWPnotify, %sHWPwindow, %sHWPepp, %sHWPpkg, %sEPB\n",
 8889			cpuid_has_aperf_mperf ? "" : "No-",
 8890			has_turbo ? "" : "No-",
 8891			do_dts ? "" : "No-",
 8892			do_ptm ? "" : "No-",
 8893			has_hwp ? "" : "No-",
 8894			has_hwp_notify ? "" : "No-",
 8895			has_hwp_activity_window ? "" : "No-", has_hwp_epp ? "" : "No-", has_hwp_pkg ? "" : "No-", has_epb ? "" : "No-");
 8896
 8897	if (!quiet)
 8898		decode_misc_enable_msr();
 8899
 8900	if (max_level >= 0x7 && !quiet) {
 8901		int has_sgx;
 8902
 8903		ecx = 0;
 8904
 8905		__cpuid_count(0x7, 0, eax, ebx, ecx, edx);
 8906
 8907		has_sgx = ebx & (1 << 2);
 8908
 8909		is_hybrid = edx & (1 << 15);
 8910
 8911		fprintf(outf, "CPUID(7): %sSGX %sHybrid\n", has_sgx ? "" : "No-", is_hybrid ? "" : "No-");
 8912
 8913		if (has_sgx)
 8914			decode_feature_control_msr();
 8915	}
 8916
 8917	if (max_level >= 0x15) {
 8918		unsigned int eax_crystal;
 8919		unsigned int ebx_tsc;
 8920
 8921		/*
 8922		 * CPUID 15H TSC/Crystal ratio, possibly Crystal Hz
 8923		 */
 8924		eax_crystal = ebx_tsc = crystal_hz = edx = 0;
 8925		__cpuid(0x15, eax_crystal, ebx_tsc, crystal_hz, edx);
 8926
 8927		if (ebx_tsc != 0) {
 8928			if (!quiet && (ebx != 0))
 8929				fprintf(outf, "CPUID(0x15): eax_crystal: %d ebx_tsc: %d ecx_crystal_hz: %d\n", eax_crystal, ebx_tsc, crystal_hz);
 8930
 8931			if (crystal_hz == 0)
 8932				crystal_hz = platform->crystal_freq;
 8933
 8934			if (crystal_hz) {
 8935				tsc_hz = (unsigned long long)crystal_hz *ebx_tsc / eax_crystal;
 8936				if (!quiet)
 8937					fprintf(outf, "TSC: %lld MHz (%d Hz * %d / %d / 1000000)\n",
 8938						tsc_hz / 1000000, crystal_hz, ebx_tsc, eax_crystal);
 8939			}
 8940		}
 8941	}
 8942	if (max_level >= 0x16) {
 8943		unsigned int base_mhz, max_mhz, bus_mhz, edx;
 8944
 8945		/*
 8946		 * CPUID 16H Base MHz, Max MHz, Bus MHz
 8947		 */
 8948		base_mhz = max_mhz = bus_mhz = edx = 0;
 8949
 8950		__cpuid(0x16, base_mhz, max_mhz, bus_mhz, edx);
 8951
 8952		bclk = bus_mhz;
 8953
 8954		base_hz = base_mhz * 1000000;
 8955		has_base_hz = 1;
 8956
 8957		if (platform->enable_tsc_tweak)
 8958			tsc_tweak = base_hz / tsc_hz;
 8959
 8960		if (!quiet)
 8961			fprintf(outf, "CPUID(0x16): base_mhz: %d max_mhz: %d bus_mhz: %d\n", base_mhz, max_mhz, bus_mhz);
 8962	}
 8963
 8964	if (cpuid_has_aperf_mperf)
 8965		aperf_mperf_multiplier = platform->need_perf_multiplier ? 1024 : 1;
 8966
 8967	BIC_PRESENT(BIC_IRQ);
 8968	BIC_PRESENT(BIC_NMI);
 8969	BIC_PRESENT(BIC_TSC_MHz);
 8970}
 8971
 8972static void counter_info_init(void)
 8973{
 8974	for (int i = 0; i < NUM_CSTATE_COUNTERS; ++i) {
 8975		struct cstate_counter_arch_info *const cai = &ccstate_counter_arch_infos[i];
 8976
 8977		if (platform->has_msr_knl_core_c6_residency && cai->msr == MSR_CORE_C6_RESIDENCY)
 8978			cai->msr = MSR_KNL_CORE_C6_RESIDENCY;
 8979
 8980		if (!platform->has_msr_core_c1_res && cai->msr == MSR_CORE_C1_RES)
 8981			cai->msr = 0;
 8982
 8983		if (platform->has_msr_atom_pkg_c6_residency && cai->msr == MSR_PKG_C6_RESIDENCY)
 8984			cai->msr = MSR_ATOM_PKG_C6_RESIDENCY;
 8985	}
 8986
 8987	for (int i = 0; i < NUM_MSR_COUNTERS; ++i) {
 8988		msr_counter_arch_infos[i].present = false;
 8989		msr_counter_arch_infos[i].needed = false;
 8990	}
 8991}
 8992
 8993void probe_pm_features(void)
 8994{
 8995	probe_pstates();
 8996
 8997	probe_cstates();
 8998
 8999	probe_lpi();
 9000
 9001	probe_intel_uncore_frequency();
 9002
 9003	probe_graphics();
 9004
 9005	probe_rapl();
 9006
 9007	probe_thermal();
 9008
 9009	if (platform->has_nhm_msrs && !no_msr)
 9010		BIC_PRESENT(BIC_SMI);
 9011
 9012	if (!quiet)
 9013		decode_misc_feature_control();
 9014}
 9015
 9016/* perf_llc_probe
 9017 *
 9018 * return 1 on success, else 0
 9019 */
 9020int has_perf_llc_access(void)
 9021{
 9022	int fd;
 9023
 9024	if (no_perf)
 9025		return 0;
 9026
 9027	fd = open_perf_counter(base_cpu, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES, -1, PERF_FORMAT_GROUP);
 9028	if (fd != -1)
 9029		close(fd);
 9030
 9031	if (fd == -1)
 9032		warnx("Failed to access %s. Some of the counters may not be available\n"
 9033		      "\tRun as root to enable them or use %s to disable the access explicitly", "perf LLC counters", "'--hide LLC' or '--no-perf'");
 9034
 9035	return (fd != -1);
 9036}
 9037
 9038void perf_llc_init(void)
 9039{
 9040	int cpu;
 9041	int retval;
 9042
 9043	if (no_perf)
 9044		return;
 9045	if (!(BIC_IS_ENABLED(BIC_LLC_RPS) && BIC_IS_ENABLED(BIC_LLC_HIT)))
 9046		return;
 9047
 9048	for (cpu = 0; cpu <= topo.max_cpu_num; ++cpu) {
 9049
 9050		if (cpu_is_not_allowed(cpu))
 9051			continue;
 9052
 9053		assert(fd_llc_percpu != 0);
 9054		fd_llc_percpu[cpu] = open_perf_counter(cpu, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES, -1, PERF_FORMAT_GROUP);
 9055		if (fd_llc_percpu[cpu] == -1) {
 9056			warnx("%s: perf REFS: failed to open counter on cpu%d", __func__, cpu);
 9057			free_fd_llc_percpu();
 9058			return;
 9059		}
 9060		assert(fd_llc_percpu != 0);
 9061		retval = open_perf_counter(cpu, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES, fd_llc_percpu[cpu], PERF_FORMAT_GROUP);
 9062		if (retval == -1) {
 9063			warnx("%s: perf MISS: failed to open counter on cpu%d", __func__, cpu);
 9064			free_fd_llc_percpu();
 9065			return;
 9066		}
 9067	}
 9068	BIC_PRESENT(BIC_LLC_RPS);
 9069	BIC_PRESENT(BIC_LLC_HIT);
 9070}
 9071
 9072/*
 9073 * in /dev/cpu/ return success for names that are numbers
 9074 * ie. filter out ".", "..", "microcode".
 9075 */
 9076int dir_filter(const struct dirent *dirp)
 9077{
 9078	if (isdigit(dirp->d_name[0]))
 9079		return 1;
 9080	else
 9081		return 0;
 9082}
 9083
 9084char *possible_file = "/sys/devices/system/cpu/possible";
 9085char possible_buf[1024];
 9086
 9087int initialize_cpu_possible_set(void)
 9088{
 9089	FILE *fp;
 9090
 9091	fp = fopen(possible_file, "r");
 9092	if (!fp) {
 9093		warn("open %s", possible_file);
 9094		return -1;
 9095	}
 9096	if (fread(possible_buf, sizeof(char), 1024, fp) == 0) {
 9097		warn("read %s", possible_file);
 9098		goto err;
 9099	}
 9100	if (parse_cpu_str(possible_buf, cpu_possible_set, cpu_possible_setsize)) {
 9101		warnx("%s: cpu str malformat %s\n", possible_file, cpu_effective_str);
 9102		goto err;
 9103	}
 9104	return 0;
 9105
 9106err:
 9107	fclose(fp);
 9108	return -1;
 9109}
 9110
 9111void topology_probe(bool startup)
 9112{
 9113	int i;
 9114	int max_core_id = 0;
 9115	int max_package_id = 0;
 9116	int max_siblings = 0;
 9117
 9118	/* Initialize num_cpus, max_cpu_num */
 9119	set_max_cpu_num();
 9120	topo.num_cpus = 0;
 9121	for_all_proc_cpus(count_cpus);
 9122	if (!summary_only)
 9123		BIC_PRESENT(BIC_CPU);
 9124
 9125	if (debug > 1)
 9126		fprintf(outf, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num);
 9127
 9128	cpus = calloc(1, (topo.max_cpu_num + 1) * sizeof(struct cpu_topology));
 9129	if (cpus == NULL)
 9130		err(1, "calloc cpus");
 9131
 9132	/*
 9133	 * Allocate and initialize cpu_present_set
 9134	 */
 9135	cpu_present_set = CPU_ALLOC((topo.max_cpu_num + 1));
 9136	if (cpu_present_set == NULL)
 9137		err(3, "CPU_ALLOC");
 9138	cpu_present_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
 9139	CPU_ZERO_S(cpu_present_setsize, cpu_present_set);
 9140	for_all_proc_cpus(mark_cpu_present);
 9141
 9142	/*
 9143	 * Allocate and initialize cpu_possible_set
 9144	 */
 9145	cpu_possible_set = CPU_ALLOC((topo.max_cpu_num + 1));
 9146	if (cpu_possible_set == NULL)
 9147		err(3, "CPU_ALLOC");
 9148	cpu_possible_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
 9149	CPU_ZERO_S(cpu_possible_setsize, cpu_possible_set);
 9150	initialize_cpu_possible_set();
 9151
 9152	/*
 9153	 * Allocate and initialize cpu_effective_set
 9154	 */
 9155	cpu_effective_set = CPU_ALLOC((topo.max_cpu_num + 1));
 9156	if (cpu_effective_set == NULL)
 9157		err(3, "CPU_ALLOC");
 9158	cpu_effective_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
 9159	CPU_ZERO_S(cpu_effective_setsize, cpu_effective_set);
 9160	update_effective_set(startup);
 9161
 9162	/*
 9163	 * Allocate and initialize cpu_allowed_set
 9164	 */
 9165	cpu_allowed_set = CPU_ALLOC((topo.max_cpu_num + 1));
 9166	if (cpu_allowed_set == NULL)
 9167		err(3, "CPU_ALLOC");
 9168	cpu_allowed_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
 9169	CPU_ZERO_S(cpu_allowed_setsize, cpu_allowed_set);
 9170
 9171	/*
 9172	 * Validate and update cpu_allowed_set.
 9173	 *
 9174	 * Make sure all cpus in cpu_subset are also in cpu_present_set during startup.
 9175	 * Give a warning when cpus in cpu_subset become unavailable at runtime.
 9176	 * Give a warning when cpus are not effective because of cgroup setting.
 9177	 *
 9178	 * cpu_allowed_set is the intersection of cpu_present_set/cpu_effective_set/cpu_subset.
 9179	 */
 9180	for (i = 0; i < CPU_SUBSET_MAXCPUS; ++i) {
 9181		if (cpu_subset && !CPU_ISSET_S(i, cpu_subset_size, cpu_subset))
 9182			continue;
 9183
 9184		if (!CPU_ISSET_S(i, cpu_present_setsize, cpu_present_set)) {
 9185			if (cpu_subset) {
 9186				/* cpus in cpu_subset must be in cpu_present_set during startup */
 9187				if (startup)
 9188					err(1, "cpu%d not present", i);
 9189				else
 9190					fprintf(stderr, "cpu%d not present\n", i);
 9191			}
 9192			continue;
 9193		}
 9194
 9195		if (CPU_COUNT_S(cpu_effective_setsize, cpu_effective_set)) {
 9196			if (!CPU_ISSET_S(i, cpu_effective_setsize, cpu_effective_set)) {
 9197				fprintf(stderr, "cpu%d not effective\n", i);
 9198				continue;
 9199			}
 9200		}
 9201
 9202		CPU_SET_S(i, cpu_allowed_setsize, cpu_allowed_set);
 9203	}
 9204
 9205	if (!CPU_COUNT_S(cpu_allowed_setsize, cpu_allowed_set))
 9206		err(-ENODEV, "No valid cpus found");
 9207	sched_setaffinity(0, cpu_allowed_setsize, cpu_allowed_set);
 9208
 9209	/*
 9210	 * Allocate and initialize cpu_affinity_set
 9211	 */
 9212	cpu_affinity_set = CPU_ALLOC((topo.max_cpu_num + 1));
 9213	if (cpu_affinity_set == NULL)
 9214		err(3, "CPU_ALLOC");
 9215	cpu_affinity_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
 9216	CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
 9217
 9218	for_all_proc_cpus(init_thread_id);
 9219
 9220	for_all_proc_cpus(set_cpu_hybrid_type);
 9221
 9222	/*
 9223	 * For online cpus
 9224	 * find max_core_id, max_package_id
 9225	 */
 9226	for (i = 0; i <= topo.max_cpu_num; ++i) {
 9227		int siblings;
 9228
 9229		if (cpu_is_not_present(i)) {
 9230			if (debug > 1)
 9231				fprintf(outf, "cpu%d NOT PRESENT\n", i);
 9232			continue;
 9233		}
 9234
 9235		cpus[i].logical_cpu_id = i;
 9236
 9237		/* get package information */
 9238		cpus[i].physical_package_id = get_physical_package_id(i);
 9239		if (cpus[i].physical_package_id > max_package_id)
 9240			max_package_id = cpus[i].physical_package_id;
 9241
 9242		/* get die information */
 9243		cpus[i].die_id = get_die_id(i);
 9244		if (cpus[i].die_id > topo.max_die_id)
 9245			topo.max_die_id = cpus[i].die_id;
 9246
 9247		/* get l3 information */
 9248		cpus[i].l3_id = get_l3_id(i);
 9249		if (cpus[i].l3_id > topo.max_l3_id)
 9250			topo.max_l3_id = cpus[i].l3_id;
 9251
 9252		/* get numa node information */
 9253		cpus[i].physical_node_id = get_physical_node_id(&cpus[i]);
 9254		if (cpus[i].physical_node_id > topo.max_node_num)
 9255			topo.max_node_num = cpus[i].physical_node_id;
 9256
 9257		/* get core information */
 9258		cpus[i].physical_core_id = get_core_id(i);
 9259		if (cpus[i].physical_core_id > max_core_id)
 9260			max_core_id = cpus[i].physical_core_id;
 9261
 9262		/* get thread information */
 9263		siblings = get_thread_siblings(&cpus[i]);
 9264		if (siblings > max_siblings)
 9265			max_siblings = siblings;
 9266		if (cpus[i].thread_id == 0)
 9267			topo.num_cores++;
 9268	}
 9269	topo.max_core_id = max_core_id;
 9270	topo.max_package_id = max_package_id;
 9271
 9272	topo.cores_per_node = max_core_id + 1;
 9273	if (debug > 1)
 9274		fprintf(outf, "max_core_id %d, sizing for %d cores per package\n", max_core_id, topo.cores_per_node);
 9275	if (!summary_only)
 9276		BIC_PRESENT(BIC_Core);
 9277
 9278	topo.num_die = topo.max_die_id + 1;
 9279	if (debug > 1)
 9280		fprintf(outf, "max_die_id %d, sizing for %d die\n", topo.max_die_id, topo.num_die);
 9281	if (!summary_only && topo.num_die > 1)
 9282		BIC_PRESENT(BIC_Die);
 9283
 9284	if (!summary_only && topo.max_l3_id > 0)
 9285		BIC_PRESENT(BIC_L3);
 9286
 9287	topo.num_packages = max_package_id + 1;
 9288	if (debug > 1)
 9289		fprintf(outf, "max_package_id %d, sizing for %d packages\n", max_package_id, topo.num_packages);
 9290	if (!summary_only && topo.num_packages > 1)
 9291		BIC_PRESENT(BIC_Package);
 9292
 9293	set_node_data();
 9294	if (debug > 1)
 9295		fprintf(outf, "nodes_per_pkg %d\n", topo.nodes_per_pkg);
 9296	if (!summary_only && topo.nodes_per_pkg > 1)
 9297		BIC_PRESENT(BIC_Node);
 9298
 9299	topo.threads_per_core = max_siblings;
 9300	if (debug > 1)
 9301		fprintf(outf, "max_siblings %d\n", max_siblings);
 9302
 9303	if (debug < 1)
 9304		return;
 9305
 9306	for (i = 0; i <= topo.max_cpu_num; ++i) {
 9307		if (cpu_is_not_present(i))
 9308			continue;
 9309		fprintf(outf,
 9310			"cpu %d pkg %d die %d l3 %d node %d lnode %d core %d thread %d\n",
 9311			i, cpus[i].physical_package_id, cpus[i].die_id, cpus[i].l3_id,
 9312			cpus[i].physical_node_id, cpus[i].logical_node_id, cpus[i].physical_core_id, cpus[i].thread_id);
 9313	}
 9314
 9315}
 9316
 9317void allocate_counters(struct thread_data **t, struct core_data **c, struct pkg_data **p)
 9318{
 9319	int i;
 9320	int num_cores = topo.cores_per_node * topo.nodes_per_pkg * topo.num_packages;
 9321	int num_threads = topo.threads_per_core * num_cores;
 9322
 9323	*t = calloc(num_threads, sizeof(struct thread_data));
 9324	if (*t == NULL)
 9325		goto error;
 9326
 9327	for (i = 0; i < num_threads; i++)
 9328		(*t)[i].cpu_id = -1;
 9329
 9330	*c = calloc(num_cores, sizeof(struct core_data));
 9331	if (*c == NULL)
 9332		goto error;
 9333
 9334	for (i = 0; i < num_cores; i++) {
 9335		(*c)[i].core_id = -1;
 9336		(*c)[i].base_cpu = -1;
 9337	}
 9338
 9339	*p = calloc(topo.num_packages, sizeof(struct pkg_data));
 9340	if (*p == NULL)
 9341		goto error;
 9342
 9343	for (i = 0; i < topo.num_packages; i++) {
 9344		(*p)[i].package_id = i;
 9345		(*p)[i].base_cpu = -1;
 9346	}
 9347
 9348	return;
 9349error:
 9350	err(1, "calloc counters");
 9351}
 9352
 9353/*
 9354 * init_counter()
 9355 *
 9356 * set FIRST_THREAD_IN_CORE and FIRST_CORE_IN_PACKAGE
 9357 */
 9358void init_counter(struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base, int cpu_id)
 9359{
 9360	int pkg_id = cpus[cpu_id].physical_package_id;
 9361	int node_id = cpus[cpu_id].logical_node_id;
 9362	int core_id = cpus[cpu_id].physical_core_id;
 9363	int thread_id = cpus[cpu_id].thread_id;
 9364	struct thread_data *t;
 9365	struct core_data *c;
 9366
 9367	/* Workaround for systems where physical_node_id==-1
 9368	 * and logical_node_id==(-1 - topo.num_cpus)
 9369	 */
 9370	if (node_id < 0)
 9371		node_id = 0;
 9372
 9373	t = GET_THREAD(thread_base, thread_id, core_id, node_id, pkg_id);
 9374	c = GET_CORE(core_base, core_id, node_id, pkg_id);
 9375
 9376	t->cpu_id = cpu_id;
 9377	if (!cpu_is_not_allowed(cpu_id)) {
 9378
 9379		if (c->base_cpu < 0)
 9380			c->base_cpu = t->cpu_id;
 9381		if (pkg_base[pkg_id].base_cpu < 0)
 9382			pkg_base[pkg_id].base_cpu = t->cpu_id;
 9383	}
 9384
 9385	c->core_id = core_id;
 9386	pkg_base[pkg_id].package_id = pkg_id;
 9387}
 9388
 9389int initialize_counters(int cpu_id)
 9390{
 9391	init_counter(EVEN_COUNTERS, cpu_id);
 9392	init_counter(ODD_COUNTERS, cpu_id);
 9393	return 0;
 9394}
 9395
 9396void allocate_output_buffer()
 9397{
 9398	output_buffer = calloc(1, (1 + topo.num_cpus) * 2048);
 9399	outp = output_buffer;
 9400	if (outp == NULL)
 9401		err(-1, "calloc output buffer");
 9402}
 9403
 9404void allocate_fd_percpu(void)
 9405{
 9406	fd_percpu = calloc(topo.max_cpu_num + 1, sizeof(int));
 9407	if (fd_percpu == NULL)
 9408		err(-1, "calloc fd_percpu");
 9409}
 9410
 9411void allocate_irq_buffers(void)
 9412{
 9413	irq_column_2_cpu = calloc(topo.num_cpus, sizeof(int));
 9414	if (irq_column_2_cpu == NULL)
 9415		err(-1, "calloc %d", topo.num_cpus);
 9416
 9417	irqs_per_cpu = calloc(topo.max_cpu_num + 1, sizeof(int));
 9418	if (irqs_per_cpu == NULL)
 9419		err(-1, "calloc %d IRQ", topo.max_cpu_num + 1);
 9420
 9421	nmi_per_cpu = calloc(topo.max_cpu_num + 1, sizeof(int));
 9422	if (nmi_per_cpu == NULL)
 9423		err(-1, "calloc %d NMI", topo.max_cpu_num + 1);
 9424}
 9425
 9426int update_topo(PER_THREAD_PARAMS)
 9427{
 9428	topo.allowed_cpus++;
 9429	if ((int)t->cpu_id == c->base_cpu)
 9430		topo.allowed_cores++;
 9431	if ((int)t->cpu_id == p->base_cpu)
 9432		topo.allowed_packages++;
 9433
 9434	return 0;
 9435}
 9436
 9437void topology_update(void)
 9438{
 9439	topo.allowed_cpus = 0;
 9440	topo.allowed_cores = 0;
 9441	topo.allowed_packages = 0;
 9442	for_all_cpus(update_topo, ODD_COUNTERS);
 9443}
 9444
 9445void setup_all_buffers(bool startup)
 9446{
 9447	topology_probe(startup);
 9448	allocate_irq_buffers();
 9449	allocate_fd_percpu();
 9450	allocate_counters(&thread_even, &core_even, &package_even);
 9451	allocate_counters(&thread_odd, &core_odd, &package_odd);
 9452	allocate_output_buffer();
 9453	for_all_proc_cpus(initialize_counters);
 9454	topology_update();
 9455}
 9456
 9457void set_base_cpu(void)
 9458{
 9459	int i;
 9460
 9461	for (i = 0; i < topo.max_cpu_num + 1; ++i) {
 9462		if (cpu_is_not_allowed(i))
 9463			continue;
 9464		base_cpu = i;
 9465		if (debug > 1)
 9466			fprintf(outf, "base_cpu = %d\n", base_cpu);
 9467		return;
 9468	}
 9469	err(-ENODEV, "No valid cpus found");
 9470}
 9471
 9472bool has_added_counters(void)
 9473{
 9474	/*
 9475	 * It only makes sense to call this after the command line is parsed,
 9476	 * otherwise sys structure is not populated.
 9477	 */
 9478
 9479	return sys.added_core_counters | sys.added_thread_counters | sys.added_package_counters;
 9480}
 9481
 9482void check_msr_access(void)
 9483{
 9484	check_msr_driver();
 9485	check_msr_permission();
 9486
 9487	if (no_msr)
 9488		bic_disable_msr_access();
 9489}
 9490
 9491void check_perf_access(void)
 9492{
 9493	if (BIC_IS_ENABLED(BIC_IPC))
 9494		if (!has_perf_instr_count_access())
 9495			no_perf = 1;
 9496
 9497	if (BIC_IS_ENABLED(BIC_LLC_RPS) || BIC_IS_ENABLED(BIC_LLC_HIT))
 9498		if (!has_perf_llc_access())
 9499			no_perf = 1;
 9500
 9501	if (no_perf)
 9502		bic_disable_perf_access();
 9503}
 9504
 9505bool perf_has_hybrid_devices(void)
 9506{
 9507	/*
 9508	 *  0: unknown
 9509	 *  1: has separate perf device for p and e core
 9510	 * -1: doesn't have separate perf device for p and e core
 9511	 */
 9512	static int cached;
 9513
 9514	if (cached > 0)
 9515		return true;
 9516
 9517	if (cached < 0)
 9518		return false;
 9519
 9520	if (access("/sys/bus/event_source/devices/cpu_core", F_OK)) {
 9521		cached = -1;
 9522		return false;
 9523	}
 9524
 9525	if (access("/sys/bus/event_source/devices/cpu_atom", F_OK)) {
 9526		cached = -1;
 9527		return false;
 9528	}
 9529
 9530	cached = 1;
 9531	return true;
 9532}
 9533
 9534int added_perf_counters_init_(struct perf_counter_info *pinfo)
 9535{
 9536	size_t num_domains = 0;
 9537	unsigned int next_domain;
 9538	bool *domain_visited;
 9539	unsigned int perf_type, perf_config;
 9540	double perf_scale;
 9541	int fd_perf;
 9542
 9543	if (!pinfo)
 9544		return 0;
 9545
 9546	const size_t max_num_domains = MAX(topo.max_cpu_num + 1, MAX(topo.max_core_id + 1, topo.max_package_id + 1));
 9547
 9548	domain_visited = calloc(max_num_domains, sizeof(*domain_visited));
 9549
 9550	while (pinfo) {
 9551		switch (pinfo->scope) {
 9552		case SCOPE_CPU:
 9553			num_domains = topo.max_cpu_num + 1;
 9554			break;
 9555
 9556		case SCOPE_CORE:
 9557			num_domains = topo.max_core_id + 1;
 9558			break;
 9559
 9560		case SCOPE_PACKAGE:
 9561			num_domains = topo.max_package_id + 1;
 9562			break;
 9563		}
 9564
 9565		/* Allocate buffer for file descriptor for each domain. */
 9566		pinfo->fd_perf_per_domain = calloc(num_domains, sizeof(*pinfo->fd_perf_per_domain));
 9567		if (!pinfo->fd_perf_per_domain)
 9568			errx(1, "%s: alloc %s", __func__, "fd_perf_per_domain");
 9569
 9570		for (size_t i = 0; i < num_domains; ++i)
 9571			pinfo->fd_perf_per_domain[i] = -1;
 9572
 9573		pinfo->num_domains = num_domains;
 9574		pinfo->scale = 1.0;
 9575
 9576		memset(domain_visited, 0, max_num_domains * sizeof(*domain_visited));
 9577
 9578		for (int cpu = 0; cpu < topo.max_cpu_num + 1; ++cpu) {
 9579
 9580			next_domain = cpu_to_domain(pinfo, cpu);
 9581
 9582			assert(next_domain < num_domains);
 9583
 9584			if (cpu_is_not_allowed(cpu))
 9585				continue;
 9586
 9587			if (domain_visited[next_domain])
 9588				continue;
 9589
 9590			/*
 9591			 * Intel hybrid platforms expose different perf devices for P and E cores.
 9592			 * Instead of one, "/sys/bus/event_source/devices/cpu" device, there are
 9593			 * "/sys/bus/event_source/devices/{cpu_core,cpu_atom}".
 9594			 *
 9595			 * This makes it more complicated to the user, because most of the counters
 9596			 * are available on both and have to be handled manually, otherwise.
 9597			 *
 9598			 * Code below, allow user to use the old "cpu" name, which is translated accordingly.
 9599			 */
 9600			const char *perf_device = pinfo->device;
 9601
 9602			if (strcmp(perf_device, "cpu") == 0 && perf_has_hybrid_devices()) {
 9603				switch (cpus[cpu].type) {
 9604				case INTEL_PCORE_TYPE:
 9605					perf_device = "cpu_core";
 9606					break;
 9607
 9608				case INTEL_ECORE_TYPE:
 9609					perf_device = "cpu_atom";
 9610					break;
 9611
 9612				default:	/* Don't change, we will probably fail and report a problem soon. */
 9613					break;
 9614				}
 9615			}
 9616
 9617			perf_type = read_perf_type(perf_device);
 9618			if (perf_type == (unsigned int)-1) {
 9619				warnx("%s: perf/%s/%s: failed to read %s", __func__, perf_device, pinfo->event, "type");
 9620				continue;
 9621			}
 9622
 9623			perf_config = read_perf_config(perf_device, pinfo->event);
 9624			if (perf_config == (unsigned int)-1) {
 9625				warnx("%s: perf/%s/%s: failed to read %s", __func__, perf_device, pinfo->event, "config");
 9626				continue;
 9627			}
 9628
 9629			/* Scale is not required, some counters just don't have it. */
 9630			perf_scale = read_perf_scale(perf_device, pinfo->event);
 9631			if (perf_scale == 0.0)
 9632				perf_scale = 1.0;
 9633
 9634			fd_perf = open_perf_counter(cpu, perf_type, perf_config, -1, 0);
 9635			if (fd_perf == -1) {
 9636				warnx("%s: perf/%s/%s: failed to open counter on cpu%d", __func__, perf_device, pinfo->event, cpu);
 9637				continue;
 9638			}
 9639
 9640			domain_visited[next_domain] = 1;
 9641			pinfo->fd_perf_per_domain[next_domain] = fd_perf;
 9642			pinfo->scale = perf_scale;
 9643
 9644			if (debug)
 9645				fprintf(stderr, "Add perf/%s/%s cpu%d: %d\n", perf_device, pinfo->event, cpu, pinfo->fd_perf_per_domain[next_domain]);
 9646		}
 9647
 9648		pinfo = pinfo->next;
 9649	}
 9650
 9651	free(domain_visited);
 9652
 9653	return 0;
 9654}
 9655
 9656void added_perf_counters_init(void)
 9657{
 9658	if (added_perf_counters_init_(sys.perf_tp))
 9659		errx(1, "%s: %s", __func__, "thread");
 9660
 9661	if (added_perf_counters_init_(sys.perf_cp))
 9662		errx(1, "%s: %s", __func__, "core");
 9663
 9664	if (added_perf_counters_init_(sys.perf_pp))
 9665		errx(1, "%s: %s", __func__, "package");
 9666}
 9667
 9668int parse_telem_info_file(int fd_dir, const char *info_filename, const char *format, unsigned long *output)
 9669{
 9670	int fd_telem_info;
 9671	FILE *file_telem_info;
 9672	unsigned long value;
 9673
 9674	fd_telem_info = openat(fd_dir, info_filename, O_RDONLY);
 9675	if (fd_telem_info == -1)
 9676		return -1;
 9677
 9678	file_telem_info = fdopen(fd_telem_info, "r");
 9679	if (file_telem_info == NULL) {
 9680		close(fd_telem_info);
 9681		return -1;
 9682	}
 9683
 9684	if (fscanf(file_telem_info, format, &value) != 1) {
 9685		fclose(file_telem_info);
 9686		return -1;
 9687	}
 9688
 9689	fclose(file_telem_info);
 9690
 9691	*output = value;
 9692
 9693	return 0;
 9694}
 9695
 9696struct pmt_mmio *pmt_mmio_open(unsigned int target_guid)
 9697{
 9698	struct pmt_diriter_t pmt_iter;
 9699	const struct dirent *entry;
 9700	struct stat st;
 9701	int fd_telem_dir, fd_pmt;
 9702	unsigned long guid, size, offset;
 9703	size_t mmap_size;
 9704	void *mmio;
 9705	struct pmt_mmio *head = NULL, *last = NULL;
 9706	struct pmt_mmio *new_pmt = NULL;
 9707
 9708	if (stat(SYSFS_TELEM_PATH, &st) == -1)
 9709		return NULL;
 9710
 9711	pmt_diriter_init(&pmt_iter);
 9712	entry = pmt_diriter_begin(&pmt_iter, SYSFS_TELEM_PATH);
 9713	if (!entry) {
 9714		pmt_diriter_remove(&pmt_iter);
 9715		return NULL;
 9716	}
 9717
 9718	for (; entry != NULL; entry = pmt_diriter_next(&pmt_iter)) {
 9719		if (fstatat(dirfd(pmt_iter.dir), entry->d_name, &st, 0) == -1)
 9720			break;
 9721
 9722		if (!S_ISDIR(st.st_mode))
 9723			continue;
 9724
 9725		fd_telem_dir = openat(dirfd(pmt_iter.dir), entry->d_name, O_RDONLY);
 9726		if (fd_telem_dir == -1)
 9727			break;
 9728
 9729		if (parse_telem_info_file(fd_telem_dir, "guid", "%lx", &guid)) {
 9730			close(fd_telem_dir);
 9731			break;
 9732		}
 9733
 9734		if (parse_telem_info_file(fd_telem_dir, "size", "%lu", &size)) {
 9735			close(fd_telem_dir);
 9736			break;
 9737		}
 9738
 9739		if (guid != target_guid) {
 9740			close(fd_telem_dir);
 9741			continue;
 9742		}
 9743
 9744		if (parse_telem_info_file(fd_telem_dir, "offset", "%lu", &offset)) {
 9745			close(fd_telem_dir);
 9746			break;
 9747		}
 9748
 9749		assert(offset == 0);
 9750
 9751		fd_pmt = openat(fd_telem_dir, "telem", O_RDONLY);
 9752		if (fd_pmt == -1)
 9753			goto loop_cleanup_and_break;
 9754
 9755		mmap_size = ROUND_UP_TO_PAGE_SIZE(size);
 9756		mmio = mmap(0, mmap_size, PROT_READ, MAP_SHARED, fd_pmt, 0);
 9757		if (mmio != MAP_FAILED) {
 9758			if (debug)
 9759				fprintf(stderr, "%s: 0x%lx mmaped at: %p\n", __func__, guid, mmio);
 9760
 9761			new_pmt = calloc(1, sizeof(*new_pmt));
 9762
 9763			if (!new_pmt) {
 9764				fprintf(stderr, "%s: Failed to allocate pmt_mmio\n", __func__);
 9765				exit(1);
 9766			}
 9767
 9768			/*
 9769			 * Create linked list of mmaped regions,
 9770			 * but preserve the ordering from sysfs.
 9771			 * Ordering is important for the user to
 9772			 * use the seq=%u parameter when adding a counter.
 9773			 */
 9774			new_pmt->guid = guid;
 9775			new_pmt->mmio_base = mmio;
 9776			new_pmt->pmt_offset = offset;
 9777			new_pmt->size = size;
 9778			new_pmt->next = pmt_mmios;
 9779
 9780			if (last)
 9781				last->next = new_pmt;
 9782			else
 9783				head = new_pmt;
 9784
 9785			last = new_pmt;
 9786		}
 9787
 9788loop_cleanup_and_break:
 9789		close(fd_pmt);
 9790		close(fd_telem_dir);
 9791	}
 9792
 9793	pmt_diriter_remove(&pmt_iter);
 9794
 9795	/*
 9796	 * If we found something, stick just
 9797	 * created linked list to the front.
 9798	 */
 9799	if (head)
 9800		pmt_mmios = head;
 9801
 9802	return head;
 9803}
 9804
 9805struct pmt_mmio *pmt_mmio_find(unsigned int guid)
 9806{
 9807	struct pmt_mmio *pmmio = pmt_mmios;
 9808
 9809	while (pmmio) {
 9810		if (pmmio->guid == guid)
 9811			return pmmio;
 9812
 9813		pmmio = pmmio->next;
 9814	}
 9815
 9816	return NULL;
 9817}
 9818
 9819void *pmt_get_counter_pointer(struct pmt_mmio *pmmio, unsigned long counter_offset)
 9820{
 9821	char *ret;
 9822
 9823	/* Get base of mmaped PMT file. */
 9824	ret = (char *)pmmio->mmio_base;
 9825
 9826	/*
 9827	 * Apply PMT MMIO offset to obtain beginning of the mmaped telemetry data.
 9828	 * It's not guaranteed that the mmaped memory begins with the telemetry data
 9829	 *      - we might have to apply the offset first.
 9830	 */
 9831	ret += pmmio->pmt_offset;
 9832
 9833	/* Apply the counter offset to get the address to the mmaped counter. */
 9834	ret += counter_offset;
 9835
 9836	return ret;
 9837}
 9838
 9839struct pmt_mmio *pmt_add_guid(unsigned int guid, unsigned int seq)
 9840{
 9841	struct pmt_mmio *ret;
 9842
 9843	ret = pmt_mmio_find(guid);
 9844	if (!ret)
 9845		ret = pmt_mmio_open(guid);
 9846
 9847	while (ret && seq) {
 9848		ret = ret->next;
 9849		--seq;
 9850	}
 9851
 9852	return ret;
 9853}
 9854
 9855enum pmt_open_mode {
 9856	PMT_OPEN_TRY,		/* Open failure is not an error. */
 9857	PMT_OPEN_REQUIRED,	/* Open failure is a fatal error. */
 9858};
 9859
 9860struct pmt_counter *pmt_find_counter(struct pmt_counter *pcounter, const char *name)
 9861{
 9862	while (pcounter) {
 9863		if (strcmp(pcounter->name, name) == 0)
 9864			break;
 9865
 9866		pcounter = pcounter->next;
 9867	}
 9868
 9869	return pcounter;
 9870}
 9871
 9872struct pmt_counter **pmt_get_scope_root(enum counter_scope scope)
 9873{
 9874	switch (scope) {
 9875	case SCOPE_CPU:
 9876		return &sys.pmt_tp;
 9877	case SCOPE_CORE:
 9878		return &sys.pmt_cp;
 9879	case SCOPE_PACKAGE:
 9880		return &sys.pmt_pp;
 9881	}
 9882
 9883	__builtin_unreachable();
 9884}
 9885
 9886void pmt_counter_add_domain(struct pmt_counter *pcounter, unsigned long *pmmio, unsigned int domain_id)
 9887{
 9888	/* Make sure the new domain fits. */
 9889	if (domain_id >= pcounter->num_domains)
 9890		pmt_counter_resize(pcounter, domain_id + 1);
 9891
 9892	assert(pcounter->domains);
 9893	assert(domain_id < pcounter->num_domains);
 9894
 9895	pcounter->domains[domain_id].pcounter = pmmio;
 9896}
 9897
 9898int pmt_add_counter(unsigned int guid, unsigned int seq, const char *name, enum pmt_datatype type,
 9899		    unsigned int lsb, unsigned int msb, unsigned int offset, enum counter_scope scope,
 9900		    enum counter_format format, unsigned int domain_id, enum pmt_open_mode mode)
 9901{
 9902	struct pmt_mmio *mmio;
 9903	struct pmt_counter *pcounter;
 9904	struct pmt_counter **const pmt_root = pmt_get_scope_root(scope);
 9905	bool new_counter = false;
 9906	int conflict = 0;
 9907
 9908	if (lsb > msb) {
 9909		fprintf(stderr, "%s: %s: `%s` must be satisfied\n", __func__, "lsb <= msb", name);
 9910		exit(1);
 9911	}
 9912
 9913	if (msb >= 64) {
 9914		fprintf(stderr, "%s: %s: `%s` must be satisfied\n", __func__, "msb < 64", name);
 9915		exit(1);
 9916	}
 9917
 9918	mmio = pmt_add_guid(guid, seq);
 9919	if (!mmio) {
 9920		if (mode != PMT_OPEN_TRY) {
 9921			fprintf(stderr, "%s: failed to map PMT MMIO for guid %x, seq %u\n", __func__, guid, seq);
 9922			exit(1);
 9923		}
 9924
 9925		return 1;
 9926	}
 9927
 9928	if (offset >= mmio->size) {
 9929		if (mode != PMT_OPEN_TRY) {
 9930			fprintf(stderr, "%s: offset %u outside of PMT MMIO size %u\n", __func__, offset, mmio->size);
 9931			exit(1);
 9932		}
 9933
 9934		return 1;
 9935	}
 9936
 9937	pcounter = pmt_find_counter(*pmt_root, name);
 9938	if (!pcounter) {
 9939		pcounter = calloc(1, sizeof(*pcounter));
 9940		new_counter = true;
 9941	}
 9942
 9943	if (new_counter) {
 9944		strncpy(pcounter->name, name, ARRAY_SIZE(pcounter->name) - 1);
 9945		pcounter->type = type;
 9946		pcounter->scope = scope;
 9947		pcounter->lsb = lsb;
 9948		pcounter->msb = msb;
 9949		pcounter->format = format;
 9950	} else {
 9951		conflict += pcounter->type != type;
 9952		conflict += pcounter->scope != scope;
 9953		conflict += pcounter->lsb != lsb;
 9954		conflict += pcounter->msb != msb;
 9955		conflict += pcounter->format != format;
 9956	}
 9957
 9958	if (conflict) {
 9959		fprintf(stderr, "%s: conflicting parameters for the PMT counter with the same name %s\n", __func__, name);
 9960		exit(1);
 9961	}
 9962
 9963	pmt_counter_add_domain(pcounter, pmt_get_counter_pointer(mmio, offset), domain_id);
 9964
 9965	if (new_counter) {
 9966		pcounter->next = *pmt_root;
 9967		*pmt_root = pcounter;
 9968	}
 9969
 9970	return 0;
 9971}
 9972
 9973void pmt_init(void)
 9974{
 9975	int cpu_num;
 9976	unsigned long seq, offset, mod_num;
 9977
 9978	if (BIC_IS_ENABLED(BIC_Diec6)) {
 9979		pmt_add_counter(PMT_MTL_DC6_GUID, PMT_MTL_DC6_SEQ, "Die%c6", PMT_TYPE_XTAL_TIME,
 9980				PMT_COUNTER_MTL_DC6_LSB, PMT_COUNTER_MTL_DC6_MSB, PMT_COUNTER_MTL_DC6_OFFSET,
 9981				SCOPE_PACKAGE, FORMAT_DELTA, 0, PMT_OPEN_TRY);
 9982	}
 9983
 9984	if (BIC_IS_ENABLED(BIC_CPU_c1e)) {
 9985		seq = 0;
 9986		offset = PMT_COUNTER_CWF_MC1E_OFFSET_BASE;
 9987		mod_num = 0;	/* Relative module number for current PMT file. */
 9988
 9989		/* Open the counter for each CPU. */
 9990		for (cpu_num = 0; cpu_num < topo.max_cpu_num;) {
 9991
 9992			if (cpu_is_not_allowed(cpu_num))
 9993				goto next_loop_iter;
 9994
 9995			/*
 9996			 * Set the scope to CPU, even though CWF report the counter per module.
 9997			 * CPUs inside the same module will read from the same location, instead of reporting zeros.
 9998			 *
 9999			 * CWF with newer firmware might require a PMT_TYPE_XTAL_TIME intead of PMT_TYPE_TCORE_CLOCK.
10000			 */
10001			pmt_add_counter(PMT_CWF_MC1E_GUID, seq, "CPU%c1e", PMT_TYPE_TCORE_CLOCK,
10002					PMT_COUNTER_CWF_MC1E_LSB, PMT_COUNTER_CWF_MC1E_MSB, offset, SCOPE_CPU, FORMAT_DELTA, cpu_num, PMT_OPEN_TRY);
10003
10004			/*
10005			 * Rather complex logic for each time we go to the next loop iteration,
10006			 * so keep it as a label.
10007			 */
10008next_loop_iter:
10009			/*
10010			 * Advance the cpu number and check if we should also advance offset to
10011			 * the next counter inside the PMT file.
10012			 *
10013			 * On Clearwater Forest platform, the counter is reported per module,
10014			 * so open the same counter for all of the CPUs inside the module.
10015			 * That way, reported table show the correct value for all of the CPUs inside the module,
10016			 * instead of zeros.
10017			 */
10018			++cpu_num;
10019			if (cpu_num % PMT_COUNTER_CWF_CPUS_PER_MODULE == 0) {
10020				offset += PMT_COUNTER_CWF_MC1E_OFFSET_INCREMENT;
10021				++mod_num;
10022			}
10023
10024			/*
10025			 * There are PMT_COUNTER_CWF_MC1E_NUM_MODULES_PER_FILE in each PMT file.
10026			 *
10027			 * If that number is reached, seq must be incremented to advance to the next file in a sequence.
10028			 * Offset inside that file and a module counter has to be reset.
10029			 */
10030			if (mod_num == PMT_COUNTER_CWF_MC1E_NUM_MODULES_PER_FILE) {
10031				++seq;
10032				offset = PMT_COUNTER_CWF_MC1E_OFFSET_BASE;
10033				mod_num = 0;
10034			}
10035		}
10036	}
10037}
10038
10039void turbostat_init()
10040{
10041	setup_all_buffers(true);
10042	set_base_cpu();
10043	check_msr_access();
10044	check_perf_access();
10045	process_cpuid();
10046	counter_info_init();
10047	probe_pm_features();
10048	msr_perf_init();
10049	linux_perf_init();
10050	rapl_perf_init();
10051	cstate_perf_init();
10052	perf_llc_init();
10053	added_perf_counters_init();
10054	pmt_init();
10055
10056	for_all_cpus(get_cpu_type, ODD_COUNTERS);
10057	for_all_cpus(get_cpu_type, EVEN_COUNTERS);
10058
10059	if (BIC_IS_ENABLED(BIC_IPC) && has_aperf_access && get_instr_count_fd(base_cpu) != -1)
10060		BIC_PRESENT(BIC_IPC);
10061
10062	/*
10063	 * If TSC tweak is needed, but couldn't get it,
10064	 * disable more BICs, since it can't be reported accurately.
10065	 */
10066	if (platform->enable_tsc_tweak && !has_base_hz) {
10067		CLR_BIC(BIC_Busy, &bic_enabled);
10068		CLR_BIC(BIC_Bzy_MHz, &bic_enabled);
10069	}
10070}
10071
10072void affinitize_child(void)
10073{
10074	/* Prefer cpu_possible_set, if available */
10075	if (sched_setaffinity(0, cpu_possible_setsize, cpu_possible_set)) {
10076		warn("sched_setaffinity cpu_possible_set");
10077
10078		/* Otherwise, allow child to run on same cpu set as turbostat */
10079		if (sched_setaffinity(0, cpu_allowed_setsize, cpu_allowed_set))
10080			warn("sched_setaffinity cpu_allowed_set");
10081	}
10082}
10083
10084int fork_it(char **argv)
10085{
10086	pid_t child_pid;
10087	int status;
10088
10089	snapshot_proc_sysfs_files();
10090	status = for_all_cpus(get_counters, EVEN_COUNTERS);
10091	first_counter_read = 0;
10092	if (status)
10093		exit(status);
10094	gettimeofday(&tv_even, (struct timezone *)NULL);
10095
10096	child_pid = fork();
10097	if (!child_pid) {
10098		/* child */
10099		affinitize_child();
10100		execvp(argv[0], argv);
10101		err(errno, "exec %s", argv[0]);
10102	} else {
10103
10104		/* parent */
10105		if (child_pid == -1)
10106			err(1, "fork");
10107
10108		signal(SIGINT, SIG_IGN);
10109		signal(SIGQUIT, SIG_IGN);
10110		if (waitpid(child_pid, &status, 0) == -1)
10111			err(status, "waitpid");
10112
10113		if (WIFEXITED(status))
10114			status = WEXITSTATUS(status);
10115	}
10116	/*
10117	 * n.b. fork_it() does not check for errors from for_all_cpus()
10118	 * because re-starting is problematic when forking
10119	 */
10120	snapshot_proc_sysfs_files();
10121	for_all_cpus(get_counters, ODD_COUNTERS);
10122	gettimeofday(&tv_odd, (struct timezone *)NULL);
10123	timersub(&tv_odd, &tv_even, &tv_delta);
10124	if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS))
10125		fprintf(outf, "%s: Counter reset detected\n", progname);
10126	delta_platform(&platform_counters_odd, &platform_counters_even);
10127
10128	compute_average(EVEN_COUNTERS);
10129	format_all_counters(EVEN_COUNTERS);
10130
10131	fprintf(outf, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec / 1000000.0);
10132
10133	flush_output_stderr();
10134
10135	return status;
10136}
10137
10138int get_and_dump_counters(void)
10139{
10140	int status;
10141
10142	snapshot_proc_sysfs_files();
10143	status = for_all_cpus(get_counters, ODD_COUNTERS);
10144	if (status)
10145		return status;
10146
10147	status = for_all_cpus(dump_counters, ODD_COUNTERS);
10148	if (status)
10149		return status;
10150
10151	flush_output_stdout();
10152
10153	return status;
10154}
10155
10156void print_version()
10157{
10158	fprintf(outf, "turbostat version 2025.12.02 - Len Brown <lenb@kernel.org>\n");
10159}
10160
10161#define COMMAND_LINE_SIZE 2048
10162
10163void print_bootcmd(void)
10164{
10165	char bootcmd[COMMAND_LINE_SIZE];
10166	FILE *fp;
10167	int ret;
10168
10169	memset(bootcmd, 0, COMMAND_LINE_SIZE);
10170	fp = fopen("/proc/cmdline", "r");
10171	if (!fp)
10172		return;
10173
10174	ret = fread(bootcmd, sizeof(char), COMMAND_LINE_SIZE - 1, fp);
10175	if (ret) {
10176		bootcmd[ret] = '\0';
10177		/* the last character is already '\n' */
10178		fprintf(outf, "Kernel command line: %s", bootcmd);
10179	}
10180
10181	fclose(fp);
10182}
10183
10184struct msr_counter *find_msrp_by_name(struct msr_counter *head, char *name)
10185{
10186	struct msr_counter *mp;
10187
10188	for (mp = head; mp; mp = mp->next) {
10189		if (debug)
10190			fprintf(stderr, "%s: %s %s\n", __func__, name, mp->name);
10191		if (!strcmp(name, mp->name))
10192			return mp;
10193	}
10194	return NULL;
10195}
10196
10197int add_counter(unsigned int msr_num, char *path, char *name,
10198		unsigned int width, enum counter_scope scope, enum counter_type type, enum counter_format format, int flags, int id)
10199{
10200	struct msr_counter *msrp;
10201
10202	if (no_msr && msr_num)
10203		errx(1, "Requested MSR counter 0x%x, but in --no-msr mode", msr_num);
10204
10205	if (debug)
10206		fprintf(stderr, "%s(msr%d, %s, %s, width%d, scope%d, type%d, format%d, flags%x, id%d)\n",
10207			__func__, msr_num, path, name, width, scope, type, format, flags, id);
10208
10209	switch (scope) {
10210
10211	case SCOPE_CPU:
10212		msrp = find_msrp_by_name(sys.tp, name);
10213		if (msrp) {
10214			if (debug)
10215				fprintf(stderr, "%s: %s FOUND\n", __func__, name);
10216			break;
10217		}
10218		if (sys.added_thread_counters++ >= MAX_ADDED_THREAD_COUNTERS) {
10219			warnx("ignoring thread counter %s", name);
10220			return -1;
10221		}
10222		break;
10223	case SCOPE_CORE:
10224		msrp = find_msrp_by_name(sys.cp, name);
10225		if (msrp) {
10226			if (debug)
10227				fprintf(stderr, "%s: %s FOUND\n", __func__, name);
10228			break;
10229		}
10230		if (sys.added_core_counters++ >= MAX_ADDED_CORE_COUNTERS) {
10231			warnx("ignoring core counter %s", name);
10232			return -1;
10233		}
10234		break;
10235	case SCOPE_PACKAGE:
10236		msrp = find_msrp_by_name(sys.pp, name);
10237		if (msrp) {
10238			if (debug)
10239				fprintf(stderr, "%s: %s FOUND\n", __func__, name);
10240			break;
10241		}
10242		if (sys.added_package_counters++ >= MAX_ADDED_PACKAGE_COUNTERS) {
10243			warnx("ignoring package counter %s", name);
10244			return -1;
10245		}
10246		break;
10247	default:
10248		warnx("ignoring counter %s with unknown scope", name);
10249		return -1;
10250	}
10251
10252	if (msrp == NULL) {
10253		msrp = calloc(1, sizeof(struct msr_counter));
10254		if (msrp == NULL)
10255			err(-1, "calloc msr_counter");
10256
10257		msrp->msr_num = msr_num;
10258		strncpy(msrp->name, name, NAME_BYTES - 1);
10259		msrp->width = width;
10260		msrp->type = type;
10261		msrp->format = format;
10262		msrp->flags = flags;
10263
10264		switch (scope) {
10265		case SCOPE_CPU:
10266			msrp->next = sys.tp;
10267			sys.tp = msrp;
10268			break;
10269		case SCOPE_CORE:
10270			msrp->next = sys.cp;
10271			sys.cp = msrp;
10272			break;
10273		case SCOPE_PACKAGE:
10274			msrp->next = sys.pp;
10275			sys.pp = msrp;
10276			break;
10277		}
10278	}
10279
10280	if (path) {
10281		struct sysfs_path *sp;
10282
10283		sp = calloc(1, sizeof(struct sysfs_path));
10284		if (sp == NULL) {
10285			perror("calloc");
10286			exit(1);
10287		}
10288		strncpy(sp->path, path, PATH_BYTES - 1);
10289		sp->id = id;
10290		sp->next = msrp->sp;
10291		msrp->sp = sp;
10292	}
10293
10294	return 0;
10295}
10296
10297/*
10298 * Initialize the fields used for identifying and opening the counter.
10299 *
10300 * Defer the initialization of any runtime buffers for actually reading
10301 * the counters for when we initialize all perf counters, so we can later
10302 * easily call re_initialize().
10303 */
10304struct perf_counter_info *make_perf_counter_info(const char *perf_device,
10305						 const char *perf_event,
10306						 const char *name,
10307						 unsigned int width, enum counter_scope scope, enum counter_type type, enum counter_format format)
10308{
10309	struct perf_counter_info *pinfo;
10310
10311	pinfo = calloc(1, sizeof(*pinfo));
10312	if (!pinfo)
10313		errx(1, "%s: Failed to allocate %s/%s\n", __func__, perf_device, perf_event);
10314
10315	strncpy(pinfo->device, perf_device, ARRAY_SIZE(pinfo->device) - 1);
10316	strncpy(pinfo->event, perf_event, ARRAY_SIZE(pinfo->event) - 1);
10317
10318	strncpy(pinfo->name, name, ARRAY_SIZE(pinfo->name) - 1);
10319	pinfo->width = width;
10320	pinfo->scope = scope;
10321	pinfo->type = type;
10322	pinfo->format = format;
10323
10324	return pinfo;
10325}
10326
10327int add_perf_counter(const char *perf_device, const char *perf_event, const char *name_buffer, unsigned int width,
10328		     enum counter_scope scope, enum counter_type type, enum counter_format format)
10329{
10330	struct perf_counter_info *pinfo;
10331
10332	switch (scope) {
10333	case SCOPE_CPU:
10334		if (sys.added_thread_perf_counters >= MAX_ADDED_THREAD_COUNTERS) {
10335			warnx("ignoring thread counter perf/%s/%s", perf_device, perf_event);
10336			return -1;
10337		}
10338		break;
10339
10340	case SCOPE_CORE:
10341		if (sys.added_core_perf_counters >= MAX_ADDED_CORE_COUNTERS) {
10342			warnx("ignoring core counter perf/%s/%s", perf_device, perf_event);
10343			return -1;
10344		}
10345		break;
10346
10347	case SCOPE_PACKAGE:
10348		if (sys.added_package_perf_counters >= MAX_ADDED_PACKAGE_COUNTERS) {
10349			warnx("ignoring package counter perf/%s/%s", perf_device, perf_event);
10350			return -1;
10351		}
10352		break;
10353	}
10354
10355	pinfo = make_perf_counter_info(perf_device, perf_event, name_buffer, width, scope, type, format);
10356
10357	if (!pinfo)
10358		return -1;
10359
10360	switch (scope) {
10361	case SCOPE_CPU:
10362		pinfo->next = sys.perf_tp;
10363		sys.perf_tp = pinfo;
10364		++sys.added_thread_perf_counters;
10365		break;
10366
10367	case SCOPE_CORE:
10368		pinfo->next = sys.perf_cp;
10369		sys.perf_cp = pinfo;
10370		++sys.added_core_perf_counters;
10371		break;
10372
10373	case SCOPE_PACKAGE:
10374		pinfo->next = sys.perf_pp;
10375		sys.perf_pp = pinfo;
10376		++sys.added_package_perf_counters;
10377		break;
10378	}
10379
10380	// FIXME: we might not have debug here yet
10381	if (debug)
10382		fprintf(stderr, "%s: %s/%s, name: %s, scope%d\n", __func__, pinfo->device, pinfo->event, pinfo->name, pinfo->scope);
10383
10384	return 0;
10385}
10386
10387void parse_add_command_msr(char *add_command)
10388{
10389	int msr_num = 0;
10390	char *path = NULL;
10391	char perf_device[PERF_DEV_NAME_BYTES] = "";
10392	char perf_event[PERF_EVT_NAME_BYTES] = "";
10393	char name_buffer[PERF_NAME_BYTES] = "";
10394	int width = 64;
10395	int fail = 0;
10396	enum counter_scope scope = SCOPE_CPU;
10397	enum counter_type type = COUNTER_CYCLES;
10398	enum counter_format format = FORMAT_DELTA;
10399
10400	while (add_command) {
10401
10402		if (sscanf(add_command, "msr0x%x", &msr_num) == 1)
10403			goto next;
10404
10405		if (sscanf(add_command, "msr%d", &msr_num) == 1)
10406			goto next;
10407
10408		BUILD_BUG_ON(ARRAY_SIZE(perf_device) <= 31);
10409		BUILD_BUG_ON(ARRAY_SIZE(perf_event) <= 31);
10410		if (sscanf(add_command, "perf/%31[^/]/%31[^,]", &perf_device[0], &perf_event[0]) == 2)
10411			goto next;
10412
10413		if (*add_command == '/') {
10414			path = add_command;
10415			goto next;
10416		}
10417
10418		if (sscanf(add_command, "u%d", &width) == 1) {
10419			if ((width == 32) || (width == 64))
10420				goto next;
10421			width = 64;
10422		}
10423		if (!strncmp(add_command, "cpu", strlen("cpu"))) {
10424			scope = SCOPE_CPU;
10425			goto next;
10426		}
10427		if (!strncmp(add_command, "core", strlen("core"))) {
10428			scope = SCOPE_CORE;
10429			goto next;
10430		}
10431		if (!strncmp(add_command, "package", strlen("package"))) {
10432			scope = SCOPE_PACKAGE;
10433			goto next;
10434		}
10435		if (!strncmp(add_command, "cycles", strlen("cycles"))) {
10436			type = COUNTER_CYCLES;
10437			goto next;
10438		}
10439		if (!strncmp(add_command, "seconds", strlen("seconds"))) {
10440			type = COUNTER_SECONDS;
10441			goto next;
10442		}
10443		if (!strncmp(add_command, "usec", strlen("usec"))) {
10444			type = COUNTER_USEC;
10445			goto next;
10446		}
10447		if (!strncmp(add_command, "raw", strlen("raw"))) {
10448			format = FORMAT_RAW;
10449			goto next;
10450		}
10451		if (!strncmp(add_command, "average", strlen("average"))) {
10452			format = FORMAT_AVERAGE;
10453			goto next;
10454		}
10455		if (!strncmp(add_command, "delta", strlen("delta"))) {
10456			format = FORMAT_DELTA;
10457			goto next;
10458		}
10459		if (!strncmp(add_command, "percent", strlen("percent"))) {
10460			format = FORMAT_PERCENT;
10461			goto next;
10462		}
10463
10464		BUILD_BUG_ON(ARRAY_SIZE(name_buffer) <= 18);
10465		if (sscanf(add_command, "%18s,%*s", name_buffer) == 1) {
10466			char *eos;
10467
10468			eos = strchr(name_buffer, ',');
10469			if (eos)
10470				*eos = '\0';
10471			goto next;
10472		}
10473
10474next:
10475		add_command = strchr(add_command, ',');
10476		if (add_command) {
10477			*add_command = '\0';
10478			add_command++;
10479		}
10480
10481	}
10482	if ((msr_num == 0) && (path == NULL) && (perf_device[0] == '\0' || perf_event[0] == '\0')) {
10483		fprintf(stderr, "--add: (msrDDD | msr0xXXX | /path_to_counter | perf/device/event) required\n");
10484		fail++;
10485	}
10486
10487	/* Test for non-empty perf_device and perf_event */
10488	const bool is_perf_counter = perf_device[0] && perf_event[0];
10489
10490	/* generate default column header */
10491	if (*name_buffer == '\0') {
10492		if (is_perf_counter) {
10493			snprintf(name_buffer, ARRAY_SIZE(name_buffer), "perf/%s", perf_event);
10494		} else {
10495			if (width == 32)
10496				sprintf(name_buffer, "M0x%x%s", msr_num, format == FORMAT_PERCENT ? "%" : "");
10497			else
10498				sprintf(name_buffer, "M0X%x%s", msr_num, format == FORMAT_PERCENT ? "%" : "");
10499		}
10500	}
10501
10502	if (is_perf_counter) {
10503		if (add_perf_counter(perf_device, perf_event, name_buffer, width, scope, type, format))
10504			fail++;
10505	} else {
10506		if (add_counter(msr_num, path, name_buffer, width, scope, type, format, 0, 0))
10507			fail++;
10508	}
10509
10510	if (fail) {
10511		help();
10512		exit(1);
10513	}
10514}
10515
10516bool starts_with(const char *str, const char *prefix)
10517{
10518	return strncmp(prefix, str, strlen(prefix)) == 0;
10519}
10520
10521int pmt_parse_from_path(const char *target_path, unsigned int *out_guid, unsigned int *out_seq)
10522{
10523	struct pmt_diriter_t pmt_iter;
10524	const struct dirent *dirname;
10525	struct stat stat, target_stat;
10526	int fd_telem_dir = -1;
10527	int fd_target_dir;
10528	unsigned int seq = 0;
10529	unsigned long guid, target_guid;
10530	int ret = -1;
10531
10532	fd_target_dir = open(target_path, O_RDONLY | O_DIRECTORY);
10533	if (fd_target_dir == -1) {
10534		return -1;
10535	}
10536
10537	if (fstat(fd_target_dir, &target_stat) == -1) {
10538		fprintf(stderr, "%s: Failed to stat the target: %s", __func__, strerror(errno));
10539		exit(1);
10540	}
10541
10542	if (parse_telem_info_file(fd_target_dir, "guid", "%lx", &target_guid)) {
10543		fprintf(stderr, "%s: Failed to parse the target guid file: %s", __func__, strerror(errno));
10544		exit(1);
10545	}
10546
10547	close(fd_target_dir);
10548
10549	pmt_diriter_init(&pmt_iter);
10550
10551	for (dirname = pmt_diriter_begin(&pmt_iter, SYSFS_TELEM_PATH); dirname != NULL; dirname = pmt_diriter_next(&pmt_iter)) {
10552
10553		fd_telem_dir = openat(dirfd(pmt_iter.dir), dirname->d_name, O_RDONLY | O_DIRECTORY);
10554		if (fd_telem_dir == -1)
10555			continue;
10556
10557		if (parse_telem_info_file(fd_telem_dir, "guid", "%lx", &guid)) {
10558			fprintf(stderr, "%s: Failed to parse the guid file: %s", __func__, strerror(errno));
10559			continue;
10560		}
10561
10562		if (fstat(fd_telem_dir, &stat) == -1) {
10563			fprintf(stderr, "%s: Failed to stat %s directory: %s", __func__, dirname->d_name, strerror(errno));
10564			continue;
10565		}
10566
10567		/*
10568		 * If reached the same directory as target, exit the loop.
10569		 * Seq has the correct value now.
10570		 */
10571		if (stat.st_dev == target_stat.st_dev && stat.st_ino == target_stat.st_ino) {
10572			ret = 0;
10573			break;
10574		}
10575
10576		/*
10577		 * If reached directory with the same guid,
10578		 * but it's not the target directory yet,
10579		 * increment seq and continue the search.
10580		 */
10581		if (guid == target_guid)
10582			++seq;
10583
10584		close(fd_telem_dir);
10585		fd_telem_dir = -1;
10586	}
10587
10588	pmt_diriter_remove(&pmt_iter);
10589
10590	if (fd_telem_dir != -1)
10591		close(fd_telem_dir);
10592
10593	if (!ret) {
10594		*out_guid = target_guid;
10595		*out_seq = seq;
10596	}
10597
10598	return ret;
10599}
10600
10601void parse_add_command_pmt(char *add_command)
10602{
10603	char *name = NULL;
10604	char *type_name = NULL;
10605	char *format_name = NULL;
10606	char *direct_path = NULL;
10607	static const char direct_path_prefix[] = "path=";
10608	unsigned int offset;
10609	unsigned int lsb;
10610	unsigned int msb;
10611	unsigned int guid;
10612	unsigned int seq = 0;	/* By default, pick first file in a sequence with a given GUID. */
10613	unsigned int domain_id;
10614	enum counter_scope scope = 0;
10615	enum pmt_datatype type = PMT_TYPE_RAW;
10616	enum counter_format format = FORMAT_RAW;
10617	bool has_offset = false;
10618	bool has_lsb = false;
10619	bool has_msb = false;
10620	bool has_format = true;	/* Format has a default value. */
10621	bool has_guid = false;
10622	bool has_scope = false;
10623	bool has_type = true;	/* Type has a default value. */
10624
10625	/* Consume the "pmt," prefix. */
10626	add_command = strchr(add_command, ',');
10627	if (!add_command) {
10628		help();
10629		exit(1);
10630	}
10631	++add_command;
10632
10633	while (add_command) {
10634		if (starts_with(add_command, "name=")) {
10635			name = add_command + strlen("name=");
10636			goto next;
10637		}
10638
10639		if (starts_with(add_command, "type=")) {
10640			type_name = add_command + strlen("type=");
10641			goto next;
10642		}
10643
10644		if (starts_with(add_command, "domain=")) {
10645			const size_t prefix_len = strlen("domain=");
10646
10647			if (sscanf(add_command + prefix_len, "cpu%u", &domain_id) == 1) {
10648				scope = SCOPE_CPU;
10649				has_scope = true;
10650			} else if (sscanf(add_command + prefix_len, "core%u", &domain_id) == 1) {
10651				scope = SCOPE_CORE;
10652				has_scope = true;
10653			} else if (sscanf(add_command + prefix_len, "package%u", &domain_id) == 1) {
10654				scope = SCOPE_PACKAGE;
10655				has_scope = true;
10656			}
10657
10658			if (!has_scope) {
10659				printf("%s: invalid value for scope. Expected cpu%%u, core%%u or package%%u.\n", __func__);
10660				exit(1);
10661			}
10662
10663			goto next;
10664		}
10665
10666		if (starts_with(add_command, "format=")) {
10667			format_name = add_command + strlen("format=");
10668			goto next;
10669		}
10670
10671		if (sscanf(add_command, "offset=%u", &offset) == 1) {
10672			has_offset = true;
10673			goto next;
10674		}
10675
10676		if (sscanf(add_command, "lsb=%u", &lsb) == 1) {
10677			has_lsb = true;
10678			goto next;
10679		}
10680
10681		if (sscanf(add_command, "msb=%u", &msb) == 1) {
10682			has_msb = true;
10683			goto next;
10684		}
10685
10686		if (sscanf(add_command, "guid=%x", &guid) == 1) {
10687			has_guid = true;
10688			goto next;
10689		}
10690
10691		if (sscanf(add_command, "seq=%x", &seq) == 1)
10692			goto next;
10693
10694		if (strncmp(add_command, direct_path_prefix, strlen(direct_path_prefix)) == 0) {
10695			direct_path = add_command + strlen(direct_path_prefix);
10696			goto next;
10697		}
10698next:
10699		add_command = strchr(add_command, ',');
10700		if (add_command) {
10701			*add_command = '\0';
10702			add_command++;
10703		}
10704	}
10705
10706	if (!name) {
10707		printf("%s: missing %s\n", __func__, "name");
10708		exit(1);
10709	}
10710
10711	if (strlen(name) >= PMT_COUNTER_NAME_SIZE_BYTES) {
10712		printf("%s: name has to be at most %d characters long\n", __func__, PMT_COUNTER_NAME_SIZE_BYTES);
10713		exit(1);
10714	}
10715
10716	if (format_name) {
10717		has_format = false;
10718
10719		if (strcmp("raw", format_name) == 0) {
10720			format = FORMAT_RAW;
10721			has_format = true;
10722		}
10723
10724		if (strcmp("average", format_name) == 0) {
10725			format = FORMAT_AVERAGE;
10726			has_format = true;
10727		}
10728
10729		if (strcmp("delta", format_name) == 0) {
10730			format = FORMAT_DELTA;
10731			has_format = true;
10732		}
10733
10734		if (!has_format) {
10735			fprintf(stderr, "%s: Invalid format %s. Expected raw, average or delta\n", __func__, format_name);
10736			exit(1);
10737		}
10738	}
10739
10740	if (type_name) {
10741		has_type = false;
10742
10743		if (strcmp("raw", type_name) == 0) {
10744			type = PMT_TYPE_RAW;
10745			has_type = true;
10746		}
10747
10748		if (strcmp("txtal_time", type_name) == 0) {
10749			type = PMT_TYPE_XTAL_TIME;
10750			has_type = true;
10751		}
10752
10753		if (strcmp("tcore_clock", type_name) == 0) {
10754			type = PMT_TYPE_TCORE_CLOCK;
10755			has_type = true;
10756		}
10757
10758		if (!has_type) {
10759			printf("%s: invalid %s: %s\n", __func__, "type", type_name);
10760			exit(1);
10761		}
10762	}
10763
10764	if (!has_offset) {
10765		printf("%s : missing %s\n", __func__, "offset");
10766		exit(1);
10767	}
10768
10769	if (!has_lsb) {
10770		printf("%s: missing %s\n", __func__, "lsb");
10771		exit(1);
10772	}
10773
10774	if (!has_msb) {
10775		printf("%s: missing %s\n", __func__, "msb");
10776		exit(1);
10777	}
10778
10779	if (direct_path && has_guid) {
10780		printf("%s: path and guid+seq parameters are mutually exclusive\n"
10781		       "notice: passed guid=0x%x and path=%s\n", __func__, guid, direct_path);
10782		exit(1);
10783	}
10784
10785	if (direct_path) {
10786		if (pmt_parse_from_path(direct_path, &guid, &seq)) {
10787			printf("%s: failed to parse PMT file from %s\n", __func__, direct_path);
10788			exit(1);
10789		}
10790
10791		/* GUID was just infered from the direct path. */
10792		has_guid = true;
10793	}
10794
10795	if (!has_guid) {
10796		printf("%s: missing %s\n", __func__, "guid or path");
10797		exit(1);
10798	}
10799
10800	if (!has_scope) {
10801		printf("%s: missing %s\n", __func__, "scope");
10802		exit(1);
10803	}
10804
10805	if (lsb > msb) {
10806		printf("%s: lsb > msb doesn't make sense\n", __func__);
10807		exit(1);
10808	}
10809
10810	pmt_add_counter(guid, seq, name, type, lsb, msb, offset, scope, format, domain_id, PMT_OPEN_REQUIRED);
10811}
10812
10813void parse_add_command(char *add_command)
10814{
10815	if (strncmp(add_command, "pmt", strlen("pmt")) == 0)
10816		return parse_add_command_pmt(add_command);
10817	return parse_add_command_msr(add_command);
10818}
10819
10820int is_deferred_add(char *name)
10821{
10822	int i;
10823
10824	for (i = 0; i < deferred_add_index; ++i)
10825		if (!strcmp(name, deferred_add_names[i])) {
10826			deferred_add_consumed |= (1 << i);
10827			return 1;
10828		}
10829	return 0;
10830}
10831
10832int is_deferred_skip(char *name)
10833{
10834	int i;
10835
10836	for (i = 0; i < deferred_skip_index; ++i)
10837		if (!strcmp(name, deferred_skip_names[i])) {
10838			deferred_skip_consumed |= (1 << i);
10839			return 1;
10840		}
10841	return 0;
10842}
10843
10844void verify_deferred_consumed(void)
10845{
10846	int i;
10847	int fail = 0;
10848
10849	for (i = 0; i < deferred_add_index; ++i) {
10850		if (!(deferred_add_consumed & (1 << i))) {
10851			warnx("Counter '%s' can not be added.", deferred_add_names[i]);
10852			fail++;
10853		}
10854	}
10855	for (i = 0; i < deferred_skip_index; ++i) {
10856		if (!(deferred_skip_consumed & (1 << i))) {
10857			warnx("Counter '%s' can not be skipped.", deferred_skip_names[i]);
10858			fail++;
10859		}
10860	}
10861	if (fail)
10862		exit(-EINVAL);
10863}
10864
10865void probe_cpuidle_residency(void)
10866{
10867	char path[64];
10868	char name_buf[16];
10869	FILE *input;
10870	int state;
10871	int min_state = 1024, max_state = 0;
10872	char *sp;
10873
10874	for (state = 10; state >= 0; --state) {
10875
10876		sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", base_cpu, state);
10877		input = fopen(path, "r");
10878		if (input == NULL)
10879			continue;
10880		if (!fgets(name_buf, sizeof(name_buf), input))
10881			err(1, "%s: failed to read file", path);
10882
10883		/* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
10884		sp = strchr(name_buf, '-');
10885		if (!sp)
10886			sp = strchrnul(name_buf, '\n');
10887		*sp = '%';
10888		*(sp + 1) = '\0';
10889
10890		remove_underbar(name_buf);
10891
10892		fclose(input);
10893
10894		sprintf(path, "cpuidle/state%d/time", state);
10895
10896		if (!DO_BIC(BIC_pct_idle) && !is_deferred_add(name_buf))
10897			continue;
10898
10899		if (is_deferred_skip(name_buf))
10900			continue;
10901
10902		add_counter(0, path, name_buf, 32, SCOPE_CPU, COUNTER_USEC, FORMAT_PERCENT, SYSFS_PERCPU, 0);
10903
10904		if (state > max_state)
10905			max_state = state;
10906		if (state < min_state)
10907			min_state = state;
10908	}
10909}
10910
10911static bool cpuidle_counter_wanted(char *name)
10912{
10913	if (is_deferred_skip(name))
10914		return false;
10915
10916	return DO_BIC(BIC_cpuidle) || is_deferred_add(name);
10917}
10918
10919void probe_cpuidle_counts(void)
10920{
10921	char path[64];
10922	char name_buf[16];
10923	FILE *input;
10924	int state;
10925	int min_state = 1024, max_state = 0;
10926	char *sp;
10927
10928	if (!DO_BIC(BIC_cpuidle) && !deferred_add_index)
10929		return;
10930
10931	for (state = 10; state >= 0; --state) {
10932
10933		sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", base_cpu, state);
10934		input = fopen(path, "r");
10935		if (input == NULL)
10936			continue;
10937		if (!fgets(name_buf, sizeof(name_buf), input))
10938			err(1, "%s: failed to read file", path);
10939		fclose(input);
10940
10941		remove_underbar(name_buf);
10942
10943		/* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
10944		sp = strchr(name_buf, '-');
10945		if (!sp)
10946			sp = strchrnul(name_buf, '\n');
10947
10948		/*
10949		 * The 'below' sysfs file always contains 0 for the deepest state (largest index),
10950		 * do not add it.
10951		 */
10952		if (state != max_state) {
10953			/*
10954			 * Add 'C1+' for C1, and so on. The 'below' sysfs file always contains 0 for
10955			 * the last state, so do not add it.
10956			 */
10957			*sp = '+';
10958			*(sp + 1) = '\0';
10959			if (cpuidle_counter_wanted(name_buf)) {
10960				sprintf(path, "cpuidle/state%d/below", state);
10961				add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS, FORMAT_DELTA, SYSFS_PERCPU, 0);
10962			}
10963		}
10964
10965		*sp = '\0';
10966		if (cpuidle_counter_wanted(name_buf)) {
10967			sprintf(path, "cpuidle/state%d/usage", state);
10968			add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS, FORMAT_DELTA, SYSFS_PERCPU, 0);
10969		}
10970
10971		/*
10972		 * The 'above' sysfs file always contains 0 for the shallowest state (smallest
10973		 * index), do not add it.
10974		 */
10975		if (state != min_state) {
10976			*sp = '-';
10977			*(sp + 1) = '\0';
10978			if (cpuidle_counter_wanted(name_buf)) {
10979				sprintf(path, "cpuidle/state%d/above", state);
10980				add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS, FORMAT_DELTA, SYSFS_PERCPU, 0);
10981			}
10982		}
10983	}
10984}
10985
10986/*
10987 * parse cpuset with following syntax
10988 * 1,2,4..6,8-10 and set bits in cpu_subset
10989 */
10990void parse_cpu_command(char *optarg)
10991{
10992	if (!strcmp(optarg, "core")) {
10993		if (cpu_subset)
10994			goto error;
10995		show_core_only++;
10996		return;
10997	}
10998	if (!strcmp(optarg, "package")) {
10999		if (cpu_subset)
11000			goto error;
11001		show_pkg_only++;
11002		return;
11003	}
11004	if (show_core_only || show_pkg_only)
11005		goto error;
11006
11007	cpu_subset = CPU_ALLOC(CPU_SUBSET_MAXCPUS);
11008	if (cpu_subset == NULL)
11009		err(3, "CPU_ALLOC");
11010	cpu_subset_size = CPU_ALLOC_SIZE(CPU_SUBSET_MAXCPUS);
11011
11012	CPU_ZERO_S(cpu_subset_size, cpu_subset);
11013
11014	if (parse_cpu_str(optarg, cpu_subset, cpu_subset_size))
11015		goto error;
11016
11017	return;
11018
11019error:
11020	fprintf(stderr, "\"--cpu %s\" malformed\n", optarg);
11021	help();
11022	exit(-1);
11023}
11024
11025void cmdline(int argc, char **argv)
11026{
11027	int opt;
11028	int option_index = 0;
11029	static struct option long_options[] = {
11030		{ "add", required_argument, 0, 'a' },
11031		{ "cpu", required_argument, 0, 'c' },
11032		{ "Dump", no_argument, 0, 'D' },
11033		{ "debug", no_argument, 0, 'd' },	/* internal, not documented */
11034		{ "enable", required_argument, 0, 'e' },
11035		{ "force", no_argument, 0, 'f' },
11036		{ "interval", required_argument, 0, 'i' },
11037		{ "IPC", no_argument, 0, 'I' },
11038		{ "num_iterations", required_argument, 0, 'n' },
11039		{ "header_iterations", required_argument, 0, 'N' },
11040		{ "help", no_argument, 0, 'h' },
11041		{ "hide", required_argument, 0, 'H' },	// meh, -h taken by --help
11042		{ "Joules", no_argument, 0, 'J' },
11043		{ "list", no_argument, 0, 'l' },
11044		{ "out", required_argument, 0, 'o' },
11045		{ "quiet", no_argument, 0, 'q' },
11046		{ "no-msr", no_argument, 0, 'M' },
11047		{ "no-perf", no_argument, 0, 'P' },
11048		{ "show", required_argument, 0, 's' },
11049		{ "Summary", no_argument, 0, 'S' },
11050		{ "TCC", required_argument, 0, 'T' },
11051		{ "version", no_argument, 0, 'v' },
11052		{ 0, 0, 0, 0 }
11053	};
11054
11055	progname = argv[0];
11056
11057	/*
11058	 * Parse some options early, because they may make other options invalid,
11059	 * like adding the MSR counter with --add and at the same time using --no-msr.
11060	 */
11061	while ((opt = getopt_long_only(argc, argv, "+MPn:", long_options, &option_index)) != -1) {
11062		switch (opt) {
11063		case 'M':
11064			no_msr = 1;
11065			break;
11066		case 'P':
11067			no_perf = 1;
11068			break;
11069		default:
11070			break;
11071		}
11072	}
11073	optind = 0;
11074
11075	while ((opt = getopt_long_only(argc, argv, "+C:c:Dde:hi:Jn:o:qMST:v", long_options, &option_index)) != -1) {
11076		switch (opt) {
11077		case 'a':
11078			parse_add_command(optarg);
11079			break;
11080		case 'c':
11081			parse_cpu_command(optarg);
11082			break;
11083		case 'D':
11084			dump_only++;
11085			/*
11086			 * Force the no_perf early to prevent using it as a source.
11087			 * User asks for raw values, but perf returns them relative
11088			 * to the opening of the file descriptor.
11089			 */
11090			no_perf = 1;
11091			break;
11092		case 'e':
11093			/* --enable specified counter, without clearning existing list */
11094			bic_lookup(&bic_enabled, optarg, SHOW_LIST);
11095			break;
11096		case 'f':
11097			force_load++;
11098			break;
11099		case 'd':
11100			debug++;
11101			bic_set_all(&bic_enabled);
11102			break;
11103		case 'H':
11104			/*
11105			 * --hide: do not show those specified
11106			 *  multiple invocations simply clear more bits in enabled mask
11107			 */
11108			{
11109				cpu_set_t bic_group_hide;
11110
11111				BIC_INIT(&bic_group_hide);
11112
11113				bic_lookup(&bic_group_hide, optarg, HIDE_LIST);
11114				bic_clear_bits(&bic_enabled, &bic_group_hide);
11115			}
11116			break;
11117		case 'h':
11118		default:
11119			help();
11120			exit(1);
11121		case 'i':
11122			{
11123				double interval = strtod(optarg, NULL);
11124
11125				if (interval < 0.001) {
11126					fprintf(outf, "interval %f seconds is too small\n", interval);
11127					exit(2);
11128				}
11129
11130				interval_tv.tv_sec = interval_ts.tv_sec = interval;
11131				interval_tv.tv_usec = (interval - interval_tv.tv_sec) * 1000000;
11132				interval_ts.tv_nsec = (interval - interval_ts.tv_sec) * 1000000000;
11133			}
11134			break;
11135		case 'J':
11136			rapl_joules++;
11137			break;
11138		case 'l':
11139			bic_set_all(&bic_enabled);
11140			list_header_only++;
11141			quiet++;
11142			break;
11143		case 'o':
11144			outf = fopen_or_die(optarg, "w");
11145			break;
11146		case 'q':
11147			quiet = 1;
11148			break;
11149		case 'M':
11150		case 'P':
11151			/* Parsed earlier */
11152			break;
11153		case 'n':
11154			num_iterations = strtod(optarg, NULL);
11155
11156			if (num_iterations <= 0) {
11157				fprintf(outf, "iterations %d should be positive number\n", num_iterations);
11158				exit(2);
11159			}
11160			break;
11161		case 'N':
11162			header_iterations = strtod(optarg, NULL);
11163
11164			if (header_iterations <= 0) {
11165				fprintf(outf, "iterations %d should be positive number\n", header_iterations);
11166				exit(2);
11167			}
11168			break;
11169		case 's':
11170			/*
11171			 * --show: show only those specified
11172			 *  The 1st invocation will clear and replace the enabled mask
11173			 *  subsequent invocations can add to it.
11174			 */
11175			if (shown == 0)
11176				BIC_INIT(&bic_enabled);
11177			bic_lookup(&bic_enabled, optarg, SHOW_LIST);
11178			shown = 1;
11179			break;
11180		case 'S':
11181			summary_only++;
11182			break;
11183		case 'T':
11184			tj_max_override = atoi(optarg);
11185			break;
11186		case 'v':
11187			print_version();
11188			exit(0);
11189			break;
11190		}
11191	}
11192}
11193
11194void set_rlimit(void)
11195{
11196	struct rlimit limit;
11197
11198	if (getrlimit(RLIMIT_NOFILE, &limit) < 0)
11199		err(1, "Failed to get rlimit");
11200
11201	if (limit.rlim_max < MAX_NOFILE)
11202		limit.rlim_max = MAX_NOFILE;
11203	if (limit.rlim_cur < MAX_NOFILE)
11204		limit.rlim_cur = MAX_NOFILE;
11205
11206	if (setrlimit(RLIMIT_NOFILE, &limit) < 0)
11207		err(1, "Failed to set rlimit");
11208}
11209
11210int main(int argc, char **argv)
11211{
11212	int fd, ret;
11213
11214	bic_groups_init();
11215
11216	fd = open("/sys/fs/cgroup/cgroup.procs", O_WRONLY);
11217	if (fd < 0)
11218		goto skip_cgroup_setting;
11219
11220	ret = write(fd, "0\n", 2);
11221	if (ret == -1)
11222		perror("Can't update cgroup\n");
11223
11224	close(fd);
11225
11226skip_cgroup_setting:
11227	outf = stderr;
11228	cmdline(argc, argv);
11229
11230	if (!quiet) {
11231		print_version();
11232		print_bootcmd();
11233	}
11234
11235	probe_cpuidle_residency();
11236	probe_cpuidle_counts();
11237
11238	verify_deferred_consumed();
11239
11240	if (!getuid())
11241		set_rlimit();
11242
11243	turbostat_init();
11244
11245	if (!no_msr)
11246		msr_sum_record();
11247
11248	/* dump counters and exit */
11249	if (dump_only)
11250		return get_and_dump_counters();
11251
11252	/* list header and exit */
11253	if (list_header_only) {
11254		print_header(",");
11255		flush_output_stdout();
11256		return 0;
11257	}
11258
11259	/*
11260	 * if any params left, it must be a command to fork
11261	 */
11262	if (argc - optind)
11263		return fork_it(argv + optind);
11264	else
11265		turbostat_loop();
11266
11267	return 0;
11268}
~/ Read-only file preview.