hwcfuncs.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /* Copyright (C) 2021 Free Software Foundation, Inc.
  2. Contributed by Oracle.
  3. This file is part of GNU Binutils.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3, or (at your option)
  7. any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, 51 Franklin Street - Fifth Floor, Boston,
  15. MA 02110-1301, USA. */
  16. /* Hardware counter profiling */
  17. #ifndef __HWCFUNCS_H
  18. #define __HWCFUNCS_H
  19. #ifdef LIBCOLLECTOR_SRC /* running in libcollector */
  20. #define hwcfuncs_int_logerr __collector_hwcfuncs_int_logerr
  21. #define hwcfuncs_parse_ctr __collector_hwcfuncs_parse_ctr
  22. #define hwcfuncs_parse_attrs __collector_hwcfuncs_parse_attrs
  23. #define hwcfuncs_bind_descriptor __collector_hwcfuncs_bind_descriptor
  24. #define hwcfuncs_bind_hwcentry __collector_hwcfuncs_bind_hwcentry
  25. #define hwcfuncs_assign_regnos __collector_hwcfuncs_assign_regnos
  26. #define regno_is_valid __collector_regno_is_valid
  27. #define hwcfuncs_get_ctrs __collector_hwcfuncs_get_ctrs
  28. #define hwcfuncs_errmsg_get __collector_hwcfuncs_errmsg_get
  29. #endif /* --- LIBCOLLECTOR_SRC --- */
  30. #include <signal.h> /* siginfo_t */
  31. #include <limits.h> /* UINT64_t */
  32. #include <sys/types.h>
  33. #include <stdint.h>
  34. #include "hwcentry.h" /* for Hwcentry type */
  35. #include "gp-time.h"
  36. typedef unsigned int uint_t;
  37. #ifdef __cplusplus
  38. extern "C" {
  39. #endif
  40. /*---------------------------------------------------------------------------*/
  41. /* compile options */
  42. #define HWC_DEBUG 0 /* 0/1 to enable extra HWC debug */
  43. /*---------------------------------------------------------------------------*/
  44. /* typedefs */
  45. /* generic hw event */
  46. typedef struct _hwc_event_t
  47. { /* generalized counter event */
  48. hrtime_t ce_hrt; /* gethrtime() */
  49. uint64_t ce_pic[MAX_PICS]; /* counter samples or start values */
  50. } hwc_event_t;
  51. /* supplementary data that accompanies some hw events */
  52. typedef struct
  53. { /* supplementary data fields */
  54. uint64_t smpl_pc; /* pc related to event */
  55. uint64_t smpl_data_source; /* chip-specific data source encoding */
  56. uint64_t smpl_latency; /* latency related to event */
  57. uint64_t smpl_mem_addr; /* memory address related to event */
  58. } hwc_sample_t;
  59. #define HWCFUNCS_INVALID_U64 0xFEEDBEEFDEADBEEFllu /* identifies fields as unused */
  60. typedef struct { /* supplementary data fields */
  61. hwc_sample_t sample[MAX_PICS]; /* counter samples or start values */
  62. } hwc_event_samples_t;
  63. #define HWCFUNCS_SAMPLE_RESET(sample) \
  64. do { \
  65. (sample)->smpl_pc =HWCFUNCS_INVALID_U64; \
  66. (sample)->smpl_data_source =HWCFUNCS_INVALID_U64; \
  67. (sample)->smpl_latency =HWCFUNCS_INVALID_U64; \
  68. (sample)->smpl_mem_addr =HWCFUNCS_INVALID_U64; \
  69. } while(0)
  70. #define HWCFUNCS_SAMPLE_IS_RESET(sample) \
  71. ( \
  72. (sample)->smpl_pc ==HWCFUNCS_INVALID_U64 && \
  73. (sample)->smpl_data_source==HWCFUNCS_INVALID_U64 && \
  74. (sample)->smpl_latency ==HWCFUNCS_INVALID_U64 && \
  75. (sample)->smpl_mem_addr ==HWCFUNCS_INVALID_U64 \
  76. )
  77. /*---------------------------------------------------------------------------*/
  78. /* macros */
  79. #define HW_INTERVAL_MAX UINT64_MAX
  80. #define HW_INTERVAL_PRESET(x) (HW_INTERVAL_MAX - ((uint64_t)(x) - 1))
  81. #define HW_INTERVAL_TYPE(x) ((uint64_t) (x)
  82. /* parsing */
  83. #define HWCFUNCS_MAX_ATTRS 20
  84. #define HWCFUNCS_PARSE_ATTR '~'
  85. #define HWCFUNCS_PARSE_EQUAL '='
  86. #define HWCFUNCS_PARSE_BACKTRACK '+'
  87. #define HWCFUNCS_PARSE_BACKTRACK_OFF '-'
  88. #define HWCFUNCS_PARSE_REGNUM '/'
  89. #define HWCFUNCS_PARSE_VALUE ','
  90. /* error codes */
  91. #define HWCFUNCS_ERROR_GENERIC (-1)
  92. #define HWCFUNCS_ERROR_NOT_SUPPORTED (-2)
  93. #define HWCFUNCS_ERROR_ALREADY_CALLED (-3)
  94. #define HWCFUNCS_ERROR_HWCINIT (-4)
  95. #define HWCFUNCS_ERROR_HWCARGS (-5)
  96. #define HWCFUNCS_ERROR_MEMORY (-6)
  97. #define HWCFUNCS_ERROR_UNAVAIL (-7)
  98. #define HWCFUNCS_ERROR_ERRNO_ZERO (-8)
  99. #define HWCFUNCS_ERROR_UNEXPECTED (-99)
  100. /*---------------------------------------------------------------------------*/
  101. /* prototypes */
  102. typedef void (*hwcfuncs_abort_fn_t) (int errnum, const char *msg);
  103. extern void hwcfuncs_int_logerr(const char *format,...);
  104. /* Log an error to the internal error buffer. See hwcfuncs_errmsg_get().
  105. Note: Not MT-safe; don't even enable logging in an MT environment.
  106. Recommend using this call only during init.
  107. Note: when a libcpc call fails, it may automatically call
  108. cpcN_capture_errmsg() to log the error message in the same internal buffer.
  109. Recommend using this call only for non-cpc failures.
  110. */
  111. #define HWCFUNCS_SUPPORT_OVERFLOW_PROFILING 0x01llu
  112. #define HWCFUNCS_SUPPORT_PEBS_SAMPLING 0x02llu
  113. #define HWCFUNCS_SUPPORT_OVERFLOW_CTR_ID 0x04llu // OS identifies which counter overflowed
  114. /* get info about session
  115. Input:
  116. <cpuver>: if not NULL, returns value of CPC cpu version
  117. <cciname>: if not NULL, returns name of CPU
  118. <npics>: if not NULL, returns maximum # of HWCs
  119. <docref>: if not NULL, returns documentation reference
  120. <support>: if not NULL, returns bitmask (see above) of hwc support
  121. Return: none
  122. */
  123. typedef void* (*hwcfuncs_tsd_get_fn_t) (void);
  124. typedef void (hwcf_hwc_cb_t) (uint_t cpcregno, const char *name);
  125. typedef void (hwcf_attr_cb_t) (const char *attr);
  126. extern void
  127. hwcfuncs_parse_ctr (const char *counter_def, int *pplus, char **pnameOnly,
  128. char **pattrs, char **pregstr, regno_t *pregno);
  129. /* Parse a counter definition string (value must already be stripped off).
  130. Input:
  131. <counter_def>: input whose format is
  132. [+|-]<countername>[~attrs...][/<regno>]
  133. pointers to return values: Any can be NULL.
  134. Return:
  135. <plus>: 1 if [+] is found, -1 if [-] is found, 0 otherwise
  136. <pnameonly>: strdup(<countername>)
  137. <pattrs>: strdup([~attrs...]) if specified, NULL otherwise.
  138. <pregstr>: strdup(/<regno>) if specified, NULL otherwise.
  139. <pregno>: <regno> if readable, REGNO_ANY if not specd, or -2 otherwise.
  140. */
  141. typedef struct
  142. {
  143. char *ca_name;
  144. uint64_t ca_val;
  145. } hwcfuncs_attr_t; /* matches cpc_attr_t */
  146. void * hwcfuncs_parse_attrs (const char *countername,
  147. hwcfuncs_attr_t attrs[], unsigned max_attrs,
  148. uint_t *pnum_attrs, char **errstring);
  149. /* Extract the attribute fields from <countername>.
  150. Input:
  151. <countername>: string whose format is
  152. [+]<ctrname>[~attributes...][/<regno>][,...]
  153. <attrs>: array of attributes to be returned
  154. <max_attrs>: number of elements in <attrs>
  155. <pnum_attrs>: if not NULL, will return how many attrs were found.
  156. <errstring>: pointer to a buffer for storing error info, or NULL.
  157. Return: upon success, a pointer to an allocated copy of <countername>, or
  158. NULL if there's a failure. (A copy is made in order to provide storage
  159. for the ca_name fields in the <attrs> array.)
  160. The pointer should be freed when <attrs> is no longer in use.
  161. <attrs> will be filled in data from countername.
  162. <pnum_attrs> will have the number of elements in <attrs>. May be
  163. non-zero even if return value indicates an error.
  164. <errstring> NULL if no error, otherwise, a malloc'd GTXT string.
  165. */
  166. extern int hwcfuncs_bind_descriptor (const char *defstring);
  167. /* Bind counters to resources.
  168. Input:
  169. <defstring>: string whose format is
  170. :%s:%s:0x%x:%d:%d,0x%x[:%s...repeat for each ctr]
  171. where the fields are:
  172. :<userName>:<internalCtr>:<register>:<timeoutVal>:<tag>:<memop>
  173. Return: 0 if successful
  174. HWCFUNCS_ERROR_HWCINIT if resources unavailable
  175. HWCFUNCS_ERROR_HWCARGS if counters were not specified correctly
  176. */
  177. extern int hwcfuncs_bind_hwcentry (const Hwcentry *entries[],
  178. unsigned numctrs);
  179. /* Bind counters to resources.
  180. Input:
  181. <entries>: array of counters
  182. <numctrs>: number of items in <entries>
  183. Return: 0 if successful
  184. HWCFUNCS_ERROR_HWCINIT if resources unavailable
  185. HWCFUNCS_ERROR_HWCARGS if counters were not specified correctly
  186. */
  187. extern int hwcfuncs_assign_regnos (Hwcentry *entries[], unsigned numctrs);
  188. /* Assign entries[]->reg_num values as needed by platform
  189. Note: modifies <entries> by supplying a regno to each counter
  190. Input:
  191. <entries>: array of counters
  192. <numctrs>: number of items in <entries>
  193. Output:
  194. <entries>: array of counters is modified
  195. Return: 0 if successful
  196. HWCFUNCS_ERROR_HWCINIT if resources unavailable
  197. HWCFUNCS_ERROR_HWCARGS if counters were not specified correctly
  198. */
  199. extern int regno_is_valid (const Hwcentry *pctr, regno_t regno);
  200. /* return 1 if <regno> is in Hwcentry's list
  201. Input:
  202. <pctr>: counter definition, reg_list[] should be initialized
  203. <regno>: register to check
  204. Return: 1 if <regno> is in Hwcentry's list, 0 otherwise
  205. */
  206. extern Hwcentry **hwcfuncs_get_ctrs (unsigned *defcnt);
  207. /* Get descriptions of the currently bound counters.
  208. Input:
  209. <defcnt>: if not NULL, returns number of counter definitions.
  210. Return:
  211. table of counter definition pointers
  212. */
  213. extern char *hwcfuncs_errmsg_get (char * buf, size_t bufsize,
  214. int enable_capture);
  215. /* Gets a recent HWC error message.
  216. To clear previous error messages and insure error message is enabled,
  217. call hwcfuncs_errmsg_get(NULL,0,1).
  218. Once enabled, one error is stored in an internal buffer. A call to this
  219. function will clear the buffer and allow a new message to be captured.
  220. Note: Not MT-safe - don't enable this feature in an MT environment.
  221. Input:
  222. <buf>: pointer to buffer or NULL.
  223. <bufsize>: size of <buf>
  224. <enable_capture>: 0 - disable buffering, 1 - enable buffering.
  225. Return: error string or an empty string.
  226. */
  227. #ifdef __cplusplus
  228. }
  229. #endif
  230. #endif /* ! __HWCFUNCS_H */