]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gprofng/common/hwcdrv.h
Update year range in gprofng copyright notices
[thirdparty/binutils-gdb.git] / gprofng / common / hwcdrv.h
CommitLineData
76bdc726 1/* Copyright (C) 2021-2023 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/* Hardware counter profiling driver's header */
22
23#ifndef __HWCDRV_H
24#define __HWCDRV_H
25
26#include "hwcfuncs.h"
27
28#ifdef linux
29#define HWCFUNCS_SIGNAL SIGIO
30#define HWCFUNCS_SIGNAL_STRING "SIGIO"
31#else
32#define HWCFUNCS_SIGNAL SIGEMT
33#define HWCFUNCS_SIGNAL_STRING "SIGEMT"
34#endif
35
36#ifndef LIBCOLLECTOR_SRC /* not running in libcollector */
37#include <string.h>
38
39#else /* running in libcollector */
40#include "collector_module.h"
41#include "libcol_util.h"
42
43#define get_hwcdrv __collector_get_hwcdrv
44#define hwcdrv_drivers __collector_hwcdrv_drivers
45#define hwcdrv_cpc1_api __collector_hwcdrv_cpc1_api
46#define hwcdrv_cpc2_api __collector_hwcdrv_cpc2_api
47#define hwcdrv_default __collector_hwcdrv_default
48#define hwcdrv_driver __collector_hwcdrv_driver
49#define hwcdrv_init __collector_hwcdrv_init
50#define hwcdrv_get_info __collector_hwcdrv_get_info
51#define hwcdrv_enable_mt __collector_hwcdrv_enable_mt
52#define hwcdrv_get_descriptions __collector_hwcdrv_get_descriptions
53#define hwcdrv_assign_regnos __collector_hwcdrv_assign_regnos
54#define hwcdrv_create_counters __collector_hwcdrv_create_counters
55#define hwcdrv_start __collector_hwcdrv_start
56#define hwcdrv_overflow __collector_hwcdrv_overflow
57#define hwcdrv_read_events __collector_hwcdrv_read_events
58#define hwcdrv_sighlr_restart __collector_hwcdrv_sighlr_restart
59#define hwcdrv_lwp_suspend __collector_hwcdrv_lwp_suspend
60#define hwcdrv_lwp_resume __collector_hwcdrv_lwp_resume
61#define hwcdrv_free_counters __collector_hwcdrv_free_counters
62#define hwcdrv_lwp_init __collector_hwcdrv_lwp_init
63#define hwcdrv_lwp_fini __collector_hwcdrv_lwp_fini
64#define hwcdrv_assign_all_regnos __collector_hwcdrv_assign_all_regnos
65#define hwcdrv_lookup_cpuver __collector_hwcdrv_lookup_cpuver
66#define hwcfuncs_int_capture_errmsg __collector_hwcfuncs_int_capture_errmsg
67
68#define GTXT(x) x
69
70/* Implemented by libcollector */
71#define calloc __collector_calloc
72#define close CALL_UTIL(close)
73#define fcntl CALL_UTIL(fcntl)
74#define fprintf CALL_UTIL(fprintf)
75//#define free __collector_free
76#define free(...)
77#define gethrtime __collector_gethrtime
78#define ioctl CALL_UTIL(ioctl)
79#define malloc __collector_malloc
80#define memcpy __collector_memcpy
81#define memset CALL_UTIL(memset)
82#define mmap CALL_UTIL(mmap)
83#define snprintf CALL_UTIL(snprintf)
84#define strchr CALL_UTIL(strchr)
85#define strcmp CALL_UTIL(strcmp)
86#define strncmp CALL_UTIL(strncmp)
87#define strcpy CALL_UTIL(strcpy)
88#define strdup __collector_strdup
89#define strncpy CALL_UTIL(strncpy)
90#define strerror CALL_UTIL(strerror)
91#define strlen CALL_UTIL(strlen)
92#define strstr CALL_UTIL(strstr)
93#define strtol CALL_UTIL(strtol)
94#define strtoll CALL_UTIL(strtoll)
95#define strtoul CALL_UTIL(strtoul)
96#define strtoull CALL_UTIL(strtoull)
97#define syscall CALL_UTIL(syscall)
98#define sysconf CALL_UTIL(sysconf)
99#define vsnprintf CALL_UTIL(vsnprintf)
100
101#endif /* --- LIBCOLLECTOR_SRC --- */
102
103/* TprintfT(<level>,...) definitions. Adjust per module as needed */
104#define DBG_LT0 0 // for high-level configuration, unexpected errors/warnings
105#define DBG_LT1 1 // for configuration details, warnings
106#define DBG_LT2 2
107#define DBG_LT3 3
108#define DBG_LT4 4
109
110#ifdef __cplusplus
111extern "C"
112{
113#endif
114
115 /* hwcdrv api */
116 typedef struct
117 {
118 int (*hwcdrv_init)(hwcfuncs_abort_fn_t abort_ftn, int * tsd_sz);
119 /* Initialize hwc counter library (do not call again after fork)
120 Must be called before other functions.
121 Input:
122 <abort_ftn>: NULL or callback function to be used for fatal errors
123 <tsd_sz>: If not NULL, returns size in bytes required for thread-specific storage
124 Return: 0 if successful
125 */
126
127 void (*hwcdrv_get_info)(int *cpuver, const char **cciname, uint_t *npics,
128 const char **docref, uint64_t *support);
129 /* get info about session
130 Input:
131 <cpuver>: if not NULL, returns value of CPC cpu version
132 <cciname>: if not NULL, returns name of CPU
133 <npics>: if not NULL, returns maximum # of HWCs
134 <docref>: if not NULL, returns documentation reference
135 <support>: if not NULL, returns bitmask (see hwcfuncs.h) of hwc support
136 Return: 0 if successful, nonzero otherwise
137 */
138
139 int (*hwcdrv_enable_mt)(hwcfuncs_tsd_get_fn_t tsd_ftn);
140 /* Enables multi-threaded mode (do not need to call again after fork)
141 Input:
142 <tsd_ftn>: If <tsd_sz>==0, this parameter is ignored.
143 Otherwise:
144 tsd_ftn() must be able to return a pointer to thread-specific
145 memory of <tsd_sz> bytes.
146 For a given thread, tsd_ftn() must
147 always return the same pointer.
148 Return: none
149 */
150
151 int (*hwcdrv_get_descriptions)(hwcf_hwc_cb_t *hwc_find_action,
152 hwcf_attr_cb_t *attr_find_action);
153 /* Initiate callbacks with all available HWC names and and HWC attributes.
154 Input:
155 <hwc_find_action>: if not NULL, will be called once for each HWC
156 <attr_find_action>: if not NULL, will be called once for each attribute
157 Return: 0 if successful
158 or a cpc return code upon error
159 */
160
161 int (*hwcdrv_assign_regnos)(Hwcentry* entries[], unsigned numctrs);
162 /* Assign entries[]->reg_num values as needed by platform
163 Input:
164 <entries>: array of counters
165 <numctrs>: number of items in <entries>
166 Return: 0 if successful
167 HWCFUNCS_ERROR_HWCINIT if resources unavailable
168 HWCFUNCS_ERROR_HWCARGS if counters were not specified correctly
169 */
170
171 int (*hwcdrv_create_counters)(unsigned hwcdef_cnt, Hwcentry *hwcdef);
172 /* Create the counters, but don't start them.
173 call this once in main thread to create counters.
174 Input:
175 <defcnt>: number of counter definitions.
176 <hwcdef>: counter definitions.
177 Return: 0 if successful
178 or a cpc return code upon error
179 */
180
181 int (*hwcdrv_start)(void);
182 /* Start the counters.
183 call this once in main thread to start counters.
184 Return: 0 if successful
185 or a cpc return code upon error
186 */
187
188 int (*hwcdrv_overflow)(siginfo_t *si, hwc_event_t *sample,
189 hwc_event_t *lost_samples);
190 /* Linux only. Capture current counter values.
191 This is intended to be called from SIGEMT handler;
192 Input:
193 <si>: signal handler context information
194 <sample>: returns non-zero values for counters that overflowed
195 <lost_samples>: returns non-zero values for counters that "lost" counts
196 Return: 0 if successful
197 or a cpc return code upon error.
198 */
199
200 int (*hwcdrv_read_events)(hwc_event_t *overflow_data,
201 hwc_event_samples_t *sampled_data);
202 /* Read current counter values and samples. Read of samples is destructive.
203 Note: hwcdrv_read_events is not supported on Linux.
204 <overflow_data>: returns snapshot of counter values
205 <sampled_data>: returns sampled data
206 Return: 0 if successful
207 HWCFUNCS_ERROR_UNAVAIL if resource unavailable(e.g. called before initted)
208 (other values may be possible)
209 */
210
211 int (*hwcdrv_sighlr_restart)(const hwc_event_t* startVals);
212 /* Restarts the counters at the given value.
213 This is intended to be called from SIGEMT handler;
214 Input:
215 <startVals>: Solaris: new start values.
216 Linux: pointer may be NULL; startVals is ignored.
217 Return: 0 if successful
218 or a cpc return code upon error.
219 */
220
221 int (*hwcdrv_lwp_suspend)(void);
222 /* Attempt to stop counters on this lwp only.
223 hwcdrv_lwp_resume() should be used to restart counters.
224 Return: 0 if successful
225 or a cpc return code upon error.
226 */
227
228 int (*hwcdrv_lwp_resume)(void);
229 /* Attempt to restart counters on this lwp when counters were
230 stopped with hwcdrv_lwp_suspend().
231 Return: 0 if successful
232 or a cpc return code upon error.
233 */
234
235 int (*hwcdrv_free_counters)(void);
236 /* Stops counters on this lwp only and frees resources.
237 This will fail w/ unpredictable results if other lwps's are
238 still running. After this call returns,
239 hwcdrv_create_counters() may be called with new values.
240 Return: 0 if successful
241 or a cpc return code upon error.
242 */
243
244 int (*hwcdrv_lwp_init)(void);
245 /* per-thread counter init.
246 Solaris: nop.
247 Linux: just after thread creation call this from inside thread
248 to create context and start counters.
249 Return: 0 if successful
250 or a perfctr return code upon error
251 */
252
253 void (*hwcdrv_lwp_fini)(void);
254 /* per-thread counter cleanup.
255 Solaris: nop.
256 Linux: call in each thread upon thread destruction.
257 */
258
259 int hwcdrv_init_status;
260 } hwcdrv_api_t;
261
262 extern hwcdrv_api_t *get_hwcdrv ();
263 extern hwcdrv_api_t *__collector_get_hwcdrv ();
264 extern int __collector_hwcfuncs_bind_descriptor (const char *defstring);
265 extern Hwcentry **__collector_hwcfuncs_get_ctrs (unsigned *defcnt);
266 extern hwcdrv_api_t *hwcdrv_drivers[]; // array of available drivers
267
268 /* prototypes for internal use by hwcdrv drivers */
269 typedef struct
270 { // see hwcdrv_get_info() for field definitions
271 int cpcN_cpuver;
272 uint_t cpcN_npics;
273 const char *cpcN_docref;
274 const char *cpcN_cciname;
275 } hwcdrv_about_t;
276
277 extern int hwcdrv_assign_all_regnos (Hwcentry* entries[], unsigned numctrs);
278 /* assign user's counters to specific CPU registers */
279
280 extern int hwcdrv_lookup_cpuver (const char * cpcN_cciname);
281 /* returns hwc_cpus.h ID for a given string. */
282
283 extern void hwcfuncs_int_capture_errmsg (const char *fn, int subcode,
284 const char *fmt, va_list ap);
285#define logerr hwcfuncs_int_logerr
286
287 /*---------------------------------------------------------------------------*/
288 /* prototypes for internal use by linux hwcdrv drivers */
289#define PERFCTR_FIXED_MAGIC 0x40000000 /* tells perfctr to use intel fixed pmcs */
290#define PERFCTR_UMASK_SHIFT 8
291#define EXTENDED_EVNUM_2_EVSEL(evnum) \
292 ( (((eventsel_t)(evnum) & 0x0f00ULL) << 24) | ((eventsel_t)(evnum) & ~0x0f00ULL) )
293
294 typedef uint64_t eventsel_t;
295 extern int hwcfuncs_get_x86_eventsel (unsigned int regno, const char *int_name,
296 eventsel_t *return_event, uint_t *return_pmc_sel);
297
298 typedef int (hwcdrv_get_events_fn_t) (hwcf_hwc_cb_t *hwc_cb);
299 typedef int (hwcdrv_get_eventnum_fn_t) (const char *eventname, uint_t pmc,
300 eventsel_t *eventnum,
301 eventsel_t *valid_umask, uint_t *pmc_sel);
302 extern hwcdrv_get_eventnum_fn_t *hwcdrv_get_x86_eventnum;
303
304 typedef struct
305 {
306 const char * attrname; // user-visible name of attribute
307 int is_inverted; // nonzero means boolean attribute is inverted
308 eventsel_t mask; // which attribute bits can be set?
309 eventsel_t shift; // how far to shift bits for use in x86 register
310 } attr_info_t;
311 extern const attr_info_t *perfctr_attrs_table;
312
313 /* hdrv_pcbe api: cpu-specific drivers for Linux */
314 typedef struct
315 {
316 int (*hdrv_pcbe_init)(void);
317 uint_t (*hdrv_pcbe_ncounters)(void);
318 const char *(*hdrv_pcbe_impl_name)(void);
319 const char *(*hdrv_pcbe_cpuref)(void);
320 int (*hdrv_pcbe_get_events)(hwcf_hwc_cb_t *hwc_cb);
321 int (*hdrv_pcbe_get_eventnum)(const char * eventname, uint_t pmc,
322 eventsel_t *eventnum, eventsel_t *valid_umask,
323 uint_t *pmc_sel);
324 } hdrv_pcbe_api_t;
325
326#ifdef __cplusplus
327}
328#endif
329
330#endif