xref: /netbsd-src/external/gpl3/binutils.old/dist/gprofng/common/hwcfuncs.h (revision c42dbd0ed2e61fe6eda8590caa852ccf34719964)
1 /* Copyright (C) 2021 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 */
22 
23 #ifndef __HWCFUNCS_H
24 #define __HWCFUNCS_H
25 
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 --- */
37 
38 #include <signal.h>     /* siginfo_t */
39 #include <limits.h>     /* UINT64_t */
40 #include <sys/types.h>
41 #include <stdint.h>
42 
43 #include "hwcentry.h"   /* for Hwcentry type */
44 #include "gp-time.h"
45 
46 typedef unsigned int uint_t;
47 
48 #ifdef	__cplusplus
49 extern "C" {
50 #endif
51 
52 /*---------------------------------------------------------------------------*/
53 /* compile options */
54 
55 #define HWC_DEBUG   0 /* 0/1 to enable extra HWC debug */
56 
57 /*---------------------------------------------------------------------------*/
58 /* typedefs */
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 */
64   } hwc_event_t;
65 
66   /* supplementary data that accompanies some hw events */
67   typedef struct
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 */
73   } hwc_sample_t;
74 #define HWCFUNCS_INVALID_U64 0xFEEDBEEFDEADBEEFllu /* identifies fields as unused */
75 
76 typedef struct {                                /* supplementary data fields */
77     hwc_sample_t sample[MAX_PICS];  /* counter samples or start values */
78 } hwc_event_samples_t;
79 
80 #define HWCFUNCS_SAMPLE_RESET(sample) \
81 	do { \
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; \
86 	} while(0)
87 
88 #define HWCFUNCS_SAMPLE_IS_RESET(sample) \
89 	( \
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 \
94 	)
95 
96 /*---------------------------------------------------------------------------*/
97 /* macros */
98 
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)
102 
103 /* parsing */
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            ','
111 
112 /* error codes */
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)
122 
123 /*---------------------------------------------------------------------------*/
124 /* prototypes */
125 
126 typedef void (*hwcfuncs_abort_fn_t) (int errnum, const char *msg);
127 
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.
135  */
136 
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
141      Input:
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
147      Return: none
148    */
149 
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);
153 
154   extern void
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).
158      Input:
159        <counter_def>: input whose format is
160 	 [+|-]<countername>[~attrs...][/<regno>]
161        pointers to return values:  Any can be NULL.
162      Return:
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.
168    */
169 
170   typedef struct
171   {
172     char *ca_name;
173     uint64_t ca_val;
174   } hwcfuncs_attr_t; /* matches cpc_attr_t */
175 
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>.
180        Input:
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.)
190 
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.
196    */
197 
198   extern int hwcfuncs_bind_descriptor (const char *defstring);
199   /* Bind counters to resources.
200      Input:
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
208    */
209 
210   extern int hwcfuncs_bind_hwcentry (const Hwcentry *entries[],
211 				     unsigned numctrs);
212   /* Bind counters to resources.
213      Input:
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
219    */
220 
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
224      Input:
225        <entries>: array of counters
226        <numctrs>: number of items in <entries>
227      Output:
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
232    */
233 
234   extern int regno_is_valid (const Hwcentry *pctr, regno_t regno);
235   /* return 1 if <regno> is in Hwcentry's list
236      Input:
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
240    */
241 
242   extern Hwcentry **hwcfuncs_get_ctrs (unsigned *defcnt);
243   /* Get descriptions of the currently bound counters.
244      Input:
245        <defcnt>: if not NULL, returns number of counter definitions.
246      Return:
247        table of counter definition pointers
248    */
249 
250   extern char *hwcfuncs_errmsg_get (char * buf, size_t bufsize,
251 				    int enable_capture);
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.
258      Input:
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.
263    */
264 
265 #ifdef	__cplusplus
266 }
267 #endif
268 
269 #endif /* ! __HWCFUNCS_H */
270