PAPI  5.3.2.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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  */
25 unsigned int PAPI_NATIVE_EVENT_AND_MASK = 0x000003ff;
26 unsigned int PAPI_NATIVE_EVENT_SHIFT = 0;
27 unsigned int PAPI_NATIVE_UMASK_AND_MASK = 0x03fffc00;
28 unsigned int PAPI_NATIVE_UMASK_MAX = 16;
29 unsigned 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. */
47 static inline int
48 encode_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. */
61 static inline int
62 encode_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 */
78 int
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 */
98 int
99 prepare_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 */
115 static inline unsigned int
116 convert_pfm_masks( pfmlib_event_t * gete )
117 {
118  int ret;
119  unsigned int i, code, tmp = 0;
120 
121  for ( i = 0; i < gete->num_masks; i++ ) {
122  if ( ( ret =
123  pfm_get_event_mask_code( gete->event, gete->unit_masks[i],
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 */
136 unsigned 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 */
148 int
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 
183 int
184 _papi_libpfm_ntv_name_to_code( 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",
204  event.unit_masks[i], PAPI_NATIVE_UMASK_MAX );
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 
224 int
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 ) {
243  char tmp[PAPI_2MAX_STR_LEN];
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 )
248  PAPIERROR
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 
261 int
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 =
291  pfm_get_event_mask_description( event, gete.unit_masks[i],
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 
343 int
344 _papi_libpfm_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
345 {
346 
347  SUBDBG("ENTER %#x\n",EventCode);
348 
349  _papi_libpfm_ntv_code_to_name(EventCode,info->symbol,
350  sizeof(info->symbol));
351 
353  sizeof(info->long_descr));
354 
355  return PAPI_OK;
356 }
357 
358 
359 int
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 
415 int
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 
441 int
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 );
460  if ( pfm_get_version( &version ) != PFMLIB_SUCCESS ) {
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",
467  PFM_VERSION_MAJOR( version ), PFM_VERSION_MINOR( version ) );
468 
469  /* Complain if the compiled-against version doesn't match current version */
470  if ( PFM_VERSION_MAJOR( version ) != PFM_VERSION_MAJOR( PFMLIB_VERSION ) ) {
471  PAPIERROR( "Version mismatch of libpfm: compiled %#x vs. installed %#x\n",
472  PFM_VERSION_MAJOR( PFMLIB_VERSION ),
473  PFM_VERSION_MAJOR( version ) );
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 );
483  if ( pfm_get_pmu_type( &_perfmon2_pfm_pmu_type ) != PFMLIB_SUCCESS ) {
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 */
498  retval = _papi_load_preset_table( pmu_name, _perfmon2_pfm_pmu_type, cidx );
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 
537 long 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 
767 typedef pfmlib_event_t pfm_register_t;
768 
769 int
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 
794  pfmlib_input_param_t inp;
795  pfmlib_output_param_t outp;
796 
797  memset( &inp, 0, sizeof ( inp ) );
798  memset( &outp, 0, sizeof ( outp ) );
799  inp.pfp_event_count = 1;
800  inp.pfp_dfl_plm = PAPI_DOM_USER;
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 
832 int
834 
835  SUBDBG("shutdown\n");
836 
837  return PAPI_OK;
838 }
839 
840 
sprintf(splash[splash_line++],"\tIozone: Performance Test of File I/O\n")
int _papi_libpfm_init(papi_vector_t *my_vector, int cidx)
memset(eventId, 0, size)
static int prepare_umask(unsigned int foo, unsigned int *values)
long long generate_p4_event(long long escr, long long cccr, long long escr_addr)
#define PAPI_NATIVE_MASK
static unsigned int convert_pfm_masks(pfmlib_event_t *gete)
#define PAPI_ENOMEM
Definition: fpapi.h:107
#define PAPI_EMISC
Definition: fpapi.h:119
static int encode_native_event_raw(unsigned int event, unsigned int mask)
static int encode_native_event(unsigned int event, unsigned int num_mask, unsigned int *mask_values)
#define PAPI_MIN_STR_LEN
Definition: fpapi.h:41
int _papi_libpfm_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
#define PAPI_ENOEVNT
Definition: fpapi.h:112
#define PAPI_ENOINIT
Definition: fpapi.h:121
#define PAPI_EATTR
Definition: fpapi.h:127
char long_descr[PAPI_HUGE_STR_LEN]
Definition: papi.h:964
int _papi_libpfm_ntv_enum_events(unsigned int *EventCode, int modifier)
static int _perfmon2_pfm_pmu_type
Definition: perfmon.c:50
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:961
device[deviceId] domain[domainId] event
Definition: linux-cuda.c:306
return PAPI_OK
Definition: linux-nvml.c:458
void
Definition: iozone.c:18627
return PAPI_EINVAL
Definition: linux-nvml.c:408
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
#define PAPI_ECNFLCT
Definition: fpapi.h:113
Return codes and api definitions.
int num_native_events
long long ret
Definition: iozone.c:1346
#define PAPI_ECOUNT
Definition: fpapi.h:128
#define PAPI_2MAX_STR_LEN
Definition: papi.h:464
unsigned int PAPI_NATIVE_UMASK_SHIFT
int _papi_libpfm_ntv_code_to_name(unsigned int EventCode, char *ntv_name, int len)
unsigned int PAPI_NATIVE_UMASK_MAX
unsigned int PAPI_NATIVE_EVENT_AND_MASK
int i
Definition: fileop.c:140
#define PAPI_ENOSUPP
Definition: fpapi.h:123
#define PAPI_ENOEVST
Definition: fpapi.h:116
#define PAPI_ECOMBO
Definition: fpapi.h:129
free(dummyfile[xx])
static int cidx
Definition: event_info.c:40
unsigned int _pfm_convert_umask(unsigned int event, unsigned int umask)
pthread_attr_t foo
Definition: iozone.c:18592
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
#define PERF_TYPE_RAW
unsigned int PAPI_NATIVE_UMASK_AND_MASK
long long
Definition: iozone.c:19827
void PAPIERROR(char *format,...)
strcat(command, mountname)
int _papi_load_preset_table(char *pmu_str, int pmu_type, int cidx)
Definition: papi_preset.c:299
int _papi_libpfm_error(int pfm_error)
char version[]
Definition: fileop.c:134
int cpuid_family
Definition: papi.h:787
#define PAPI_ESYS
Definition: fpapi.h:108
int _papi_libpfm_ntv_code_to_descr(unsigned int EventCode, char *ntv_descr, int len)
int _papi_libpfm_shutdown(void)
papi_mdi_t _papi_hwi_system_info
Definition: papi_internal.c:57
PAPI_hw_info_t hw_info
again struct sockaddr sizeof(struct sockaddr_in))
#define PAPI_VENDOR_INTEL
Definition: papi.h:346
pfmlib_event_t pfm_register_t
Definition: perfctr-x86.h:140
int vendor
Definition: papi.h:782
#define PAPI_EBUG
Definition: fpapi.h:111
char * name
Definition: iozone.c:23648
int
Definition: iozone.c:18528
int _papi_libpfm_ntv_name_to_code(char *name, unsigned int *event_code)
#define PAPI_EBUF
Definition: fpapi.h:125
#define PAPI_NATIVE_AND_MASK
char support_version[PAPI_MIN_STR_LEN]
Definition: papi.h:630
int _papi_libpfm_ntv_code_to_bits(unsigned int EventCode, hwd_register_t *bits)
#define PAPI_DOM_USER
Definition: fpapi.h:21
unsigned int PAPI_NATIVE_EVENT_SHIFT
long j
Definition: iozone.c:19135
static long long values[NUM_EVENTS]
Definition: init_fini.c:10
ssize_t retval
Definition: libasync.c:338
long long tmp
Definition: iozone.c:12031
int _papi_libpfm_setup_counters(struct perf_event_attr *attr, hwd_register_t *ni_bits)
pthread_attr_t attr
Definition: iozone.c:18466
static int _pfm_decode_native_event(unsigned int EventCode, unsigned int *event, unsigned int *umask)