1 /* Copyright (C) 2021 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
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)
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.
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. */
21 /* Hardware counter profiling */
26 #ifdef LIBCOLLECTOR_SRC /* running in libcollector */
27 #define hwcfuncs_int_logerr __collector_hwcfuncs_int_logerr
28 #define hwcfuncs_parse_ctr __collector_hwcfuncs_parse_ctr
29 #define hwcfuncs_parse_attrs __collector_hwcfuncs_parse_attrs
30 #define hwcfuncs_bind_descriptor __collector_hwcfuncs_bind_descriptor
31 #define hwcfuncs_bind_hwcentry __collector_hwcfuncs_bind_hwcentry
32 #define hwcfuncs_assign_regnos __collector_hwcfuncs_assign_regnos
33 #define regno_is_valid __collector_regno_is_valid
34 #define hwcfuncs_get_ctrs __collector_hwcfuncs_get_ctrs
35 #define hwcfuncs_errmsg_get __collector_hwcfuncs_errmsg_get
36 #endif /* --- LIBCOLLECTOR_SRC --- */
38 #include <signal.h> /* siginfo_t */
39 #include <limits.h> /* UINT64_t */
40 #include <sys/types.h>
43 #include "hwcentry.h" /* for Hwcentry type */
46 typedef unsigned int uint_t
;
52 /*---------------------------------------------------------------------------*/
55 #define HWC_DEBUG 0 /* 0/1 to enable extra HWC debug */
57 /*---------------------------------------------------------------------------*/
59 /* generic hw event */
60 typedef struct _hwc_event_t
61 { /* generalized counter event */
62 hrtime_t ce_hrt
; /* gethrtime() */
63 uint64_t ce_pic
[MAX_PICS
]; /* counter samples or start values */
66 /* supplementary data that accompanies some hw events */
68 { /* supplementary data fields */
69 uint64_t smpl_pc
; /* pc related to event */
70 uint64_t smpl_data_source
; /* chip-specific data source encoding */
71 uint64_t smpl_latency
; /* latency related to event */
72 uint64_t smpl_mem_addr
; /* memory address related to event */
74 #define HWCFUNCS_INVALID_U64 0xFEEDBEEFDEADBEEFllu /* identifies fields as unused */
76 typedef struct { /* supplementary data fields */
77 hwc_sample_t sample
[MAX_PICS
]; /* counter samples or start values */
78 } hwc_event_samples_t
;
80 #define HWCFUNCS_SAMPLE_RESET(sample) \
82 (sample)->smpl_pc =HWCFUNCS_INVALID_U64; \
83 (sample)->smpl_data_source =HWCFUNCS_INVALID_U64; \
84 (sample)->smpl_latency =HWCFUNCS_INVALID_U64; \
85 (sample)->smpl_mem_addr =HWCFUNCS_INVALID_U64; \
88 #define HWCFUNCS_SAMPLE_IS_RESET(sample) \
90 (sample)->smpl_pc ==HWCFUNCS_INVALID_U64 && \
91 (sample)->smpl_data_source==HWCFUNCS_INVALID_U64 && \
92 (sample)->smpl_latency ==HWCFUNCS_INVALID_U64 && \
93 (sample)->smpl_mem_addr ==HWCFUNCS_INVALID_U64 \
96 /*---------------------------------------------------------------------------*/
99 #define HW_INTERVAL_MAX UINT64_MAX
100 #define HW_INTERVAL_PRESET(x) (HW_INTERVAL_MAX - ((uint64_t)(x) - 1))
101 #define HW_INTERVAL_TYPE(x) ((uint64_t) (x)
104 #define HWCFUNCS_MAX_ATTRS 20
105 #define HWCFUNCS_PARSE_ATTR '~'
106 #define HWCFUNCS_PARSE_EQUAL '='
107 #define HWCFUNCS_PARSE_BACKTRACK '+'
108 #define HWCFUNCS_PARSE_BACKTRACK_OFF '-'
109 #define HWCFUNCS_PARSE_REGNUM '/'
110 #define HWCFUNCS_PARSE_VALUE ','
113 #define HWCFUNCS_ERROR_GENERIC (-1)
114 #define HWCFUNCS_ERROR_NOT_SUPPORTED (-2)
115 #define HWCFUNCS_ERROR_ALREADY_CALLED (-3)
116 #define HWCFUNCS_ERROR_HWCINIT (-4)
117 #define HWCFUNCS_ERROR_HWCARGS (-5)
118 #define HWCFUNCS_ERROR_MEMORY (-6)
119 #define HWCFUNCS_ERROR_UNAVAIL (-7)
120 #define HWCFUNCS_ERROR_ERRNO_ZERO (-8)
121 #define HWCFUNCS_ERROR_UNEXPECTED (-99)
123 /*---------------------------------------------------------------------------*/
126 typedef void (*hwcfuncs_abort_fn_t
) (int errnum
, const char *msg
);
128 extern void hwcfuncs_int_logerr(const char *format
,...);
129 /* Log an error to the internal error buffer. See hwcfuncs_errmsg_get().
130 Note: Not MT-safe; don't even enable logging in an MT environment.
131 Recommend using this call only during init.
132 Note: when a libcpc call fails, it may automatically call
133 cpcN_capture_errmsg() to log the error message in the same internal buffer.
134 Recommend using this call only for non-cpc failures.
137 #define HWCFUNCS_SUPPORT_OVERFLOW_PROFILING 0x01llu
138 #define HWCFUNCS_SUPPORT_PEBS_SAMPLING 0x02llu
139 #define HWCFUNCS_SUPPORT_OVERFLOW_CTR_ID 0x04llu // OS identifies which counter overflowed
140 /* get info about session
142 <cpuver>: if not NULL, returns value of CPC cpu version
143 <cciname>: if not NULL, returns name of CPU
144 <npics>: if not NULL, returns maximum # of HWCs
145 <docref>: if not NULL, returns documentation reference
146 <support>: if not NULL, returns bitmask (see above) of hwc support
150 typedef void* (*hwcfuncs_tsd_get_fn_t
) (void);
151 typedef void (hwcf_hwc_cb_t
) (uint_t cpcregno
, const char *name
);
152 typedef void (hwcf_attr_cb_t
) (const char *attr
);
155 hwcfuncs_parse_ctr (const char *counter_def
, int *pplus
, char **pnameOnly
,
156 char **pattrs
, char **pregstr
, regno_t
*pregno
);
157 /* Parse a counter definition string (value must already be stripped off).
159 <counter_def>: input whose format is
160 [+|-]<countername>[~attrs...][/<regno>]
161 pointers to return values: Any can be NULL.
163 <plus>: 1 if [+] is found, -1 if [-] is found, 0 otherwise
164 <pnameonly>: strdup(<countername>)
165 <pattrs>: strdup([~attrs...]) if specified, NULL otherwise.
166 <pregstr>: strdup(/<regno>) if specified, NULL otherwise.
167 <pregno>: <regno> if readable, REGNO_ANY if not specd, or -2 otherwise.
174 } hwcfuncs_attr_t
; /* matches cpc_attr_t */
176 void * hwcfuncs_parse_attrs (const char *countername
,
177 hwcfuncs_attr_t attrs
[], unsigned max_attrs
,
178 uint_t
*pnum_attrs
, char **errstring
);
179 /* Extract the attribute fields from <countername>.
181 <countername>: string whose format is
182 [+]<ctrname>[~attributes...][/<regno>][,...]
183 <attrs>: array of attributes to be returned
184 <max_attrs>: number of elements in <attrs>
185 <pnum_attrs>: if not NULL, will return how many attrs were found.
186 <errstring>: pointer to a buffer for storing error info, or NULL.
187 Return: upon success, a pointer to an allocated copy of <countername>, or
188 NULL if there's a failure. (A copy is made in order to provide storage
189 for the ca_name fields in the <attrs> array.)
191 The pointer should be freed when <attrs> is no longer in use.
192 <attrs> will be filled in data from countername.
193 <pnum_attrs> will have the number of elements in <attrs>. May be
194 non-zero even if return value indicates an error.
195 <errstring> NULL if no error, otherwise, a malloc'd GTXT string.
198 extern int hwcfuncs_bind_descriptor (const char *defstring
);
199 /* Bind counters to resources.
201 <defstring>: string whose format is
202 :%s:%s:0x%x:%d:%d,0x%x[:%s...repeat for each ctr]
203 where the fields are:
204 :<userName>:<internalCtr>:<register>:<timeoutVal>:<tag>:<memop>
205 Return: 0 if successful
206 HWCFUNCS_ERROR_HWCINIT if resources unavailable
207 HWCFUNCS_ERROR_HWCARGS if counters were not specified correctly
210 extern int hwcfuncs_bind_hwcentry (const Hwcentry
*entries
[],
212 /* Bind counters to resources.
214 <entries>: array of counters
215 <numctrs>: number of items in <entries>
216 Return: 0 if successful
217 HWCFUNCS_ERROR_HWCINIT if resources unavailable
218 HWCFUNCS_ERROR_HWCARGS if counters were not specified correctly
221 extern int hwcfuncs_assign_regnos (Hwcentry
*entries
[], unsigned numctrs
);
222 /* Assign entries[]->reg_num values as needed by platform
223 Note: modifies <entries> by supplying a regno to each counter
225 <entries>: array of counters
226 <numctrs>: number of items in <entries>
228 <entries>: array of counters is modified
229 Return: 0 if successful
230 HWCFUNCS_ERROR_HWCINIT if resources unavailable
231 HWCFUNCS_ERROR_HWCARGS if counters were not specified correctly
234 extern int regno_is_valid (const Hwcentry
*pctr
, regno_t regno
);
235 /* return 1 if <regno> is in Hwcentry's list
237 <pctr>: counter definition, reg_list[] should be initialized
238 <regno>: register to check
239 Return: 1 if <regno> is in Hwcentry's list, 0 otherwise
242 extern Hwcentry
**hwcfuncs_get_ctrs (unsigned *defcnt
);
243 /* Get descriptions of the currently bound counters.
245 <defcnt>: if not NULL, returns number of counter definitions.
247 table of counter definition pointers
250 extern char *hwcfuncs_errmsg_get (char * buf
, size_t bufsize
,
252 /* Gets a recent HWC error message.
253 To clear previous error messages and insure error message is enabled,
254 call hwcfuncs_errmsg_get(NULL,0,1).
255 Once enabled, one error is stored in an internal buffer. A call to this
256 function will clear the buffer and allow a new message to be captured.
257 Note: Not MT-safe - don't enable this feature in an MT environment.
259 <buf>: pointer to buffer or NULL.
260 <bufsize>: size of <buf>
261 <enable_capture>: 0 - disable buffering, 1 - enable buffering.
262 Return: error string or an empty string.
269 #endif /* ! __HWCFUNCS_H */