PAPI 7.1.0.0
Loading...
Searching...
No Matches
papi_libpfm3_events.c
Go to the documentation of this file.
1/*
2* File: papi_libpfm3_events.c
3* Author: Dan Terpstra: blantantly extracted from Phil's perfmon.c
4* mucci@cs.utk.edu
5*
6*/
7
8#include <ctype.h>
9#include <string.h>
10#include <errno.h>
11
12#include "papi.h"
13#include "papi_internal.h"
14#include "papi_vector.h"
15#include "papi_memory.h"
16
17#include "perfmon/perfmon.h"
18#include "perfmon/pfmlib.h"
19
20#include "papi_libpfm_events.h"
21
22/* Native events consist of a flag field, an event field, and a unit mask field.
23 * These variables define the characteristics of the event and unit mask fields.
24 */
25unsigned int PAPI_NATIVE_EVENT_AND_MASK = 0x000003ff;
26unsigned int PAPI_NATIVE_EVENT_SHIFT = 0;
27unsigned int PAPI_NATIVE_UMASK_AND_MASK = 0x03fffc00;
28unsigned int PAPI_NATIVE_UMASK_MAX = 16;
29unsigned int PAPI_NATIVE_UMASK_SHIFT = 10;
30
31/* Globals */
33
34
35/* NOTE: PAPI stores umask info in a variable sized (16 bit?) bitfield.
36 Perfmon2 stores umask info in a large (48 element?) array of values.
37 Native event encodings for perfmon2 contain array indices
38 encoded as bits in this bitfield. These indices must be converted
39 into a umask value before programming the counters. For Perfmon,
40 this is done by converting back to an array of values; for
41 perfctr, it must be done by looking up the values.
42*/
43
44/* This routine is used to step through all possible combinations of umask
45 values. It assumes that mask contains a valid combination of array indices
46 for this event. */
47static inline int
48encode_native_event_raw( unsigned int event, unsigned int mask )
49{
50 unsigned int tmp = event << PAPI_NATIVE_EVENT_SHIFT;
51 SUBDBG( "Old native index was %#08x with %#08x mask\n", tmp, mask );
52 tmp = tmp | ( mask << PAPI_NATIVE_UMASK_SHIFT );
53 SUBDBG( "New encoding is %#08x\n", tmp | PAPI_NATIVE_MASK );
54 return ( int ) ( tmp | PAPI_NATIVE_MASK );
55}
56
57/* This routine converts array indices contained in the mask_values array
58 into bits in the umask field that is OR'd into the native event code.
59 These bits are NOT the mask values themselves, but indices into an array
60 of mask values contained in the native event table. */
61static inline int
62encode_native_event( unsigned int event, unsigned int num_mask,
63 unsigned int *mask_values )
64{
65 unsigned int i;
66 unsigned int tmp = event << PAPI_NATIVE_EVENT_SHIFT;
67 SUBDBG( "Native base event is %#08x with %d masks\n", tmp, num_mask );
68 for ( i = 0; i < num_mask; i++ ) {
69 SUBDBG( "Mask index is %#08x\n", mask_values[i] );
70 tmp = tmp | ( ( 1 << mask_values[i] ) << PAPI_NATIVE_UMASK_SHIFT );
71 }
72 SUBDBG( "Full native encoding is 0x%08x\n", tmp | PAPI_NATIVE_MASK );
73 return ( int ) ( tmp | PAPI_NATIVE_MASK );
74}
75
76
77/* Break a PAPI native event code into its composite event code and pfm mask bits */
78int
79_pfm_decode_native_event( unsigned int EventCode, unsigned int *event,
80 unsigned int *umask )
81{
82 unsigned int tevent, major, minor;
83
84 tevent = EventCode & PAPI_NATIVE_AND_MASK;
86 if ( ( int ) major >= num_native_events )
87 return PAPI_ENOEVNT;
88
90 *event = major;
91 *umask = minor;
92 SUBDBG( "EventCode %#08x is event %d, umask %#x\n", EventCode, major,
93 minor );
94 return PAPI_OK;
95}
96
97/* convert a collection of pfm mask bits into an array of pfm mask indices */
98int
99prepare_umask( unsigned int foo, unsigned int *values )
100{
101 unsigned int tmp = foo, i;
102 int j = 0;
103
104 SUBDBG( "umask %#x\n", tmp );
105 while ( ( i = ( unsigned int ) ffs( ( int ) tmp ) ) ) {
106 tmp = tmp ^ ( 1 << ( i - 1 ) );
107 values[j] = i - 1;
108 SUBDBG( "umask %d is %d\n", j, values[j] );
109 j++;
110 }
111 return ( j );
112}
113
114/* convert the mask values in a pfm event structure into a PAPI unit mask */
115static inline unsigned int
117{
118 int ret;
119 unsigned int i, code, tmp = 0;
120
121 for ( i = 0; i < gete->num_masks; i++ ) {
122 if ( ( ret =
124 &code ) ) == PFMLIB_SUCCESS ) {
125 SUBDBG( "Mask value is %#08x\n", code );
126 tmp |= code;
127 } else {
128 PAPIERROR( "pfm_get_event_mask_code(%#x,%d,%p): %s", gete->event,
129 i, &code, pfm_strerror( ret ) );
130 }
131 }
132 return ( tmp );
133}
134
135/* convert an event code and pfm unit mask into a PAPI unit mask */
136unsigned int
137_pfm_convert_umask( unsigned int event, unsigned int umask )
138{
139 pfmlib_event_t gete;
140 memset( &gete, 0, sizeof ( gete ) );
141 gete.event = event;
142 gete.num_masks = ( unsigned int ) prepare_umask( umask, gete.unit_masks );
143 return ( convert_pfm_masks( &gete ) );
144}
145
146/* convert libpfm error codes to PAPI error codes for
147 more informative error reporting */
148int
149_papi_libpfm_error( int pfm_error )
150{
151 switch ( pfm_error ) {
152 case PFMLIB_SUCCESS: return PAPI_OK; /* success */
153 case PFMLIB_ERR_NOTSUPP: return PAPI_ENOSUPP; /* function not supported */
154 case PFMLIB_ERR_INVAL: return PAPI_EINVAL; /* invalid parameters */
155 case PFMLIB_ERR_NOINIT: return PAPI_ENOINIT; /* library was not initialized */
156 case PFMLIB_ERR_NOTFOUND: return PAPI_ENOEVNT; /* event not found */
157 case PFMLIB_ERR_NOASSIGN: return PAPI_ECNFLCT; /* cannot assign events to counters */
158 case PFMLIB_ERR_FULL: return PAPI_EBUF; /* buffer is full or too small */
159 case PFMLIB_ERR_EVTMANY: return PAPI_EMISC; /* event used more than once */
160 case PFMLIB_ERR_MAGIC: return PAPI_EBUG; /* invalid library magic number */
161 case PFMLIB_ERR_FEATCOMB: return PAPI_ECOMBO; /* invalid combination of features */
162 case PFMLIB_ERR_EVTSET: return PAPI_ENOEVST; /* incompatible event sets */
163 case PFMLIB_ERR_EVTINCOMP: return PAPI_ECNFLCT; /* incompatible event combination */
164 case PFMLIB_ERR_TOOMANY: return PAPI_ECOUNT; /* too many events or unit masks */
165 case PFMLIB_ERR_BADHOST: return PAPI_ESYS; /* not supported by host CPU */
166 case PFMLIB_ERR_UMASK: return PAPI_EATTR; /* invalid or missing unit mask */
167 case PFMLIB_ERR_NOMEM: return PAPI_ENOMEM; /* out of memory */
168
169 /* Itanium only */
170 case PFMLIB_ERR_IRRTOOBIG: /* code range too big */
171 case PFMLIB_ERR_IRREMPTY: /* empty code range */
172 case PFMLIB_ERR_IRRINVAL: /* invalid code range */
173 case PFMLIB_ERR_IRRTOOMANY: /* too many code ranges */
174 case PFMLIB_ERR_DRRINVAL: /* invalid data range */
175 case PFMLIB_ERR_DRRTOOMANY: /* too many data ranges */
176 case PFMLIB_ERR_IRRALIGN: /* bad alignment for code range */
177 case PFMLIB_ERR_IRRFLAGS: /* code range missing flags */
178 default:
179 return PAPI_EINVAL;
180 }
181}
182
183int
184_papi_libpfm_ntv_name_to_code( const char *name, unsigned int *event_code )
185{
186 pfmlib_event_t event;
187 unsigned int i;
188 int ret;
189
190 SUBDBG( "pfm_find_full_event(%s,%p)\n", name, &event );
191 ret = pfm_find_full_event( name, &event );
192 if ( ret == PFMLIB_SUCCESS ) {
193 SUBDBG( "Full event name found\n" );
194 /* we can only capture PAPI_NATIVE_UMASK_MAX or fewer masks */
195 if ( event.num_masks > PAPI_NATIVE_UMASK_MAX ) {
196 SUBDBG( "num_masks (%d) > max masks (%d)\n", event.num_masks,
198 return PAPI_ENOEVNT;
199 } else {
200 /* no mask index can exceed PAPI_NATIVE_UMASK_MAX */
201 for ( i = 0; i < event.num_masks; i++ ) {
202 if ( event.unit_masks[i] > PAPI_NATIVE_UMASK_MAX ) {
203 SUBDBG( "mask index (%d) > max masks (%d)\n",
205 return PAPI_ENOEVNT;
206 }
207 }
208 *event_code =
209 encode_native_event( event.event, event.num_masks,
210 event.unit_masks );
211 return PAPI_OK;
212 }
213 } else if ( ret == PFMLIB_ERR_UMASK ) {
214 SUBDBG( "UMASK error, looking for base event only\n" );
215 ret = pfm_find_event( name, &event.event );
216 if ( ret == PFMLIB_SUCCESS ) {
217 *event_code = encode_native_event( event.event, 0, 0 );
218 return PAPI_EATTR;
219 }
220 }
221 return PAPI_ENOEVNT;
222}
223
224int
225_papi_libpfm_ntv_code_to_name( unsigned int EventCode, char *ntv_name, int len )
226{
227 int ret;
228 unsigned int event, umask;
229 pfmlib_event_t gete;
230
231 memset( &gete, 0, sizeof ( gete ) );
232
233 if ( _pfm_decode_native_event( EventCode, &event, &umask ) != PAPI_OK )
234 return ( PAPI_ENOEVNT );
235
236 gete.event = event;
237 gete.num_masks = ( unsigned int ) prepare_umask( umask, gete.unit_masks );
238 if ( gete.num_masks == 0 )
239 ret = pfm_get_event_name( gete.event, ntv_name, ( size_t ) len );
240 else
241 ret = pfm_get_full_event_name( &gete, ntv_name, ( size_t ) len );
242 if ( ret != PFMLIB_SUCCESS ) {
244 pfm_get_event_name( gete.event, tmp, sizeof ( tmp ) );
245 /* Skip error message if event is not supported by host cpu;
246 * we don't need to give this info away for papi_native_avail util */
247 if ( ret != PFMLIB_ERR_BADHOST )
249 ( "pfm_get_full_event_name(%p(event %d,%s,%d masks),%p,%d): %d -- %s",
250 &gete, gete.event, tmp, gete.num_masks, ntv_name, len, ret,
251 pfm_strerror( ret ) );
252 if ( ret == PFMLIB_ERR_FULL ) {
253 return PAPI_EBUF;
254 }
255
256 return PAPI_EMISC;
257 }
258 return PAPI_OK;
259}
260
261int
262_papi_libpfm_ntv_code_to_descr( unsigned int EventCode, char *ntv_descr, int len )
263{
264 unsigned int event, umask;
265 char *eventd, **maskd, *tmp;
266 int i, ret;
267 pfmlib_event_t gete;
268 size_t total_len = 0;
269
270 memset( &gete, 0, sizeof ( gete ) );
271
272 if ( _pfm_decode_native_event( EventCode, &event, &umask ) != PAPI_OK )
273 return ( PAPI_ENOEVNT );
274
275 ret = pfm_get_event_description( event, &eventd );
276 if ( ret != PFMLIB_SUCCESS ) {
277 PAPIERROR( "pfm_get_event_description(%d,%p): %s",
278 event, &eventd, pfm_strerror( ret ) );
279 return ( PAPI_ENOEVNT );
280 }
281
282 if ( ( gete.num_masks =
283 ( unsigned int ) prepare_umask( umask, gete.unit_masks ) ) ) {
284 maskd = ( char ** ) malloc( gete.num_masks * sizeof ( char * ) );
285 if ( maskd == NULL ) {
286 free( eventd );
287 return ( PAPI_ENOMEM );
288 }
289 for ( i = 0; i < ( int ) gete.num_masks; i++ ) {
290 ret =
292 &maskd[i] );
293 if ( ret != PFMLIB_SUCCESS ) {
294 PAPIERROR( "pfm_get_event_mask_description(%d,%d,%p): %s",
295 event, umask, &maskd, pfm_strerror( ret ) );
296 free( eventd );
297 for ( ; i >= 0; i-- )
298 free( maskd[i] );
299 free( maskd );
300 return ( PAPI_EINVAL );
301 }
302 total_len += strlen( maskd[i] );
303 }
304 tmp =
305 ( char * ) malloc( strlen( eventd ) + strlen( ", masks:" ) +
306 total_len + gete.num_masks + 1 );
307 if ( tmp == NULL ) {
308 for ( i = ( int ) gete.num_masks - 1; i >= 0; i-- )
309 free( maskd[i] );
310 free( maskd );
311 free( eventd );
312 }
313 tmp[0] = '\0';
314 strcat( tmp, eventd );
315 strcat( tmp, ", masks:" );
316 for ( i = 0; i < ( int ) gete.num_masks; i++ ) {
317 if ( i != 0 )
318 strcat( tmp, "," );
319 strcat( tmp, maskd[i] );
320 free( maskd[i] );
321 }
322 free( maskd );
323 } else {
324 tmp = ( char * ) malloc( strlen( eventd ) + 1 );
325 if ( tmp == NULL ) {
326 free( eventd );
327 return ( PAPI_ENOMEM );
328 }
329 tmp[0] = '\0';
330 strcat( tmp, eventd );
331 free( eventd );
332 }
333 strncpy( ntv_descr, tmp, ( size_t ) len );
334 if ( ( int ) strlen( tmp ) > len - 1 )
335 ret = PAPI_EBUF;
336 else
337 ret = PAPI_OK;
338 free( tmp );
339 return ( ret );
340}
341
342
343int
345{
346
347 SUBDBG("ENTER %#x\n",EventCode);
348
350 sizeof(info->symbol));
351
353 sizeof(info->long_descr));
354
355 return PAPI_OK;
356}
357
358
359int
360_papi_libpfm_ntv_enum_events( unsigned int *EventCode, int modifier )
361{
362 unsigned int event, umask, num_masks;
363 int ret;
364
365 if ( modifier == PAPI_ENUM_FIRST ) {
366 *EventCode = PAPI_NATIVE_MASK; /* assumes first native event is always 0x4000000 */
367 return ( PAPI_OK );
368 }
369
370 if ( _pfm_decode_native_event( *EventCode, &event, &umask ) != PAPI_OK )
371 return ( PAPI_ENOEVNT );
372
373 ret = pfm_get_num_event_masks( event, &num_masks );
374 if ( ret != PFMLIB_SUCCESS ) {
375 PAPIERROR( "pfm_get_num_event_masks(%d,%p): %s", event, &num_masks,
376 pfm_strerror( ret ) );
377 return ( PAPI_ENOEVNT );
378 }
379 if ( num_masks > PAPI_NATIVE_UMASK_MAX )
380 num_masks = PAPI_NATIVE_UMASK_MAX;
381 SUBDBG( "This is umask %d of %d\n", umask, num_masks );
382
383 if ( modifier == PAPI_ENUM_EVENTS ) {
384 if ( event < ( unsigned int ) num_native_events - 1 ) {
385 *EventCode =
386 ( unsigned int ) encode_native_event_raw( event + 1, 0 );
387 return ( PAPI_OK );
388 }
389 return ( PAPI_ENOEVNT );
390 } else if ( modifier == PAPI_NTV_ENUM_UMASK_COMBOS ) {
391 if ( umask + 1 < ( unsigned int ) ( 1 << num_masks ) ) {
392 *EventCode =
393 ( unsigned int ) encode_native_event_raw( event, umask + 1 );
394 return ( PAPI_OK );
395 }
396 return ( PAPI_ENOEVNT );
397 } else if ( modifier == PAPI_NTV_ENUM_UMASKS ) {
398 int thisbit = ffs( ( int ) umask );
399
400 SUBDBG( "First bit is %d in %08x\b\n", thisbit - 1, umask );
401 thisbit = 1 << thisbit;
402
403 if ( thisbit & ( ( 1 << num_masks ) - 1 ) ) {
404 *EventCode =
405 ( unsigned int ) encode_native_event_raw( event,
406 ( unsigned int )
407 thisbit );
408 return ( PAPI_OK );
409 }
410 return ( PAPI_ENOEVNT );
411 } else
412 return ( PAPI_EINVAL );
413}
414
415int
416_papi_libpfm_ntv_code_to_bits( unsigned int EventCode, hwd_register_t * bits )
417{
418 unsigned int event, umask;
419 pfmlib_event_t gete;
420
421 /* For PFM & Perfmon, native info is just an index into PFM event table. */
422 if ( _pfm_decode_native_event( EventCode, &event, &umask ) != PAPI_OK )
423 return PAPI_ENOEVNT;
424
425 memset( &gete, 0x0, sizeof ( pfmlib_event_t ) );
426
427 gete.event = event;
428 gete.num_masks = prepare_umask( umask, gete.unit_masks );
429
430 memcpy( bits, &gete, sizeof ( pfmlib_event_t ) );
431
432 return PAPI_OK;
433
434}
435
436
437/* used by linux-timer.c for ia64 */
439
440
441int
443
444 int retval;
445 unsigned int ncnt;
446 unsigned int version;
447 char pmu_name[PAPI_MIN_STR_LEN];
448
449
450 /* The following checks the version of the PFM library
451 against the version PAPI linked to... */
452 SUBDBG( "pfm_initialize()\n" );
453 if ( ( retval = pfm_initialize( ) ) != PFMLIB_SUCCESS ) {
454 PAPIERROR( "pfm_initialize(): %s", pfm_strerror( retval ) );
455 return PAPI_ESYS;
456 }
457
458 /* Get the libpfm3 version */
459 SUBDBG( "pfm_get_version(%p)\n", &version );
461 PAPIERROR( "pfm_get_version(%p): %s", version, pfm_strerror( retval ) );
462 return PAPI_ESYS;
463 }
464
465 /* Set the version */
466 sprintf( my_vector->cmp_info.support_version, "%d.%d",
468
469 /* Complain if the compiled-against version doesn't match current version */
471 PAPIERROR( "Version mismatch of libpfm: compiled %#x vs. installed %#x\n",
474 return PAPI_ESYS;
475 }
476
477 /* Always initialize globals dynamically to handle forks properly. */
478
480
481 /* Opened once for all threads. */
482 SUBDBG( "pfm_get_pmu_type(%p)\n", &_perfmon2_pfm_pmu_type );
484 PAPIERROR( "pfm_get_pmu_type(%p): %s", _perfmon2_pfm_pmu_type,
485 pfm_strerror( retval ) );
486 return PAPI_ESYS;
487 }
488
489 pmu_name[0] = '\0';
490 if ( pfm_get_pmu_name( pmu_name, PAPI_MIN_STR_LEN ) != PFMLIB_SUCCESS ) {
491 PAPIERROR( "pfm_get_pmu_name(%p,%d): %s", pmu_name, PAPI_MIN_STR_LEN,
492 pfm_strerror( retval ) );
493 return PAPI_ESYS;
494 }
495 SUBDBG( "PMU is a %s, type %d\n", pmu_name, _perfmon2_pfm_pmu_type );
496
497 /* Setup presets */
499 if ( retval )
500 return retval;
501
502 /* Fill in cmp_info */
503
504 SUBDBG( "pfm_get_num_events(%p)\n", &ncnt );
505 if ( ( retval = pfm_get_num_events( &ncnt ) ) != PFMLIB_SUCCESS ) {
506 PAPIERROR( "pfm_get_num_events(%p): %s\n", &ncnt,
507 pfm_strerror( retval ) );
508 return PAPI_ESYS;
509 }
510 SUBDBG( "pfm_get_num_events: %d\n", ncnt );
511 my_vector->cmp_info.num_native_events = ncnt;
512 num_native_events = ncnt;
513
514 pfm_get_num_counters( ( unsigned int * ) &my_vector->cmp_info.num_cntrs );
515 SUBDBG( "pfm_get_num_counters: %d\n", my_vector->cmp_info.num_cntrs );
516
517
519 /* Pentium4 */
521 PAPI_NATIVE_EVENT_AND_MASK = 0x000000ff;
522 PAPI_NATIVE_UMASK_AND_MASK = 0x0fffff00;
524 /* Itanium2 */
525 } else if ( _papi_hwi_system_info.hw_info.cpuid_family == 31 ||
527 PAPI_NATIVE_EVENT_AND_MASK = 0x00000fff;
528 PAPI_NATIVE_UMASK_AND_MASK = 0x0ffff000;
530 }
531 }
532
533
534 return PAPI_OK;
535}
536
537long long generate_p4_event(long long escr,
538 long long cccr,
539 long long escr_addr) {
540
541/*
542 * RAW events specification
543 *
544 * Bits Meaning
545 * ----- -------
546 * 0-6 Metric value from enum P4_PEBS_METRIC (if needed)
547 * 7-11 Reserved, set to 0
548 * 12-31 Bits 12-31 of CCCR register (Intel SDM Vol 3)
549 * 32-56 Bits 0-24 of ESCR register (Intel SDM Vol 3)
550 * 57-62 Event key from enum P4_EVENTS
551 * 63 Reserved, set to 0
552 */
553
554 enum P4_EVENTS {
555 P4_EVENT_TC_DELIVER_MODE,
556 P4_EVENT_BPU_FETCH_REQUEST,
557 P4_EVENT_ITLB_REFERENCE,
558 P4_EVENT_MEMORY_CANCEL,
559 P4_EVENT_MEMORY_COMPLETE,
560 P4_EVENT_LOAD_PORT_REPLAY,
561 P4_EVENT_STORE_PORT_REPLAY,
562 P4_EVENT_MOB_LOAD_REPLAY,
563 P4_EVENT_PAGE_WALK_TYPE,
564 P4_EVENT_BSQ_CACHE_REFERENCE,
565 P4_EVENT_IOQ_ALLOCATION,
566 P4_EVENT_IOQ_ACTIVE_ENTRIES,
567 P4_EVENT_FSB_DATA_ACTIVITY,
568 P4_EVENT_BSQ_ALLOCATION,
569 P4_EVENT_BSQ_ACTIVE_ENTRIES,
570 P4_EVENT_SSE_INPUT_ASSIST,
571 P4_EVENT_PACKED_SP_UOP,
572 P4_EVENT_PACKED_DP_UOP,
573 P4_EVENT_SCALAR_SP_UOP,
574 P4_EVENT_SCALAR_DP_UOP,
575 P4_EVENT_64BIT_MMX_UOP,
576 P4_EVENT_128BIT_MMX_UOP,
577 P4_EVENT_X87_FP_UOP,
578 P4_EVENT_TC_MISC,
579 P4_EVENT_GLOBAL_POWER_EVENTS,
580 P4_EVENT_TC_MS_XFER,
581 P4_EVENT_UOP_QUEUE_WRITES,
582 P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE,
583 P4_EVENT_RETIRED_BRANCH_TYPE,
584 P4_EVENT_RESOURCE_STALL,
585 P4_EVENT_WC_BUFFER,
586 P4_EVENT_B2B_CYCLES,
587 P4_EVENT_BNR,
588 P4_EVENT_SNOOP,
589 P4_EVENT_RESPONSE,
590 P4_EVENT_FRONT_END_EVENT,
591 P4_EVENT_EXECUTION_EVENT,
592 P4_EVENT_REPLAY_EVENT,
593 P4_EVENT_INSTR_RETIRED,
594 P4_EVENT_UOPS_RETIRED,
595 P4_EVENT_UOP_TYPE,
596 P4_EVENT_BRANCH_RETIRED,
597 P4_EVENT_MISPRED_BRANCH_RETIRED,
598 P4_EVENT_X87_ASSIST,
599 P4_EVENT_MACHINE_CLEAR,
600 P4_EVENT_INSTR_COMPLETED,
601 };
602
603
604 int eventsel=(escr>>25)&0x3f;
605 int cccrsel=(cccr>>13)&0x7;
606 int event_key=-1;
607 long long pe_event;
608
609 switch(eventsel) {
610 case 0x1: if (cccrsel==1) {
611 if (escr_addr>0x3c8) {
612 // tc_escr0,1 0x3c4
613 event_key=P4_EVENT_TC_DELIVER_MODE;
614 }
615 else {
616 // alf_escr0, 0x3ca
617 event_key=P4_EVENT_RESOURCE_STALL;
618 }
619 }
620 if (cccrsel==4) {
621 if (escr_addr<0x3af) {
622 // pmh_escr0,1 0x3ac
623 event_key=P4_EVENT_PAGE_WALK_TYPE;
624 }
625 else {
626 // cru_escr0, 3b8 cccr=04
627 event_key=P4_EVENT_UOPS_RETIRED;
628 }
629 }
630 break;
631 case 0x2: if (cccrsel==5) {
632 if (escr_addr<0x3a8) {
633 // MSR_DAC_ESCR0 / MSR_DAC_ESCR1
634 event_key=P4_EVENT_MEMORY_CANCEL;
635 } else {
636 //MSR_CRU_ESCR2, MSR_CRU_ESCR3
637 event_key=P4_EVENT_MACHINE_CLEAR;
638 }
639 } else if (cccrsel==1) {
640 event_key=P4_EVENT_64BIT_MMX_UOP;
641 } else if (cccrsel==4) {
642 event_key=P4_EVENT_INSTR_RETIRED;
643 } else if (cccrsel==2) {
644 event_key=P4_EVENT_UOP_TYPE;
645 }
646 break;
647 case 0x3: if (cccrsel==0) {
648 event_key=P4_EVENT_BPU_FETCH_REQUEST;
649 }
650 if (cccrsel==2) {
651 event_key=P4_EVENT_MOB_LOAD_REPLAY;
652 }
653 if (cccrsel==6) {
654 event_key=P4_EVENT_IOQ_ALLOCATION;
655 }
656 if (cccrsel==4) {
657 event_key=P4_EVENT_MISPRED_BRANCH_RETIRED;
658 }
659 if (cccrsel==5) {
660 event_key=P4_EVENT_X87_ASSIST;
661 }
662 break;
663 case 0x4: if (cccrsel==2) {
664 if (escr_addr<0x3b0) {
665 // saat, 0x3ae
666 event_key=P4_EVENT_LOAD_PORT_REPLAY;
667 }
668 else {
669 // tbpu 0x3c2
670 event_key=P4_EVENT_RETIRED_BRANCH_TYPE;
671 }
672 }
673 if (cccrsel==1) {
674 event_key=P4_EVENT_X87_FP_UOP;
675 }
676 if (cccrsel==3) {
677 event_key=P4_EVENT_RESPONSE;
678 }
679 break;
680 case 0x5: if (cccrsel==2) {
681 if (escr_addr<0x3b0) {
682 // saat, 0x3ae
683 event_key=P4_EVENT_STORE_PORT_REPLAY;
684 }
685 else {
686 // tbpu, 0x3c2
687 event_key=P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE;
688 }
689 }
690 if (cccrsel==7) {
691 event_key=P4_EVENT_BSQ_ALLOCATION;
692 }
693 if (cccrsel==0) {
694 event_key=P4_EVENT_TC_MS_XFER;
695 }
696 if (cccrsel==5) {
697 event_key=P4_EVENT_WC_BUFFER;
698 }
699 break;
700 case 0x6: if (cccrsel==7) {
701 event_key=P4_EVENT_BSQ_ACTIVE_ENTRIES;
702 }
703 if (cccrsel==1) {
704 event_key=P4_EVENT_TC_MISC;
705 }
706 if (cccrsel==3) {
707 event_key=P4_EVENT_SNOOP;
708 }
709 if (cccrsel==5) {
710 event_key=P4_EVENT_BRANCH_RETIRED;
711 }
712 break;
713 case 0x7: event_key=P4_EVENT_INSTR_COMPLETED; break;
714 case 0x8: if (cccrsel==2) {
715 event_key=P4_EVENT_MEMORY_COMPLETE;
716 }
717 if (cccrsel==1) {
718 event_key=P4_EVENT_PACKED_SP_UOP;
719 }
720 if (cccrsel==3) {
721 event_key=P4_EVENT_BNR;
722 }
723 if (cccrsel==5) {
724 event_key=P4_EVENT_FRONT_END_EVENT;
725 }
726 break;
727 case 0x9: if (cccrsel==0) {
728 event_key=P4_EVENT_UOP_QUEUE_WRITES;
729 }
730 if (cccrsel==5) {
731 event_key=P4_EVENT_REPLAY_EVENT;
732 }
733 break;
734 case 0xa: event_key=P4_EVENT_SCALAR_SP_UOP; break;
735 case 0xc: if (cccrsel==7) {
736 event_key=P4_EVENT_BSQ_CACHE_REFERENCE;
737 }
738 if (cccrsel==1) {
739 event_key=P4_EVENT_PACKED_DP_UOP;
740 }
741 if (cccrsel==5) {
742 event_key=P4_EVENT_EXECUTION_EVENT;
743 }
744 break;
745 case 0xe: event_key=P4_EVENT_SCALAR_DP_UOP; break;
746 case 0x13: event_key=P4_EVENT_GLOBAL_POWER_EVENTS; break;
747 case 0x16: event_key=P4_EVENT_B2B_CYCLES; break;
748 case 0x17: event_key=P4_EVENT_FSB_DATA_ACTIVITY; break;
749 case 0x18: event_key=P4_EVENT_ITLB_REFERENCE; break;
750 case 0x1a: if (cccrsel==6) {
751 event_key=P4_EVENT_IOQ_ACTIVE_ENTRIES;
752 }
753 if (cccrsel==1) {
754 event_key=P4_EVENT_128BIT_MMX_UOP;
755 }
756 break;
757 case 0x34: event_key= P4_EVENT_SSE_INPUT_ASSIST; break;
758 }
759
760 pe_event=(escr&0x1ffffff)<<32;
761 pe_event|=(cccr&0xfffff000);
762 pe_event|=(((long long)(event_key))<<57);
763
764 return pe_event;
765}
766
768
769int
771 hwd_register_t *ni_bits ) {
772
773 int ret,pe_event;
774 (void)ni_bits;
775
776 /*
777 * We need an event code that is common across all counters.
778 * The implementation is required to know how to translate the supplied
779 * code to whichever counter it ends up on.
780 */
781
782#if defined(__powerpc__)
783 int code;
784 ret = pfm_get_event_code_counter( ( ( pfm_register_t * ) ni_bits )->event, 0, &code );
785 if ( ret ) {
786 /* Unrecognized code, but should never happen */
787 return PAPI_EBUG;
788 }
789 pe_event = code;
790 SUBDBG( "Stuffing native event index (code %#x, raw code %#x) into events array.\n",
791 ( ( pfm_register_t * ) ni_bits )->event, code );
792#else
793
796
797 memset( &inp, 0, sizeof ( inp ) );
798 memset( &outp, 0, sizeof ( outp ) );
799 inp.pfp_event_count = 1;
801 pfm_regmask_set( &inp.pfp_unavail_pmcs, 16 ); // mark fixed counters as unavailable
802
803 inp.pfp_events[0] = *( ( pfm_register_t * ) ni_bits );
804 ret = pfm_dispatch_events( &inp, NULL, &outp, NULL );
805 if (ret != PFMLIB_SUCCESS) {
806 SUBDBG( "Error: pfm_dispatch_events returned: %d\n", ret);
807 return PAPI_ESYS;
808 }
809
810 /* Special case p4 */
813
814 pe_event=generate_p4_event( outp.pfp_pmcs[0].reg_value, /* escr */
815 outp.pfp_pmcs[1].reg_value, /* cccr */
816 outp.pfp_pmcs[0].reg_addr); /* escr_addr */
817 }
818 else {
819 pe_event = outp.pfp_pmcs[0].reg_value;
820 }
821 SUBDBG( "pe_event: %#llx\n", outp.pfp_pmcs[0].reg_value );
822#endif
823
824 attr->config=pe_event;
825
826 /* for libpfm3 we currently only handle RAW type */
827 attr->type=PERF_TYPE_RAW;
828
829 return PAPI_OK;
830}
831
832int
834
835 SUBDBG("shutdown\n");
836
837 return PAPI_OK;
838}
839
840
double tmp
int i
#define PAPI_DOM_USER
Definition: f90papi.h:174
#define PAPI_ENUM_EVENTS
Definition: f90papi.h:224
#define PAPI_EBUG
Definition: f90papi.h:176
#define PAPI_OK
Definition: f90papi.h:73
#define PAPI_NTV_ENUM_UMASK_COMBOS
Definition: f90papi.h:108
#define PAPI_ENUM_FIRST
Definition: f90papi.h:85
#define PAPI_MIN_STR_LEN
Definition: f90papi.h:208
#define PAPI_ECNFLCT
Definition: f90papi.h:234
#define PAPI_ENOEVNT
Definition: f90papi.h:139
#define PAPI_ECOMBO
Definition: f90papi.h:256
#define PAPI_ENOEVST
Definition: f90papi.h:95
#define PAPI_VENDOR_INTEL
Definition: f90papi.h:275
#define PAPI_ECOUNT
Definition: f90papi.h:195
#define PAPI_EINVAL
Definition: f90papi.h:115
#define PAPI_ENOSUPP
Definition: f90papi.h:244
#define PAPI_EMISC
Definition: f90papi.h:122
#define PAPI_ESYS
Definition: f90papi.h:136
#define PAPI_NTV_ENUM_UMASKS
Definition: f90papi.h:66
#define PAPI_2MAX_STR_LEN
Definition: f90papi.h:180
#define PAPI_ENOMEM
Definition: f90papi.h:16
#define PAPI_ENOINIT
Definition: f90papi.h:160
#define PAPI_EATTR
Definition: f90papi.h:97
#define PAPI_EBUF
Definition: f90papi.h:253
static long long values[NUM_EVENTS]
Definition: init_fini.c:10
#define PFM_VERSION_MAJOR(x)
#define PFM_VERSION_MINOR(x)
uint8_t version
#define PAPI_NATIVE_AND_MASK
#define PAPI_NATIVE_MASK
Return codes and api definitions.
#define SUBDBG(format, args...)
Definition: papi_debug.h:64
void PAPIERROR(char *format,...)
unsigned int PAPI_NATIVE_EVENT_AND_MASK
int _papi_libpfm_init(papi_vector_t *my_vector, int cidx)
int _perfmon2_pfm_pmu_type
int _papi_libpfm_ntv_code_to_name(unsigned int EventCode, char *ntv_name, int len)
int _papi_libpfm_ntv_enum_events(unsigned int *EventCode, int modifier)
int _papi_libpfm_shutdown(void)
int num_native_events
int _papi_libpfm_ntv_name_to_code(const char *name, unsigned int *event_code)
int _papi_libpfm_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
static int encode_native_event_raw(unsigned int event, unsigned int mask)
int _papi_libpfm_ntv_code_to_descr(unsigned int EventCode, char *ntv_descr, int len)
int _pfm_decode_native_event(unsigned int EventCode, unsigned int *event, unsigned int *umask)
unsigned int PAPI_NATIVE_UMASK_AND_MASK
static int encode_native_event(unsigned int event, unsigned int num_mask, unsigned int *mask_values)
unsigned int PAPI_NATIVE_EVENT_SHIFT
unsigned int PAPI_NATIVE_UMASK_SHIFT
long long generate_p4_event(long long escr, long long cccr, long long escr_addr)
pfmlib_event_t pfm_register_t
static unsigned int convert_pfm_masks(pfmlib_event_t *gete)
int prepare_umask(unsigned int foo, unsigned int *values)
unsigned int _pfm_convert_umask(unsigned int event, unsigned int umask)
unsigned int PAPI_NATIVE_UMASK_MAX
int _papi_libpfm_ntv_code_to_bits(unsigned int EventCode, hwd_register_t *bits)
int _papi_libpfm_error(int pfm_error)
int _papi_libpfm_setup_counters(struct perf_event_attr *attr, hwd_register_t *ni_bits)
#define PERF_TYPE_RAW
int _papi_load_preset_table(char *pmu_str, int pmu_type, int cidx)
Definition: papi_preset.c:771
static int cidx
papi_mdi_t _papi_hwi_system_info
Definition: papi_internal.c:56
#define PFMLIB_VERSION
Definition: pfmlib.h:34
pfm_err_t pfm_get_pmu_name(char *name, int maxlen)
#define PFMLIB_ERR_FEATCOMB
Definition: pfmlib.h:292
char * pfm_strerror(int code)
pfm_err_t pfm_dispatch_events(pfmlib_input_param_t *p, void *model_in, pfmlib_output_param_t *q, void *model_out)
pfm_err_t pfm_get_event_code_counter(unsigned int idx, unsigned int cnt, int *code)
#define PFMLIB_ERR_BADHOST
Definition: pfmlib.h:303
#define PFMLIB_ERR_IRRALIGN
Definition: pfmlib.h:304
#define PFMLIB_ERR_MAGIC
Definition: pfmlib.h:291
#define PFMLIB_ERR_UMASK
Definition: pfmlib.h:306
pfm_err_t pfm_get_num_events(unsigned int *count)
#define PFMLIB_ERR_EVTSET
Definition: pfmlib.h:293
static int pfm_regmask_set(pfmlib_regmask_t *h, unsigned int b)
Definition: pfmlib.h:321
#define PFMLIB_SUCCESS
Definition: pfmlib.h:283
pfm_err_t pfm_get_event_mask_description(unsigned int event_idx, unsigned int mask_idx, char **desc)
#define PFMLIB_ERR_EVTINCOMP
Definition: pfmlib.h:294
pfm_err_t pfm_get_full_event_name(pfmlib_event_t *e, char *name, size_t maxlen)
#define PFMLIB_ERR_NOMEM
Definition: pfmlib.h:307
pfm_err_t pfm_get_event_name(unsigned int idx, char *name, size_t maxlen)
#define PFMLIB_ERR_NOTFOUND
Definition: pfmlib.h:287
#define PFMLIB_ERR_DRRTOOMANY
Definition: pfmlib.h:302
#define PFMLIB_ERR_DRRINVAL
Definition: pfmlib.h:301
pfm_err_t pfm_get_event_description(unsigned int idx, char **str)
#define PFMLIB_ERR_INVAL
Definition: pfmlib.h:285
#define PFMLIB_ERR_TOOMANY
Definition: pfmlib.h:295
#define PFMLIB_ERR_IRRTOOBIG
Definition: pfmlib.h:297
pfm_err_t pfm_initialize(void)
#define PFMLIB_ERR_NOINIT
Definition: pfmlib.h:286
pfm_err_t pfm_find_full_event(const char *str, pfmlib_event_t *e)
#define PFMLIB_ERR_IRRTOOMANY
Definition: pfmlib.h:300
#define PFMLIB_ERR_NOASSIGN
Definition: pfmlib.h:288
pfm_err_t pfm_get_pmu_type(int *type)
#define PFMLIB_ERR_IRREMPTY
Definition: pfmlib.h:298
#define PFMLIB_ERR_IRRINVAL
Definition: pfmlib.h:299
pfm_err_t pfm_get_num_event_masks(unsigned int event_idx, unsigned int *count)
#define PFMLIB_ERR_IRRFLAGS
Definition: pfmlib.h:305
#define PFMLIB_ERR_NOTSUPP
Definition: pfmlib.h:284
#define PFMLIB_ERR_EVTMANY
Definition: pfmlib.h:290
pfm_err_t pfm_get_event_mask_code(unsigned int idx, unsigned int mask_idx, unsigned int *code)
pfm_err_t pfm_get_version(unsigned int *version)
pfm_err_t pfm_find_event(const char *str, unsigned int *idx)
pfm_err_t pfm_get_num_counters(unsigned int *num)
#define PFMLIB_ERR_FULL
Definition: pfmlib.h:289
const char * name
Definition: rocs.c:225
int
Definition: sde_internal.h:89
long long int long long
Definition: sde_internal.h:85
char support_version[PAPI_MIN_STR_LEN]
Definition: papi.h:632
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:960
char long_descr[PAPI_HUGE_STR_LEN]
Definition: papi.h:963
int cpuid_family
Definition: papi.h:786
int vendor
Definition: papi.h:781
PAPI_hw_info_t hw_info
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
unsigned int num_masks
Definition: pfmlib.h:90
unsigned int unit_masks[PFMLIB_MAX_MASKS_PER_EVENT]
Definition: pfmlib.h:89
unsigned int event
Definition: pfmlib.h:86
unsigned int pfp_dfl_plm
Definition: pfmlib.h:110
pfmlib_regmask_t pfp_unavail_pmcs
Definition: pfmlib.h:114
pfmlib_event_t pfp_events[PFMLIB_MAX_PMCS]
Definition: pfmlib.h:113
unsigned int pfp_event_count
Definition: pfmlib.h:109
pfmlib_reg_t pfp_pmcs[PFMLIB_MAX_PMCS]
Definition: pfmlib.h:129
unsigned long long reg_value
Definition: pfmlib.h:98
unsigned long long reg_addr
Definition: pfmlib.h:99
int retval
Definition: zero_fork.c:53