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