/* Copyright (C) 2021-2023 Free Software Foundation, Inc. Contributed by Oracle. This file is part of GNU Binutils. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ /* Hardware counter profiling */ #ifndef __HWCFUNCS_H #define __HWCFUNCS_H #ifdef LIBCOLLECTOR_SRC /* running in libcollector */ #define hwcfuncs_int_logerr __collector_hwcfuncs_int_logerr #define hwcfuncs_parse_ctr __collector_hwcfuncs_parse_ctr #define hwcfuncs_parse_attrs __collector_hwcfuncs_parse_attrs #define hwcfuncs_bind_descriptor __collector_hwcfuncs_bind_descriptor #define hwcfuncs_bind_hwcentry __collector_hwcfuncs_bind_hwcentry #define hwcfuncs_assign_regnos __collector_hwcfuncs_assign_regnos #define regno_is_valid __collector_regno_is_valid #define hwcfuncs_get_ctrs __collector_hwcfuncs_get_ctrs #define hwcfuncs_errmsg_get __collector_hwcfuncs_errmsg_get #endif /* --- LIBCOLLECTOR_SRC --- */ #include /* siginfo_t */ #include /* UINT64_t */ #include #include #include "hwcentry.h" /* for Hwcentry type */ #include "gp-time.h" typedef unsigned int uint_t; #ifdef __cplusplus extern "C" { #endif /*---------------------------------------------------------------------------*/ /* compile options */ #define HWC_DEBUG 0 /* 0/1 to enable extra HWC debug */ /*---------------------------------------------------------------------------*/ /* typedefs */ /* generic hw event */ typedef struct _hwc_event_t { /* generalized counter event */ hrtime_t ce_hrt; /* gethrtime() */ uint64_t ce_pic[MAX_PICS]; /* counter samples or start values */ } hwc_event_t; /* supplementary data that accompanies some hw events */ typedef struct { /* supplementary data fields */ uint64_t smpl_pc; /* pc related to event */ uint64_t smpl_data_source; /* chip-specific data source encoding */ uint64_t smpl_latency; /* latency related to event */ uint64_t smpl_mem_addr; /* memory address related to event */ } hwc_sample_t; #define HWCFUNCS_INVALID_U64 0xFEEDBEEFDEADBEEFllu /* identifies fields as unused */ typedef struct { /* supplementary data fields */ hwc_sample_t sample[MAX_PICS]; /* counter samples or start values */ } hwc_event_samples_t; #define HWCFUNCS_SAMPLE_RESET(sample) \ do { \ (sample)->smpl_pc =HWCFUNCS_INVALID_U64; \ (sample)->smpl_data_source =HWCFUNCS_INVALID_U64; \ (sample)->smpl_latency =HWCFUNCS_INVALID_U64; \ (sample)->smpl_mem_addr =HWCFUNCS_INVALID_U64; \ } while(0) #define HWCFUNCS_SAMPLE_IS_RESET(sample) \ ( \ (sample)->smpl_pc ==HWCFUNCS_INVALID_U64 && \ (sample)->smpl_data_source==HWCFUNCS_INVALID_U64 && \ (sample)->smpl_latency ==HWCFUNCS_INVALID_U64 && \ (sample)->smpl_mem_addr ==HWCFUNCS_INVALID_U64 \ ) /*---------------------------------------------------------------------------*/ /* macros */ #define HW_INTERVAL_MAX UINT64_MAX #define HW_INTERVAL_PRESET(x) (HW_INTERVAL_MAX - ((uint64_t)(x) - 1)) #define HW_INTERVAL_TYPE(x) ((uint64_t) (x) /* parsing */ #define HWCFUNCS_MAX_ATTRS 20 #define HWCFUNCS_PARSE_ATTR '~' #define HWCFUNCS_PARSE_EQUAL '=' #define HWCFUNCS_PARSE_BACKTRACK '+' #define HWCFUNCS_PARSE_BACKTRACK_OFF '-' #define HWCFUNCS_PARSE_REGNUM '/' #define HWCFUNCS_PARSE_VALUE ',' /* error codes */ #define HWCFUNCS_ERROR_GENERIC (-1) #define HWCFUNCS_ERROR_NOT_SUPPORTED (-2) #define HWCFUNCS_ERROR_ALREADY_CALLED (-3) #define HWCFUNCS_ERROR_HWCINIT (-4) #define HWCFUNCS_ERROR_HWCARGS (-5) #define HWCFUNCS_ERROR_MEMORY (-6) #define HWCFUNCS_ERROR_UNAVAIL (-7) #define HWCFUNCS_ERROR_ERRNO_ZERO (-8) #define HWCFUNCS_ERROR_UNEXPECTED (-99) /*---------------------------------------------------------------------------*/ /* prototypes */ typedef void (*hwcfuncs_abort_fn_t) (int errnum, const char *msg); extern void hwcfuncs_int_logerr(const char *format,...); /* Log an error to the internal error buffer. See hwcfuncs_errmsg_get(). Note: Not MT-safe; don't even enable logging in an MT environment. Recommend using this call only during init. Note: when a libcpc call fails, it may automatically call cpcN_capture_errmsg() to log the error message in the same internal buffer. Recommend using this call only for non-cpc failures. */ #define HWCFUNCS_SUPPORT_OVERFLOW_PROFILING 0x01llu #define HWCFUNCS_SUPPORT_PEBS_SAMPLING 0x02llu #define HWCFUNCS_SUPPORT_OVERFLOW_CTR_ID 0x04llu // OS identifies which counter overflowed /* get info about session Input: : if not NULL, returns value of CPC cpu version : if not NULL, returns name of CPU : if not NULL, returns maximum # of HWCs : if not NULL, returns documentation reference : if not NULL, returns bitmask (see above) of hwc support Return: none */ typedef void* (*hwcfuncs_tsd_get_fn_t) (void); typedef void (hwcf_hwc_cb_t) (uint_t cpcregno, const char *name); typedef void (hwcf_attr_cb_t) (const char *attr); extern void hwcfuncs_parse_ctr (const char *counter_def, int *pplus, char **pnameOnly, char **pattrs, char **pregstr, regno_t *pregno); /* Parse a counter definition string (value must already be stripped off). Input: : input whose format is [+|-][~attrs...][/] pointers to return values: Any can be NULL. Return: : 1 if [+] is found, -1 if [-] is found, 0 otherwise : strdup() : strdup([~attrs...]) if specified, NULL otherwise. : strdup(/) if specified, NULL otherwise. : if readable, REGNO_ANY if not specd, or -2 otherwise. */ typedef struct { char *ca_name; uint64_t ca_val; } hwcfuncs_attr_t; /* matches cpc_attr_t */ void * hwcfuncs_parse_attrs (const char *countername, hwcfuncs_attr_t attrs[], unsigned max_attrs, uint_t *pnum_attrs, char **errstring); /* Extract the attribute fields from . Input: : string whose format is [+][~attributes...][/][,...] : array of attributes to be returned : number of elements in : if not NULL, will return how many attrs were found. : pointer to a buffer for storing error info, or NULL. Return: upon success, a pointer to an allocated copy of , or NULL if there's a failure. (A copy is made in order to provide storage for the ca_name fields in the array.) The pointer should be freed when is no longer in use. will be filled in data from countername. will have the number of elements in . May be non-zero even if return value indicates an error. NULL if no error, otherwise, a malloc'd GTXT string. */ extern int hwcfuncs_bind_descriptor (const char *defstring); /* Bind counters to resources. Input: : string whose format is :%s:%s:0x%x:%d:%d,0x%x[:%s...repeat for each ctr] where the fields are: :::::: Return: 0 if successful HWCFUNCS_ERROR_HWCINIT if resources unavailable HWCFUNCS_ERROR_HWCARGS if counters were not specified correctly */ extern int hwcfuncs_bind_hwcentry (const Hwcentry *entries[], unsigned numctrs); /* Bind counters to resources. Input: : array of counters : number of items in Return: 0 if successful HWCFUNCS_ERROR_HWCINIT if resources unavailable HWCFUNCS_ERROR_HWCARGS if counters were not specified correctly */ extern int hwcfuncs_assign_regnos (Hwcentry *entries[], unsigned numctrs); /* Assign entries[]->reg_num values as needed by platform Note: modifies by supplying a regno to each counter Input: : array of counters : number of items in Output: : array of counters is modified Return: 0 if successful HWCFUNCS_ERROR_HWCINIT if resources unavailable HWCFUNCS_ERROR_HWCARGS if counters were not specified correctly */ extern int regno_is_valid (const Hwcentry *pctr, regno_t regno); /* return 1 if is in Hwcentry's list Input: : counter definition, reg_list[] should be initialized : register to check Return: 1 if is in Hwcentry's list, 0 otherwise */ extern Hwcentry **hwcfuncs_get_ctrs (unsigned *defcnt); /* Get descriptions of the currently bound counters. Input: : if not NULL, returns number of counter definitions. Return: table of counter definition pointers */ extern char *hwcfuncs_errmsg_get (char * buf, size_t bufsize, int enable_capture); /* Gets a recent HWC error message. To clear previous error messages and insure error message is enabled, call hwcfuncs_errmsg_get(NULL,0,1). Once enabled, one error is stored in an internal buffer. A call to this function will clear the buffer and allow a new message to be captured. Note: Not MT-safe - don't enable this feature in an MT environment. Input: : pointer to buffer or NULL. : size of : 0 - disable buffering, 1 - enable buffering. Return: error string or an empty string. */ #ifdef __cplusplus } #endif #endif /* ! __HWCFUNCS_H */