1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
|
/* Copyright (C) 2021-2026 Free Software Foundation, Inc.
Contributed by Oracle.
This file is part of GNU Binutils.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
#ifndef _HWCENTRY_H
#define _HWCENTRY_H
#ifndef LIBCOLLECTOR_SRC /* not running in libcollector */
#include <stdio.h> /* FILE */
#endif /* --- LIBCOLLECTOR_SRC --- */
#include <stdlib.h> /* size_t */
#include "hwc_cpus.h"
#include "gp-time.h"
#ifdef __cplusplus
extern "C"
{
#endif
/* ABS backtrack types */
typedef enum
{
/* !! Lowest 2 bits are used to indicate load and store, respectively !! */
/* Example: On SPARC, backtrack.c did this: if (ABS_memop & inst_type) ... */
ABST_NONE = 0x0,
ABST_LOAD = 0x1,
ABST_STORE = 0x2,
ABST_LDST = 0x3,
ABST_COUNT = 0x4,
ABST_US_DTLBM = 0xF,
ABST_NOPC = 0x100,
ABST_CLKDS = 0x103, // Obsolete
ABST_EXACT = 0x203,
ABST_LDST_SPARC64 = 0x303,
ABST_EXACT_PEBS_PLUS1 = 0x403
/* full description below... */
} ABST_type;
#define ABST_PLUS_BY_DEFAULT(n) ((n)==ABST_EXACT || (n)==ABST_EXACT_PEBS_PLUS1)
#define ABST_BACKTRACK_ENABLED(n) ((n)!=ABST_NONE && (n)!=ABST_NOPC)
#define ABST_MEMSPACE_ENABLED(n) ((n)!=ABST_NONE && (n)!=ABST_NOPC && (n)!=ABST_COUNT)
/* ABS determines the type of backtracking available for a particular metric.
* Backtracking is enabled with the "+" in "-h +<countername>...".
*
* When Backtracking is not possible:
*
* ABST_NONE=0: Either the user did not specify "+", or backtracking
* is not applicable to the metric, for example:
* clk cycles,
* instruct counts (dispatch + branch + prefetch),
* i$,
* FP ops
* ABST_NOPC=0x100 Used for non-program-related external events, for example:
* system interface events,
* memory controller counters
* Of all ABST_type options, only ABST_NOPC prevents hwprofile.c
* from recording PC/stack information.
*
* When backtracking is allowed:
*
* ABST_LOAD=1: data read events, used with metrics like:
* D$, E$, P$ read misses and hits.
* [DC+EC+PC]_rd*, Re_*_miss*,
* EC_snoop_cb(?)
* ABST_STORE=2: data write events, used with metrics like:
* D$ writes and write related misses
* DC_wr/wr-miss, EC_wb, WC=writecache, Rstall_storeQ
* [EC+PC=pcache]_snoop_inv(?), WC_snoop_cb(?),
* ABST_LDST=3: data reads/writes, used with metrics like:
* E$ references, misses.
* ABST_COUNT=4: dedicated assembly instruction: '%hi(0xfc000)'
* See SW_count_n metric on sparc.
* ABST_US_DTLBM=0xF: for load-store on Sparc -- seems to be used only
* for "unskidded DTLB_miss" with DTLB_miss metric.
* Checks two adjacent instructions for Data access.
* ABST_CLKDS=0x103: data reads/writes, used with Clock-based Dataspace
* profiling. Ultrasparc T2 and earlier.
* ABST_EXACT=0x203: data reads/writes, precise trap with no skid
* ABST_LDST_SPARC64=0x303: Fujitsu SPARC64 load/store
* ABST_EXACT_PEBS_PLUS1=0x403: data reads/writes, precise sampling with 1 instr. skid
*/
/* Hwcentry - structure for defining a counter.
* Some fields have different usage when returned from
* hwc_lookup(), hwc_post_lookup(), or hwc_scan_*().
* Each function will describe its return values in more detail.
*/
typedef struct
{
char *name; /* user HWC specification */
char *int_name; /* internal HWC specification */
regno_t reg_num; /* register in CPU, aka picnum, or REGNO_ANY */
char *metric; /* descriptive name, for well-known counters only */
volatile int val; /* default or actual overflow value */
int timecvt; /* multiplier to convert metric to time, 0 if N/A */
ABST_type memop; /* type of backtracking allowed */
char *short_desc; /* optional one-liner description, or NULL */
/* the fields above this line are expected, in order, by the tables in hwctable.c */
/* ================================================== */
/* the fields below this line are more flexible */
unsigned int use_perf_event_type : 16; /* Set 1 to use two fields below */
unsigned int type : 16; /* Type of perf_event_attr */
long long config; /* perf_event_type -specific configuration */
long long config1; /* perf_event_type -specific configuration */
int sort_order; /* "tag" to associate experiment record with HWC def */
hrtime_t min_time; /* target minimum time between overflow events. 0 is off. See HWCTIME_* macros */
hrtime_t min_time_default; /* if min_time==HWCTIME_AUTO, use this value instead. 0 is off. */
int ref_val; /* if min_time==HWCTIME_AUTO, use this time. 0 is off. */
int lval, hval; /* temporary to allow DBX to build until dbx glue.cc fixed */
} Hwcentry;
// Hwcentry.min_time canned values
#define HWCTIME_TBD ((hrtime_t)( -1LL)) /* self-adjusting enabled but nsecs not yet selected */
#define HWCTIME_HI ( 1 * 1000 * 1000LL ) /* 1 msec represented in nsecs */
#define HWCTIME_ON ( 10 * 1000 * 1000LL ) /* 10 msec represented in nsecs */
#define HWCTIME_LO ( 100 * 1000 * 1000LL ) /* 100 msec represented in nsecs */
#define HWC_VAL_HI(refVal) (((refVal)/10) + 1)
#define HWC_VAL_ON(refVal) (refVal)
#define HWC_VAL_LO(refVal) (((refVal)*10)/100*100 + 1) // zero's out lower digits, add 1
#define HWC_VAL_CUSTOM(refVal, targetNanoSec) ((double)(refVal)*(targetNanoSec)/HWCTIME_ON)
#define HWCENTRY_USES_SAMPLING(h) ((h)->memop==ABST_EXACT_PEBS_PLUS1)
extern int hwc_lookup (int forKernel, hrtime_t min_time_default,
const char *uname, Hwcentry *list[], unsigned listsz,
char **emsg, char **wmsg);
/* Parses counter cmdline string. Returns counter definitions.
* Input:
* <forKernel> lookup using which table: 0-collect or 1-er_kernel
* <min_time_default> minimum nseconds between events if Hwcentry.min_time == HWCTIME_TBD. 0 to disable.
* <uname> command line HWC definition of format:
* <ctr_def>...[{','|(whitespace)}<ctr_n_def>] where
* <ctr_def> == [+]<ctr>[/<reg#>][,<interval>]
* <list> array of pointers to store counter definitions
* <listsz> number of elements in <list>
* Returns:
* Success:
* Returns number of valid counters in <list> and <list>'s elements
* will be initialized as follows:
*
* <list[]->name>:
* Copy of the <uname> with the following modification:
* if backtracking is not supported, the + will be removed.
* <list[]->int_name>:
* For well-known and convenience ctrs, the internal HWC specification,
* e.g. BSQ_cache_reference~emask=0x0100.
* For raw ctrs, this will be a copy of <name>.
* <list[]->reg_num>:
* Register number if specified by user or table, REGNO_ANY otherwise.
* <list[]->metric>:
* For well-known counters, descriptive name, e.g. "D$ Read Misses".
* NULL otherwise.
* <list[]->val>:
* Overflow value selected by user, default value otherwise.
* <list[]->timecvt>:
* Value from tables.
* <list[]->memop>:
* If + is selected and backtracking is allowed, value from table.
* ABST_NONE or ABST_NOPC otherwise.
*
* It is the responsibility of the caller to free 'name' and 'int_name'.
* 'metric' is a static string and shouldn't be freed.
* 'emsg' will point to NULL
*
* Failure:
* Frees all allocated elements.
* emsg will point to a string with an error message to print
* returns -1
*/
extern char *hwc_validate_ctrs (int forKernel, Hwcentry *list[], unsigned listsz);
/* Validates that the vector of specified HW counters can be loaded (more-or-less)
* Some invalid combinations, especially on Linux will not be detected
*/
extern int hwc_get_cpc_cpuver ();
/* Return the cpc_cpuver for this system. Other possible values:
* CPUVER_GENERIC=0, CPU could not be determined, but HWCs are ok.
* CPUVER_UNDEFINED=-1, HWCs are not available.
*/
extern char *hwc_get_docref (char *buf, size_t buflen);
/* Return a CPU HWC document reference, or NULL. */
extern char *hwc_get_default_cntrs2 (int forKernel, int style);
/* like hwc_get_default_cntrs() for style==1 */
/* but allows other styles of formatting as well */
/* deprecate and eventually remove hwc_get_default_cntrs() */
extern char *hwc_get_orig_default_cntrs (int forKernel);
/* Get the default HW counter string as set in the table */
/* NULL means none is defined in the table */
extern void hwc_update_val (Hwcentry *ctr);
/* Check time-based intervals and update Hwcentry.val as needed */
extern char *hwc_get_cpuname (char *buf, size_t buflen);
/* Return the cpc cpu name for this system, or NULL. */
extern unsigned hwc_get_max_regs ();
/* Return number of counters registers for this system. */
extern unsigned hwc_get_max_concurrent (int forKernel);
/* Return the max number of simultaneous counters for this system. */
extern char **hwc_get_attrs (int forKernel);
/* Return:
* Array of attributes (strings) supported by this system.
* Last element in array is null.
* Array and its elements should NOT be freed by the caller.
*/
extern unsigned hwc_scan_attrs (void (*action)(const char *attr,
const char *desc));
/* Scan the HW counter attributes, and call function for each attribute.
* Input:
* <action>:
* If NULL, no action is performed, but count is still returned.
* Otherwise called for each type of attributes, or if none exist,
* called once with NULL parameter.
* Return: count of times <action> would have been called w/ non-NULL data.
*/
extern Hwcentry *hwc_post_lookup (Hwcentry * pret_ctr, char *uname,
char * int_name, int cpc_cpuver);
/* When post-processing a run, look up a Hwcentry for given type of system.
* Input:
* <pret_ctr>: storage for counter definition
* <uname>: well-known name, convenience name, or complete HWC defintion.
* <int_name>: Hwcentry->int_name or NULL for don't care
* <cpc_cpuver>: version of cpu used for experiment.
* Return:
* <pret_ctr>'s elements set as follows:
*
* <pret_ctr->name>:
* Copy of <uname> with the following modifications:
* 1) + and /<regnum> will be stripped off
* 2) attributes will be sorted and values will shown in hex.
* <pret_ctr->int_name>:
* For well-known/convenience counters, the internal HWC specification
* from the table, e.g. BSQ_cache_reference~emask=0x0100.
* Otherwise, a copy of <uname>.
* <pret_ctr->reg_num>:
* Register number if specified by user or table,
* REGNO_ANY othewise.
* <pret_ctr->metric>:
* For well-known counters, descriptive name, e.g. "D$ Read Misses".
* NULL otherwise.
* <pret_ctr->timecvt>:
* For well-known/convenience/hidden counters, value from table.
* 0 otherwise.
* <pret_ctr->memop>:
* For well-known/convenience/hidden counters, value from table.
* ABST_NONE otherwise.
* <pret_ctr->sort_order>:
* Set to 0.
*
* It is the responsibility of the caller to free 'name' and 'int_name'.
* 'metric' is a static string and shouldn't be freed.
*/
extern Hwcentry **hwc_get_std_ctrs (int forKernel);
/* Return:
* Array of well-known counters supported by this system.
* Last element in array will be NULL.
* Array and its elements should NOT be freed by the caller.
*/
extern unsigned hwc_scan_std_ctrs (void (*action)(const Hwcentry *));
/* Call <action> for each well-known counter.
* Input:
* <action>:
* If NULL, no action is performed, but count is still returned.
* Otherwise called for each type of attributes, or if none exist,
* called once with NULL parameter.
* Return:
* Count of times <action> would have been called w/ non-NULL data.
* If <action> is not NULL, Hwcentry fields will be set as follows:
* <ctr->name>:
* HWC alias name, e.g. dcrm.
* <ctr->int_name>:
* The internal HWC specification, e.g. BSQ_cache_reference~emask=0x0100.
* <ctr->reg_num>:
* Register number if specified by the table, REGNO_ANY otherwise.
* <ctr->metric>:
* Descriptive name, e.g. "D$ Read Misses".
* <ctr->lval>:
* Low-resolution overflow value.
* <ctr->val>:
* Default overflow value.
* <ctr->hval>:
* High-resolution overflow value.
* <ctr->timecvt>:
* multiplier to convert metric to time, 0 otherwise.
* <ctr->memop>:
* ABST_* type for this counter.
* <ctr->reg_list>:
* Array of legal <reg_num> values. Terminated by REGNO_ANY.
*
* Note: All fields point to static data, none should be freed.
*/
extern Hwcentry **hwc_get_raw_ctrs (int forKernel);
/* Return:
* Table of raw (not well-known) counters supported by this system.
* Last element in array will be NULL.
* Table and its elements should NOT be freed by the caller.
*/
extern unsigned hwc_scan_raw_ctrs (void (*action)(const Hwcentry *));
/* Call <action> for each raw counter.
* Input:
* <action>:
* If NULL, no action is performed, but count is still returned.
* Otherwise called for each type of attributes, or if none exist,
* called once with NULL parameter.
* Return:
* Count of times <action> would have been called w/ non-NULL data.
* If <action> is not NULL, Hwcentry fields will be set as follows:
* <ctr->name>:
* HWC raw name without attributes, e.g. BSQ_cache_reference.
* <ctr->int_name>:
* NULL.
* <ctr->metric>:
* NULL.
* The remainder of the fields are the same as for
* hwc_scan_std_ctrs().
*
* Note: All fields point to static data, none should be freed.
*/
extern void
hwc_usage (int forKernel, const char *cmd, const char *dataspace_msg);
/* Print an i18n'd description of "-h" usage, used by collect and er_kernel.
*/
extern void hwc_usage_f (int forKernel, FILE *f, const char *cmd,
const char *dataspace_msg, int show_syntax,
int show_short_desc);
/* Print an i18n'd description of "-h" usage to a FILE. Used by GUI. */
extern char *hwc_rate_string (const Hwcentry *pctr, int force_numeric_format);
/* Returns {"on"|"hi"|"lo"|""|<value>}. Return value must be freed by caller. */
extern char *hwc_i18n_metric (const Hwcentry *ctr);
/* Get a basic lable for a counter, properly i18n'd.
* Note: NOT MT SAFE.
* Examples:
* CPU Cycles
* DC_rd Events
* Pseudocode:
* if(ctr->metric != NULL) {
* sprintf(metricbuf, PTXT(ctr->metric) );
* } else if (ctr->name != NULL) {
* sprintf(metricbuf, GTXT("%s Events"), ctr->name );
* } else if (ctr->int_name != NULL) {
* sprintf(metricbuf, GTXT("%s Events"), ctr->int_name );
* }
* Return: pointer to a buffer containing the above description.
*/
extern char *hwc_hwcentry_string (char *buf, size_t buflen, const Hwcentry *ctr);
/* Get a i18n'd description of a HW counter's options.
* Examples of well-known counters:
* cycles[/{0|1}],9999991 ('CPU Cycles', alias for Cycle_cnt; CPU-cycles)
* dcr[/0],1000003 ('D$ Read Refs', alias for DC_rd; load events)
* Examples of raw counters:
* Cycle_cnt[/{0|1}],1000003 (CPU-cycles)
* DC_rd[/0],1000003 (load events)
* Return: <buf>, filled in.
*/
extern char *hwc_hwcentry_specd_string (char *buf, size_t buflen, const Hwcentry *ctr);
/* Get a i18n'd description of a HW counter's specific configuration.
* Examples of well-known counters:
* cycles,9999991 ('CPU Cycles')
* +dcr/0,1000003 ('D$ Read Refs')
* Examples of raw counters:
* Cycle_cnt,1000003
* +DC_rd/0,1000003
* Return: <buf>, filled in.
*/
extern const char *hwc_memop_string (ABST_type memop);
/* Get a i18n'd description of a variable of type ABST_type.
* Return: pointer to static string.
*/
#ifdef __cplusplus
}
#endif
#endif
|