1 /* Copyright (C) 2021-2024 Free Software Foundation, Inc. 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 111 extern "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 331