27#include "perfmon/pfmlib_perf_event.h"
29#define NATIVE_EVENT_CHUNK 1024
60 SUBDBG(
"Found allocated_name: %s, libpfm4_idx: %#x, papi_event_code: %#x\n",
73 SUBDBG(
"Found base_name: %s, mask_string: %s, libpfm4_idx: %#x, papi_event_code: %#x\n",
82 SUBDBG(
"EXIT: returned: %#x\n", event);
88 SUBDBG(
"ENTER: pinfo: %s %p, pinfo->is_present: %d, "
89 "pinfo->type: %#x, type: %#x\n",
90 pinfo->name, pinfo, pinfo->is_present, pinfo->type,
type);
91 if (!pinfo->is_present) {
132 int libpfm4_index,
int cidx,
135 SUBDBG(
"ENTER: name: %s, libpfm4_index: %#x, event_table: %p, "
136 "event_table->pmu_type: %d\n",
137 name, libpfm4_index, event_table, event_table->
pmu_type);
144 char *event_string=NULL;
148 char fullname[BUFSIZ];
151 pfm_perf_encode_arg_t perf_arg;
152 pfm_event_info_t einfo;
153 pfm_event_attr_info_t ainfo;
154 pfm_pmu_info_t pinfo;
158 SUBDBG(
"EXIT: no place to put native events\n");
171 if (event_num >= 0) {
172 nevt_idx = event_num;
182 SUBDBG(
"event_num: %d, nevt_idx: %d, ntv_evt: %p\n",
183 event_num, nevt_idx, ntv_evt);
186 memset(&perf_arg,0,
sizeof(pfm_perf_encode_arg_t));
191 perf_arg.attr=&ntv_evt->
attr;
192 perf_arg.fstr=&event_string;
199 ret = pfm_get_os_event_encoding(
name,
201 PFM_OS_PERF_EVENT_EXT,
205 if ((ret != PFM_SUCCESS) || (event_string == NULL)) {
206 SUBDBG(
"encode failed for event: %s, returned: %d\n",
221 ntv_evt->
attr.config = 0xFFFFFF;
232 free(*(perf_arg.fstr));
234 event_string = strdup(
name);
236 SUBDBG(
"event_string: %s\n", event_string);
240 event = strstr (event_string,
"::");
244 pmu_name = strdup(event_string);
247 pmu_name = malloc(2);
249 event = event_string;
251 masks = strstr (event,
":");
260 if (strlen(pmu_name) == 0) {
261 sprintf(fullname,
"%s", event);
263 sprintf(fullname,
"%s::%s", pmu_name, event);
266 SUBDBG(
"pmu_name: %s, event: %s, masks: %s, fullname: %s\n",
267 pmu_name, event, masks, fullname);
273 if (libpfm4_index == -1) {
275 if (libpfm4_index < 0) {
279 SUBDBG(
"EXIT: error from libpfm4 find event\n");
282 SUBDBG(
"libpfm4_index: %#x\n", libpfm4_index);
287 memset( &einfo, 0,
sizeof( pfm_event_info_t ));
288 einfo.size =
sizeof(pfm_event_info_t);
289 if ((ret = pfm_get_event_info(libpfm4_index,
290 PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
294 SUBDBG(
"EXIT: pfm_get_event_info failed with %d\n", ret);
300 memset(&pinfo,0,
sizeof(pfm_pmu_info_t));
301 pinfo.size =
sizeof(pfm_pmu_info_t);
302 pfm_get_pmu_info(einfo.pmu, &pinfo);
307 SUBDBG(
"EXIT: PMU not supported by this component: einfo.pmu: %d, PFM_PMU_TYPE_CORE: %d\n", einfo.pmu, PFM_PMU_TYPE_CORE);
314 ntv_evt->
pmu=pmu_name;
320 ntv_evt->
cpu=perf_arg.cpu;
322 SUBDBG(
"ntv_evt->mask_string: %p (%s)\n",
324 char *msk_ptr = strdup(masks);
330 if ((msk_ptr != NULL) && (strlen(msk_ptr) > 0)) {
334 SUBDBG(
"ptr: %p (%s)\n", ptr, ptr);
335 while (ptr != NULL) {
336 char *ptrm = strstr(ptr,
":");
343 char *wrk = strchr(ptr,
'=');
344 unsigned int msk_name_len;
346 msk_name_len = wrk - ptr;
347 SUBDBG(
"Found =, length=%d\n",msk_name_len);
349 msk_name_len = strlen (ptr);
350 SUBDBG(
"No =, length=%d\n",msk_name_len);
354 for (
i=0 ;
i<einfo.nattrs ;
i++) {
359 sizeof(pfm_event_attr_info_t));
360 ainfo.size =
sizeof(pfm_event_attr_info_t);
361 ret = pfm_get_event_attr_info(libpfm4_index,
362 i, PFM_OS_PERF_EVENT_EXT, &ainfo);
363 if (ret != PFM_SUCCESS) {
366 SUBDBG(
"EXIT: error libpfm4 find event: Attribute info not found, libpfm4_index: %#x, ret: %d\n", libpfm4_index,
_papi_libpfm4_error(ret));
373 if ((msk_name_len == strlen(ainfo.name)) &&
374 (strncmp(ptr, ainfo.name, msk_name_len) == 0)) {
376 SUBDBG(
"Found mask: libpfm4=%s -- matches %s -- i: %d, %d %zu\n",
377 ainfo.name, ptr,
i, msk_name_len, strlen(ainfo.name));
379 unsigned int mskleft =
sizeof(mask_desc) - strlen(mask_desc);
382 SUBDBG(
"EXIT: Attribute description discarded: %s\n", ainfo.desc);
386 if (strlen(mask_desc) > 0) {
387 strcat (mask_desc,
":");
391 if (mskleft < (strlen(ainfo.desc) + 1)) {
392 SUBDBG(
"EXIT: Attribute description truncated: %s\n", ainfo.desc);
395 strncat (mask_desc, ainfo.desc, mskleft-1);
396 mask_desc[mskleft-1] =
'\0';
405 SUBDBG(
"EXIT: error libpfm4 find event: Mask not found: %s.\n", ptr);
411 if ( (
sizeof(mask_desc) - strlen(mask_desc)) <= 1) {
421 if (msk_ptr != NULL) {
434 SUBDBG(
"Native Event: papi_event_code: %#x, libpfm4_idx: %#x, pmu: %s, base_name: %s, mask_string: %s, allocated_name: %s\n",
436 SUBDBG(
"event_table->native_events[%d]: %p, cpu: %d, attr.config: 0x%"PRIx64
", attr.config1: 0x%"PRIx64
", attr.config2: 0x%"PRIx64
", attr.type: 0x%"PRIx32
", attr.exclude_user: %d, attr.exclude_kernel: %d, attr.exclude_guest: %d\n",
438 ntv_evt->
attr.config1, ntv_evt->
attr.config2, ntv_evt->
attr.type,
439 ntv_evt->
attr.exclude_user, ntv_evt->
attr.exclude_kernel, ntv_evt->
attr.exclude_guest);
446 SUBDBG(
"Allocating more room for native events (%d %ld)\n",
466 SUBDBG(
"EXIT: attempt to get more space for "
467 "native events failed\n");
478 if (encode_failed != 0) {
479 SUBDBG(
"EXIT: encoding event failed\n");
483 SUBDBG(
"EXIT: new_event: %p\n", ntv_evt);
505 SUBDBG(
"ENTER: pmu_idx: %d, pmu_type: %d\n", pmu_idx, pmu_type);
508 pfm_pmu_info_t pinfo;
520 memset(&pinfo,0,
sizeof(pfm_pmu_info_t));
521 pinfo.size =
sizeof(pfm_pmu_info_t);
522 ret=pfm_get_pmu_info(pmu_idx, &pinfo);
524 if (ret==PFM_ERR_INVAL) {
536 pidx=pinfo.first_event;
537 SUBDBG(
"First event in pmu: %s is %#x\n", pinfo.name, pidx);
546 SUBDBG(
"EXIT: pidx: %#x\n", pidx);
555 SUBDBG(
"EXIT: PAPI_ENOEVNT\n");
586 SUBDBG(
"ENTER: name: %s, event_code: %p, *event_code: %#x, event_table: %p\n",
name, event_code, *event_code, event_table);
593 if (event_num >= 0) {
603 if (our_event==NULL) {
604 SUBDBG(
"EXIT: Allocating event: '%s' failed\n",
name);
609 SUBDBG(
"EXIT: Found code: %#x\n",*event_code);
633 char *ntv_name,
int len,
636 SUBDBG(
"ENTER: EventCode: %#x, ntv_name: %p, len: %d, event_table: %p\n", EventCode, ntv_name, len, event_table);
646 SUBDBG(
"EXIT: PAPI_ENOEVNT\n");
666 SUBDBG(
"EXIT: PAPI_ENOEVNT\n");
680 if (strlen (ename) >= (
unsigned)len) {
681 SUBDBG(
"EXIT: event name %s will not fit in buffer provided\n", ename);
684 strcpy (ntv_name, ename);
688 if ((mname != NULL) && (strlen(mname) > 0)) {
689 if ((strlen(ename) + 8 + strlen(mname)) >= (
unsigned)len) {
690 SUBDBG(
"EXIT: Not enough room for event and mask descriptions: need: %u, have: %u", (
unsigned)(strlen(ename) + 8 + strlen(mname)), (
unsigned)len);
693 strcat (ntv_name,
":");
694 strcat (ntv_name, mname);
697 SUBDBG(
"EXIT: event name: %s\n", ntv_name);
726 char *ntv_descr,
int len,
729 SUBDBG(
"ENTER: EventCode: %#x, ntv_descr: %p, len: %d: event_table: %p\n", EventCode, ntv_descr, len, event_table);
741 SUBDBG(
"EXIT: PAPI_ENOEVNT\n");
761 SUBDBG(
"EXIT: PAPI_ENOEVNT\n");
768 if (strlen (edesc) >= (
unsigned)len) {
769 SUBDBG(
"EXIT: event name %s will not fit in buffer provided\n", edesc);
772 strcpy (ntv_descr, edesc);
776 if ((mdesc != NULL) && (strlen(mdesc) > 0)) {
777 if ((strlen(edesc) + 8 + strlen(mdesc)) >= (
unsigned)len) {
778 SUBDBG(
"EXIT: Not enough room for event and mask descriptions: need: %u, have: %u", (
unsigned)(strlen(edesc) + 8 + strlen(mdesc)), (
unsigned)len);
781 strcat (ntv_descr,
", masks:");
782 strcat (ntv_descr, mdesc);
785 SUBDBG(
"EXIT: event description: %s\n", ntv_descr);
795 SUBDBG(
"ENTER: EventCode: %#x, info: %p, event_table: %p\n", EventCode, info, event_table);
801 SUBDBG(
"EXIT: _pe_libpfm4_ntv_code_to_name returned: %d\n", ret);
806 SUBDBG(
"EXIT: _pe_libpfm4_ntv_code_to_descr returned: %d\n", ret);
833 int modifier,
int cidx,
836 SUBDBG(
"ENTER: PapiEventCode: %p, *PapiEventCode: %#x, modifier: %d, event_table: %p\n", PapiEventCode, *PapiEventCode, modifier, event_table);
840 char event_string[BUFSIZ];
841 pfm_pmu_info_t pinfo;
842 pfm_event_info_t einfo;
850 SUBDBG(
"EXIT: Invalid component first event code: %d\n", code);
855 memset( &einfo, 0,
sizeof( pfm_event_info_t ));
856 einfo.size =
sizeof(pfm_event_info_t);
857 if ((ret = pfm_get_event_info(code, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
858 SUBDBG(
"EXIT: pfm_get_event_info returned: %d\n", ret);
863 memset( &pinfo, 0,
sizeof(pfm_pmu_info_t) );
864 pinfo.size =
sizeof(pfm_pmu_info_t);
865 ret=pfm_get_pmu_info(einfo.pmu, &pinfo);
866 if (ret!=PFM_SUCCESS) {
867 SUBDBG(
"EXIT: pfm_get_pmu_info returned: %d\n", ret);
872 sprintf (event_string,
"%s::%s", pinfo.name, einfo.name);
873 SUBDBG(
"code: %#x, pmu: %s, event: %s, event_string: %s\n", code, pinfo.name, einfo.name, event_string);
882 SUBDBG(
"EXIT: Allocating event: '%s' failed\n", event_string);
888 SUBDBG(
"EXIT: event code: %#x\n", *PapiEventCode);
894 SUBDBG(
"EXIT: *PapiEventCode: %#x\n", *PapiEventCode);
903 if ((code = pfm_get_event_next(*PapiEventCode)) < 0) {
906 memset( &einfo, 0,
sizeof( pfm_event_info_t ));
907 einfo.size =
sizeof(pfm_event_info_t);
908 if ((ret = pfm_get_event_info(*PapiEventCode, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
909 SUBDBG(
"EXIT: pfm_get_event_info returned: %d\n", ret);
912 SUBDBG(
"*PapiEventCode: %#x, event: %s\n", *PapiEventCode, einfo.name);
917 SUBDBG(
"pnum: %d\n", pnum);
920 SUBDBG(
"EXIT: No more PMUs to list, returning: %d\n", code);
927 memset( &einfo, 0,
sizeof( pfm_event_info_t ));
928 einfo.size =
sizeof(pfm_event_info_t);
929 if ((ret = pfm_get_event_info(code, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
930 SUBDBG(
"EXIT: pfm_get_event_info returned: %d\n", ret);
935 memset( &pinfo, 0,
sizeof(pfm_pmu_info_t) );
936 pinfo.size =
sizeof(pfm_pmu_info_t);
937 ret=pfm_get_pmu_info(einfo.pmu, &pinfo);
938 if (ret!=PFM_SUCCESS) {
939 SUBDBG(
"EXIT: pfm_get_pmu_info returned: %d\n", ret);
944 sprintf (event_string,
"%s::%s", pinfo.name, einfo.name);
945 SUBDBG(
"code: %#x, pmu: %s, event: %s, event_string: %s\n", code, pinfo.name, einfo.name, event_string);
954 SUBDBG(
"EXIT: Allocating event: '%s' failed\n", event_string);
960 SUBDBG(
"EXIT: event code: %#x\n", *PapiEventCode);
967 SUBDBG(
"EXIT: *PapiEventCode: %#x\n", *PapiEventCode);
973 SUBDBG(
"EXIT: do not support umask combos yet\n");
980 memset( &einfo, 0,
sizeof( pfm_event_info_t ));
981 einfo.size =
sizeof(pfm_event_info_t);
982 if ((ret = pfm_get_event_info(*PapiEventCode, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
983 SUBDBG(
"EXIT: pfm_get_event_info returned: %d\n", ret);
989 max_umasks = einfo.nattrs;
993 SUBDBG(
"EXIT: already processed all umasks: attr_idx: %d\n",
attr_idx);
1000 SUBDBG(
"EXIT: _papi_hwi_get_ntv_idx returned: %d\n", ntv_idx);
1004 if ((ename == NULL) || (strlen(ename) >=
sizeof(event_string))) {
1005 SUBDBG(
"EXIT: Event name will not fit into buffer\n");
1008 strcpy (event_string, ename);
1009 SUBDBG(
"event_string: %s\n", event_string);
1013 pfm_event_attr_info_t ainfo;
1014 memset (&ainfo, 0,
sizeof(pfm_event_attr_info_t));
1015 ainfo.size =
sizeof(pfm_event_attr_info_t);
1016 ret = pfm_get_event_attr_info(*PapiEventCode,
attr_idx, PFM_OS_PERF_EVENT_EXT, &ainfo);
1017 if (ret != PFM_SUCCESS) {
1021 SUBDBG(
"*PapiEventCode: %#x, attr_idx: %d, type: %d, name: %s, description: %s\n", *PapiEventCode,
attr_idx, ainfo.type, ainfo.name, ainfo.desc);
1023 if (strlen(event_string) + strlen(ainfo.name) + 35 >
sizeof(event_string)) {
1024 SUBDBG(
"EXIT: Event name and mask will not fit into buffer\n");
1028 strcat (event_string,
":");
1029 strcat (event_string, ainfo.name);
1030 switch (ainfo.type) {
1031 case PFM_ATTR_UMASK:
1033 case PFM_ATTR_MOD_BOOL:
1034 case PFM_ATTR_MOD_INTEGER:
1036 strcat(event_string,
"=0");
1039 SUBDBG(
"EXIT: Unsupported attribute type: %d", ainfo.type);
1050 SUBDBG(
"EXIT: Allocating event: '%s' failed\n", event_string);
1057 SUBDBG(
"EXIT: event code: %#x\n", *PapiEventCode);
1067 SUBDBG(
"EXIT: event code: %#x\n", *PapiEventCode);
1073 SUBDBG(
"EXIT: do not support enumerating groups in this component\n");
1079 SUBDBG(
"EXIT: Invalid modifier argument provided\n");
1097 SUBDBG(
"ENTER: event_table: %p\n", event_table);
1127 SUBDBG(
"EXIT: PAPI_OK\n");
1150 int detected_pmus=0, found_default=0;
1156 pfm_pmu_info_t pinfo;
1157 unsigned int strSize;
1177 memset(&(event_table->
default_pmu), 0,
sizeof(pfm_pmu_info_t));
1178 event_table->
default_pmu.size =
sizeof(pfm_pmu_info_t);
1181 SUBDBG(
"Prescan for aliases.\n");
1190 memset(&pinfo,0,
sizeof(pfm_pmu_info_t));
1191 pinfo.size =
sizeof(pfm_pmu_info_t);
1192 retval=pfm_get_pmu_info(
i, &pinfo);
1198 if (
retval==PFM_ERR_INVAL) {
1202 if ( (
retval==PFM_SUCCESS) && (pinfo.name != NULL) &&
1204 (strcmp(pinfo.name,
"amd64_fam17h_zen1") == 0) ) {
1210 SUBDBG(
"Detected pmus:\n");
1213 memset(&pinfo,0,
sizeof(pfm_pmu_info_t));
1214 pinfo.size =
sizeof(pfm_pmu_info_t);
1215 retval=pfm_get_pmu_info(
i, &pinfo);
1221 if (
retval==PFM_ERR_INVAL) {
1225 if ((
retval==PFM_SUCCESS) && (pinfo.name != NULL) &&
1235 pinfo.name,pinfo.desc,pinfo.type);
1238 ncnt+=pinfo.nevents;
1248 if ( (pinfo.type==PFM_PMU_TYPE_CORE) &&
1249 strcmp(pinfo.name,
"ix86arch")) {
1251 &pinfo,
sizeof(pfm_pmu_info_t));
1256 if ( (pinfo.type==PFM_PMU_TYPE_CORE) &&
1272 SUBDBG(
"%d native events detected on %d pmus\n",ncnt,detected_pmus);
1274 if (detected_pmus==0) {
1275 SUBDBG(
"Could not find any PMUs\n");
1279 if (!found_default) {
1283 if (found_default>1) {
1287 component->cmp_info.num_native_events = ncnt;
1295 if ((
cidx==0) && (found_default)) {
1322 int detected_pmus=0;
1327 pfm_pmu_info_t pinfo;
1349 SUBDBG(
"Detected pmus:\n");
1352 memset(&pinfo,0,
sizeof(pfm_pmu_info_t));
1353 pinfo.size =
sizeof(pfm_pmu_info_t);
1354 retval=pfm_get_pmu_info(
i, &pinfo);
1360 if (
retval==PFM_ERR_INVAL) {
1364 if ((
retval==PFM_SUCCESS) && (pinfo.name != NULL) &&
1367 SUBDBG(
"\t%d %s %s %d\n",
i,pinfo.name,pinfo.desc,pinfo.type);
1370 ncnt+=pinfo.nevents;
1376 pinfo.num_fixed_cntrs;
1380 SUBDBG(
"%d native events detected on %d pmus\n",ncnt,detected_pmus);
convert libpfm error codes to PAPI error codes
Initialize the libpfm4 code.
Take an event code and convert it to a description.
Take an event code and convert it to a name.
Walk through all events in a pre-defined order.
Take an event name and convert it to an event code.
Shutdown any initialization done by the libpfm4 code.
Initialize the libpfm4 code.
Allocates a native event.
looks up an event, returns it if it exists
return the first available event that's on an active PMU
#define PAPI_NTV_ENUM_UMASK_COMBOS
#define PAPI_VENDOR_ARM_ARM
#define PAPI_NTV_ENUM_UMASKS
#define PAPI_HUGE_STR_LEN
Return codes and api definitions.
#define SUBDBG(format, args...)
int _papi_hwi_native_to_eventcode(int cidx, int event_code, int ntv_idx, const char *event_name)
unsigned int _papi_hwi_get_papi_event_code()
void _papi_hwi_set_papi_event_string(const char *event_string)
void _papi_hwi_set_papi_event_code(unsigned int event_code, int update_flag)
int _papi_hwi_get_ntv_idx(unsigned int papi_evt_code)
int _papi_load_preset_table(char *pmu_str, int pmu_type, int cidx)
#define NATIVE_EVENT_CHUNK
static int amd64_fam17h_zen1_present
int _pe_libpfm4_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info, struct native_event_table_t *event_table)
static int pmu_is_present_and_right_type(pfm_pmu_info_t *pinfo, int type)
papi_mdi_t _papi_hwi_system_info
pfm_err_t pfm_find_event(const char *str, unsigned int *idx)
char * pmu_names[PAPI_PMU_MAX]
char symbol[PAPI_HUGE_STR_LEN]
char long_descr[PAPI_HUGE_STR_LEN]
char model_string[PAPI_MAX_STR_LEN]
pfm_pmu_info_t default_pmu
struct native_event_t * native_events
int allocated_native_events
PAPI_component_info_t cmp_info
inline_static int _papi_hwi_lock(int lck)
inline_static int _papi_hwi_unlock(int lck)