PAPI  5.3.0.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
perfmon-ia64.c
Go to the documentation of this file.
1 /*
2 * File: perfmon-ia64.c
3 * Author: Philip Mucci
4 * mucci@cs.utk.edu
5 * Mods: Kevin London
6 * london@cs.utk.edu
7 * Per Ekman
8 * pek@pdc.kth.se
9 * Zhou Min
10 * min@cs.utk.edu
11 */
12 
13 
14 #include "papi.h"
15 #include "papi_internal.h"
16 #include "papi_vector.h"
17 #include "threads.h"
18 #include "papi_memory.h"
19 #include "papi_lock.h"
20 
21 #include "linux-memory.h"
22 #include "linux-timer.h"
23 #include "linux-common.h"
24 
25 #if defined(__INTEL_COMPILER)
26 
27 #define hweight64(x) _m64_popcnt(x)
28 
29 #elif defined(__GNUC__)
30 
31 static inline int
32 hweight64( unsigned long x )
33 {
34  unsigned long result;
35  __asm__( "popcnt %0=%1": "=r"( result ):"r"( x ) );
36  return ( int ) result;
37 }
38 
39 #else
40 #error "you need to provide inline assembly from your compiler"
41 #endif
42 
43 extern int _perfmon2_pfm_pmu_type;
45 
46 #define OVFL_SIGNAL SIGPROF
47 #define PFMW_PEVT_EVTCOUNT(evt) (evt->inp.pfp_event_count)
48 #define PFMW_PEVT_EVENT(evt,idx) (evt->inp.pfp_events[idx].event)
49 #define PFMW_PEVT_PLM(evt,idx) (evt->inp.pfp_events[idx].plm)
50 #define PFMW_PEVT_DFLPLM(evt) (evt->inp.pfp_dfl_plm)
51 #define PFMW_PEVT_PFPPC(evt) (evt->pc)
52 #define PFMW_PEVT_PFPPD(evt) (evt->pd)
53 #define PFMW_PEVT_PFPPC_COUNT(evt) (evt->outp.pfp_pmc_count)
54 #define PFMW_PEVT_PFPPC_REG_NUM(evt,idx) (evt->outp.pfp_pmcs[idx].reg_num)
55 #define PFMW_PEVT_PFPPC_REG_VAL(evt,idx) (evt->pc[idx].reg_value)
56 #define PFMW_PEVT_PFPPC_REG_FLG(evt,idx) (evt->pc[idx].reg_flags)
57 #define PFMW_ARCH_REG_PMCVAL(reg) (reg.pmc_val)
58 #define PFMW_ARCH_REG_PMDVAL(reg) (reg.pmd_val)
59 
60 #define PFMON_MONT_MAX_IBRS 8
61 #define PFMON_MONT_MAX_DBRS 8
62 
63 #define PFMON_ITA2_MAX_IBRS 8
64 #define PFMON_ITA2_MAX_DBRS 8
65 /*
66  #if defined(ITANIUM3)
67  #define PFMW_ARCH_REG_PMCPLM(reg) (reg.pmc_mont_counter_reg.pmc_plm)
68  #define PFMW_ARCH_REG_PMCES(reg) (reg.pmc_mont_counter_reg.pmc_es)
69  typedef pfm_mont_pmc_reg_t pfmw_arch_pmc_reg_t;
70  typedef pfm_mont_pmd_reg_t pfmw_arch_pmd_reg_t;
71  #elif defined(ITANIUM2)
72  #define PFMW_ARCH_REG_PMCPLM(reg) (reg.pmc_ita2_counter_reg.pmc_plm)
73  #define PFMW_ARCH_REG_PMCES(reg) (reg.pmc_ita2_counter_reg.pmc_es)
74  typedef pfm_ita2_pmc_reg_t pfmw_arch_pmc_reg_t;
75  typedef pfm_ita2_pmd_reg_t pfmw_arch_pmd_reg_t;
76  #else
77  #define PFMW_ARCH_REG_PMCPLM(reg) (reg.pmc_ita_count_reg.pmc_plm)
78  #define PFMW_ARCH_REG_PMCES(reg) (reg.pmc_ita_count_reg.pmc_es)
79  typedef pfm_ita_pmc_reg_t pfmw_arch_pmc_reg_t;
80  typedef pfm_ita_pmd_reg_t pfmw_arch_pmd_reg_t;
81  #endif
82 */
83 typedef pfm_default_smpl_hdr_t pfmw_smpl_hdr_t;
84 typedef pfm_default_smpl_entry_t pfmw_smpl_entry_t;
85 
86 static void
88 {
89  pfm_self_start( ( ( ia64_context_t * ) ctx )->fd );
90 }
91 
92 static void
94 {
95  pfm_self_stop( ( ( ia64_context_t * ) ctx )->fd );
96 }
97 
98 static int
99 pfmw_perfmonctl( pid_t tid, int fd, int cmd, void *arg, int narg )
100 {
101  ( void ) tid; /*unused */
102  return ( perfmonctl( fd, cmd, arg, narg ) );
103 }
104 
105 static int
107 {
108  int ret;
109  ret = close( ( ( ia64_context_t * ) thr_ctx )->fd );
110  if ( ret )
111  return PAPI_ESYS;
112  else
113  return PAPI_OK;
114 }
115 
116 static int
118 {
119  int ret;
120  unsigned int i;
121 /*
122  PFMW_PEVT_DFLPLM(evt) = PFM_PLM3;
123 */
124 #ifdef PFMLIB_MONTECITO_PMU
125  if ( _perfmon2_pfm_pmu_type == PFMLIB_MONTECITO_PMU )
126  ret =
127  pfm_dispatch_events( &evt->inp,
128  ( pfmlib_mont_input_param_t * ) evt->mod_inp,
129  &evt->outp,
130  ( pfmlib_mont_output_param_t * ) evt->
131  mod_outp );
132  else
133 #endif
134  ret =
135  pfm_dispatch_events( &evt->inp,
136  ( pfmlib_ita2_input_param_t * ) evt->mod_inp,
137  &evt->outp,
138  ( pfmlib_ita2_output_param_t * ) evt->
139  mod_outp );
140  if ( ret ) {
141  return PAPI_ESYS;
142  } else {
143  for ( i = 0; i < evt->outp.pfp_pmc_count; i++ ) {
144  evt->pc[i].reg_num = evt->outp.pfp_pmcs[i].reg_num;
145  evt->pc[i].reg_value = evt->outp.pfp_pmcs[i].reg_value;
146  }
147 #if defined(HAVE_PFMLIB_OUTPUT_PFP_PMD_COUNT)
148  for ( i = 0; i < evt->outp.pfp_pmd_count; i++ ) {
149  evt->pd[i].reg_num = evt->outp.pfp_pmds[i].reg_num;
150  }
151 #else
152  /* This is really broken */
153  for ( i = 0; i < evt->inp.pfp_event_count; i++ ) {
154  evt->pd[i].reg_num = evt->pc[i].reg_num;
155  }
156 #endif
157  return PAPI_OK;
158  }
159 }
160 
161 static int
163 {
164  pfarg_load_t load_args;
165  int ret;
166 
167  memset( &load_args, 0, sizeof ( load_args ) );
168  /*
169  * we want to monitor ourself
170  */
171 
172  load_args.load_pid = ( ( ia64_context_t * ) ctx )->tid;
173 
174  SUBDBG( "PFM_LOAD_CONTEXT FD %d, PID %d\n",
175  ( ( ia64_context_t * ) ctx )->fd,
176  ( ( ia64_context_t * ) ctx )->tid );
177  if ( perfmonctl
178  ( ( ( ia64_context_t * ) ctx )->fd, PFM_LOAD_CONTEXT, &load_args,
179  1 ) == -1 ) {
180  PAPIERROR( "perfmonctl(PFM_LOAD_CONTEXT) errno %d", errno );
181  return ( PAPI_ESYS );
182  }
183  /*
184  * setup asynchronous notification on the file descriptor
185  */
186  ret =
187  fcntl( ( ( ia64_context_t * ) ctx )->fd, F_SETFL,
188  fcntl( ( ( ia64_context_t * ) ctx )->fd, F_GETFL,
189  0 ) | O_ASYNC );
190  if ( ret == -1 ) {
191  PAPIERROR( "fcntl(%d,F_SETFL,O_ASYNC) errno %d",
192  ( ( ia64_context_t * ) ctx )->fd, errno );
193  return ( PAPI_ESYS );
194  }
195 
196  /*
197  * get ownership of the descriptor
198  */
199 
200  ret =
201  fcntl( ( ( ia64_context_t * ) ctx )->fd, F_SETOWN,
202  ( ( ia64_context_t * ) ctx )->tid );
203  if ( ret == -1 ) {
204  PAPIERROR( "fcntl(%d,F_SETOWN) errno %d",
205  ( ( ia64_context_t * ) ctx )->fd, errno );
206  return ( PAPI_ESYS );
207  }
208 
209  ret =
210  fcntl( ( ( ia64_context_t * ) ctx )->fd, F_SETSIG,
211  _ia64_vector.cmp_info.hardware_intr_sig );
212  if ( ret == -1 ) {
213  PAPIERROR( "fcntl(%d,F_SETSIG) errno %d",
214  ( ( ia64_context_t * ) ctx )->fd, errno );
215  return ( PAPI_ESYS );
216  }
217 
218  /* set close-on-exec to ensure we will be getting the PFM_END_MSG, i.e.,
219  * fd not visible to child. */
220 
221  ret = fcntl( ( ( ia64_context_t * ) ctx )->fd, F_SETFD, FD_CLOEXEC );
222  if ( ret == -1 ) {
223  PAPIERROR( "fcntl(%d,FD_CLOEXEC) errno %d",
224  ( ( ia64_context_t * ) ctx )->fd, errno );
225  return ( PAPI_ESYS );
226  }
227 
228  return ( PAPI_OK );
229 
230 }
231 
232 static int
234 {
235  pfarg_context_t ctx;
236  memset( &ctx, 0, sizeof ( ctx ) );
237 
238  SUBDBG( "PFM_CREATE_CONTEXT on 0\n" );
239  if ( perfmonctl( 0, PFM_CREATE_CONTEXT, &ctx, 1 ) == -1 ) {
240  PAPIERROR( "perfmonctl(PFM_CREATE_CONTEXT) errno %d", errno );
241  return ( PAPI_ESYS );
242  }
243  ( ( ia64_context_t * ) thr_ctx )->fd = ctx.ctx_fd;
244  ( ( ia64_context_t * ) thr_ctx )->tid = mygettid( );
245  SUBDBG( "PFM_CREATE_CONTEXT returns FD %d, TID %d\n",
246  ( int ) ( ( ia64_context_t * ) thr_ctx )->fd,
247  ( int ) ( ( ia64_context_t * ) thr_ctx )->tid );
248 
249  return ( pfmw_create_ctx_common( thr_ctx ) );
250 }
251 
252 static int
253 set_pmds_to_write( EventSetInfo_t * ESI, int index, unsigned long value )
254 {
255  int *pos, count, i;
256  unsigned int hwcntr;
257  ia64_control_state_t *this_state =
258  ( ia64_control_state_t * ) ESI->ctl_state;
259  pfmw_param_t *pevt = &( this_state->evt );
260 
261  pos = ESI->EventInfoArray[index].pos;
262  count = 0;
263  while ( pos[count] != -1 && count < MAX_COUNTERS ) {
264  hwcntr = pos[count] + PMU_FIRST_COUNTER;
265  for ( i = 0; i < MAX_COUNTERS; i++ ) {
266  if ( PFMW_PEVT_PFPPC_REG_NUM( pevt, i ) == hwcntr ) {
267  this_state->evt.pc[i].reg_smpl_pmds[0] = value;
268  break;
269  }
270  }
271  count++;
272  }
273  return ( PAPI_OK );
274 }
275 
276 static int
277 _pfm_decode_native_event( unsigned int EventCode, unsigned int *event,
278  unsigned int *umask );
279 
280 static int
282  void **smpl_vaddr, int EventIndex )
283 {
284  pfm_default_smpl_ctx_arg_t ctx;
285  pfm_uuid_t buf_fmt_id = PFM_DEFAULT_SMPL_UUID;
286  int ctx_fd;
287  unsigned int native_index, EventCode;
288  int pos;
289  //hwd_context_t *thr_ctx = (hwd_context_t *) &ESI->master->context;
290 #ifdef PFMLIB_MONTECITO_PMU
291  unsigned int umask;
292 #endif
293 
294  pos = ESI->EventInfoArray[EventIndex].pos[0];
295  EventCode = ESI->EventInfoArray[EventIndex].event_code;
296 #ifdef PFMLIB_MONTECITO_PMU
297  if ( _perfmon2_pfm_pmu_type == PFMLIB_MONTECITO_PMU ) {
299  ( ESI->NativeInfoArray[pos].ni_event, &native_index,
300  &umask ) != PAPI_OK )
301  return ( PAPI_ENOEVNT );
302  } else
303 #endif
304  native_index =
306 
307  memset( &ctx, 0, sizeof ( ctx ) );
308  /*
309  * We initialize the format specific information.
310  * The format is identified by its UUID which must be copied
311  * into the ctx_buf_fmt_id field.
312  */
313  memcpy( ctx.ctx_arg.ctx_smpl_buf_id, buf_fmt_id, sizeof ( pfm_uuid_t ) );
314  /*
315  * the size of the buffer is indicated in bytes (not entries).
316  * The kernel will record into the buffer up to a certain point.
317  * No partial samples are ever recorded.
318  */
319  ctx.buf_arg.buf_size = 4096;
320  /*
321  * now create the context for self monitoring/per-task
322  */
323  SUBDBG( "PFM_CREATE_CONTEXT on 0\n" );
324  if ( perfmonctl( 0, PFM_CREATE_CONTEXT, &ctx, 1 ) == -1 ) {
325  if ( errno == ENOSYS )
326  PAPIERROR
327  ( "Your kernel does not have performance monitoring support" );
328  else
329  PAPIERROR( "perfmonctl(PFM_CREATE_CONTEXT) errno %d", errno );
330  return ( PAPI_ESYS );
331  }
332  /*
333  * extract the file descriptor we will use to
334  * identify this newly created context
335  */
336  ctx_fd = ctx.ctx_arg.ctx_fd;
337  /* save the fd into the thread context struct */
338  ( ( ia64_context_t * ) thr_ctx )->fd = ctx_fd;
339  ( ( ia64_context_t * ) thr_ctx )->tid = mygettid( );
340  SUBDBG( "PFM_CREATE_CONTEXT returns FD %d, TID %d\n",
341  ( int ) ( ( ia64_context_t * ) thr_ctx )->fd,
342  ( int ) ( ( ia64_context_t * ) thr_ctx )->tid );
343  /* indicate which PMD to include in the sample */
344 /* DEAR and BTB events */
345  switch ( _perfmon2_pfm_pmu_type ) {
346  case PFMLIB_ITANIUM_PMU:
347  if ( pfm_ita_is_dear( native_index ) )
348  set_pmds_to_write( ESI, EventIndex, DEAR_REGS_MASK );
349  else if ( pfm_ita_is_btb( native_index )
350  || EventCode == ( unsigned int ) PAPI_BR_INS )
351  set_pmds_to_write( ESI, EventIndex, BTB_REGS_MASK );
352  break;
353  case PFMLIB_ITANIUM2_PMU:
354  if ( pfm_ita2_is_dear( native_index ) )
355  set_pmds_to_write( ESI, EventIndex, DEAR_REGS_MASK );
356  else if ( pfm_ita2_is_btb( native_index )
357  || EventCode == ( unsigned int ) PAPI_BR_INS )
358  set_pmds_to_write( ESI, EventIndex, BTB_REGS_MASK );
359  break;
360  case PFMLIB_MONTECITO_PMU:
361  if ( pfm_mont_is_dear( native_index ) )
362  set_pmds_to_write( ESI, EventIndex, MONT_DEAR_REGS_MASK );
363  else if ( pfm_mont_is_etb( native_index ) ||
364  EventCode == ( unsigned int ) PAPI_BR_INS )
365  set_pmds_to_write( ESI, EventIndex, MONT_ETB_REGS_MASK );
366  break;
367  default:
368  PAPIERROR( "PMU type %d is not supported by this component",
369  _perfmon2_pfm_pmu_type );
370  return ( PAPI_EBUG );
371  }
372 
373  *smpl_vaddr = ctx.ctx_arg.ctx_smpl_vaddr;
374 
375  return ( pfmw_create_ctx_common( thr_ctx ) );
376 }
377 
378 static int
379 pfmw_get_event_name( char *name, unsigned int idx )
380 {
381  unsigned int total;
382 
383  pfm_get_num_events( &total );
384  if ( idx >= total )
385  return PAPI_ENOEVNT;
386  if ( pfm_get_event_name( idx, name, PAPI_MAX_STR_LEN ) == PFMLIB_SUCCESS )
387  return PAPI_OK;
388  else
389  return PAPI_ENOEVNT;
390 }
391 
392 static void
393 pfmw_get_event_description( unsigned int idx, char *dest, int len )
394 {
395  char *descr;
396 
397  if ( pfm_get_event_description( idx, &descr ) == PFMLIB_SUCCESS ) {
398  strncpy( dest, descr, len );
399  free( descr );
400  } else
401  *dest = '\0';
402 }
403 
404 static int
405 pfmw_is_dear( unsigned int i )
406 {
407  switch ( _perfmon2_pfm_pmu_type ) {
408  case PFMLIB_ITANIUM_PMU:
409  return ( pfm_ita_is_dear( i ) );
410  break;
411  case PFMLIB_ITANIUM2_PMU:
412  return ( pfm_ita2_is_dear( i ) );
413  break;
414  case PFMLIB_MONTECITO_PMU:
415  return ( pfm_mont_is_dear( i ) );
416  break;
417  default:
418  PAPIERROR( "PMU type %d is not supported by this component",
419  _perfmon2_pfm_pmu_type );
420  return ( PAPI_EBUG );
421  }
422 }
423 
424 static int
425 pfmw_is_iear( unsigned int i )
426 {
427  switch ( _perfmon2_pfm_pmu_type ) {
428  case PFMLIB_ITANIUM_PMU:
429  return ( pfm_ita_is_iear( i ) );
430  break;
431  case PFMLIB_ITANIUM2_PMU:
432  return ( pfm_ita2_is_iear( i ) );
433  break;
434  case PFMLIB_MONTECITO_PMU:
435  return ( pfm_mont_is_iear( i ) );
436  break;
437  default:
438  PAPIERROR( "PMU type %d is not supported by this component",
439  _perfmon2_pfm_pmu_type );
440  return ( PAPI_EBUG );
441  }
442 }
443 
444 static int
445 pfmw_support_darr( unsigned int i )
446 {
447  switch ( _perfmon2_pfm_pmu_type ) {
448  case PFMLIB_ITANIUM_PMU:
449  return ( pfm_ita_support_darr( i ) );
450  break;
451  case PFMLIB_ITANIUM2_PMU:
452  return ( pfm_ita2_support_darr( i ) );
453  break;
454  case PFMLIB_MONTECITO_PMU:
455  return ( pfm_mont_support_darr( i ) );
456  break;
457  default:
458  PAPIERROR( "PMU type %d is not supported by this component",
459  _perfmon2_pfm_pmu_type );
460  return ( PAPI_EBUG );
461  }
462 }
463 
464 static int
465 pfmw_support_iarr( unsigned int i )
466 {
467  switch ( _perfmon2_pfm_pmu_type ) {
468  case PFMLIB_ITANIUM_PMU:
469  return ( pfm_ita_support_iarr( i ) );
470  break;
471  case PFMLIB_ITANIUM2_PMU:
472  return ( pfm_ita2_support_iarr( i ) );
473  break;
474  case PFMLIB_MONTECITO_PMU:
475  return ( pfm_mont_support_iarr( i ) );
476  break;
477  default:
478  PAPIERROR( "PMU type %d is not supported by this component",
479  _perfmon2_pfm_pmu_type );
480  return ( PAPI_EBUG );
481  }
482 }
483 
484 static int
485 pfmw_support_opcm( unsigned int i )
486 {
487  switch ( _perfmon2_pfm_pmu_type ) {
488  case PFMLIB_ITANIUM_PMU:
489  return ( pfm_ita_support_opcm( i ) );
490  break;
491  case PFMLIB_ITANIUM2_PMU:
492  return ( pfm_ita2_support_opcm( i ) );
493  break;
494  case PFMLIB_MONTECITO_PMU:
495  return ( pfm_mont_support_opcm( i ) );
496  break;
497  default:
498  PAPIERROR( "PMU type %d is not supported by this component",
499  _perfmon2_pfm_pmu_type );
500  return ( PAPI_EBUG );
501  }
502 }
503 
504 static void
506 {
507  ia64_control_state_t *this_state = ( ia64_control_state_t * ) current_state;
508  pfmw_param_t *evt = &( this_state->evt );
509  unsigned long umasks_retired[4];
510  unsigned long umask;
511  unsigned int j, i, seen_retired, ibrp, idx;
512  int code;
513  int retired_code, incr;
514  pfmlib_ita2_output_param_t *ita2_output_param;
515  pfmlib_mont_output_param_t *mont_output_param;
516 
517 #if defined(PFMLIB_ITANIUM2_PMU) || defined(PFMLIB_MONTECITO_PMU)
518 char *retired_events[] = {
519  "IA64_TAGGED_INST_RETIRED_IBRP0_PMC8",
520  "IA64_TAGGED_INST_RETIRED_IBRP1_PMC9",
521  "IA64_TAGGED_INST_RETIRED_IBRP2_PMC8",
522  "IA64_TAGGED_INST_RETIRED_IBRP3_PMC9",
523  NULL
524 };
525 #endif
526 
527  switch ( _perfmon2_pfm_pmu_type ) {
528  case PFMLIB_ITANIUM2_PMU:
529  ita2_output_param =
530  &( this_state->ita_lib_param.ita2_param.ita2_output_param );
531  /*
532  * in fine mode, it is enough to use the event
533  * which only monitors the first debug register
534  * pair. The two pairs making up the range
535  * are guaranteed to be consecutive in rr_br[].
536  */
537  incr = pfm_ita2_irange_is_fine( &evt->outp, ita2_output_param ) ? 4 : 2;
538 
539  for ( i = 0; retired_events[i]; i++ ) {
540  pfm_find_event( retired_events[i], &idx );
541  pfm_ita2_get_event_umask( idx, umasks_retired + i );
542  }
543 
544  pfm_get_event_code( idx, &retired_code );
545 
546  /*
547  * print a warning message when the using IA64_TAGGED_INST_RETIRED_IBRP* which does
548  * not completely cover the all the debug register pairs used to make up the range.
549  * This could otherwise lead to misinterpretation of the results.
550  */
551  for ( i = 0; i < ita2_output_param->pfp_ita2_irange.rr_nbr_used;
552  i += incr ) {
553 
554  ibrp = ita2_output_param->pfp_ita2_irange.rr_br[i].reg_num >> 1;
555 
556  seen_retired = 0;
557  for ( j = 0; j < evt->inp.pfp_event_count; j++ ) {
558  pfm_get_event_code( evt->inp.pfp_events[j].event, &code );
559  if ( code != retired_code )
560  continue;
561  seen_retired = 1;
562  pfm_ita2_get_event_umask( evt->inp.pfp_events[j].event,
563  &umask );
564  if ( umask == umasks_retired[ibrp] )
565  break;
566  }
567  if ( seen_retired && j == evt->inp.pfp_event_count )
568  printf
569  ( "warning: code range uses IBR pair %d which is not monitored using %s\n",
570  ibrp, retired_events[ibrp] );
571  }
572 
573  break;
574  case PFMLIB_MONTECITO_PMU:
575  mont_output_param =
576  &( this_state->ita_lib_param.mont_param.mont_output_param );
577  /*
578  * in fine mode, it is enough to use the event
579  * which only monitors the first debug register
580  * pair. The two pairs making up the range
581  * are guaranteed to be consecutive in rr_br[].
582  */
583  incr = pfm_mont_irange_is_fine( &evt->outp, mont_output_param ) ? 4 : 2;
584 
585  for ( i = 0; retired_events[i]; i++ ) {
586  pfm_find_event( retired_events[i], &idx );
587  pfm_mont_get_event_umask( idx, umasks_retired + i );
588  }
589 
590  pfm_get_event_code( idx, &retired_code );
591 
592  /*
593  * print a warning message when the using IA64_TAGGED_INST_RETIRED_IBRP* which does
594  * not completely cover the all the debug register pairs used to make up the range.
595  * This could otherwise lead to misinterpretation of the results.
596  */
597  for ( i = 0; i < mont_output_param->pfp_mont_irange.rr_nbr_used;
598  i += incr ) {
599 
600  ibrp = mont_output_param->pfp_mont_irange.rr_br[i].reg_num >> 1;
601 
602  seen_retired = 0;
603  for ( j = 0; j < evt->inp.pfp_event_count; j++ ) {
604  pfm_get_event_code( evt->inp.pfp_events[j].event, &code );
605  if ( code != retired_code )
606  continue;
607  seen_retired = 1;
608  pfm_mont_get_event_umask( evt->inp.pfp_events[j].event,
609  &umask );
610  if ( umask == umasks_retired[ibrp] )
611  break;
612  }
613  if ( seen_retired && j == evt->inp.pfp_event_count )
614  printf
615  ( "warning: code range uses IBR pair %d which is not monitored using %s\n",
616  ibrp, retired_events[ibrp] );
617  }
618  break;
619  default:
620  PAPIERROR( "PMU type %d is not supported by this component",
621  _perfmon2_pfm_pmu_type );
622  }
623 }
624 
625 static int
627 {
628  ia64_control_state_t *this_state = ( ia64_control_state_t * ) current_state;
629  unsigned int i, used_dbr;
630  int r;
631  int pid = ( ( ia64_context_t * ) pctx )->fd;
632 
633  pfmlib_ita2_output_param_t *ita2_output_param;
634  pfarg_dbreg_t ita2_dbreg[PFMON_ITA2_MAX_IBRS];
635  pfmlib_mont_output_param_t *mont_output_param;
636  pfarg_dbreg_t mont_dbreg[PFMON_MONT_MAX_IBRS];
637 
638  memset( mont_dbreg, 0, sizeof ( mont_dbreg ) );
639  memset( ita2_dbreg, 0, sizeof ( ita2_dbreg ) );
640  check_ibrp_events( current_state );
641 
642  switch ( _perfmon2_pfm_pmu_type ) {
643  case PFMLIB_ITANIUM2_PMU:
644  ita2_output_param =
645  &( this_state->ita_lib_param.ita2_param.ita2_output_param );
646  used_dbr = ita2_output_param->pfp_ita2_irange.rr_nbr_used;
647 
648  for ( i = 0; i < used_dbr; i++ ) {
649  ita2_dbreg[i].dbreg_num =
650  ita2_output_param->pfp_ita2_irange.rr_br[i].reg_num;
651  ita2_dbreg[i].dbreg_value =
652  ita2_output_param->pfp_ita2_irange.rr_br[i].reg_value;
653  }
654 
655  r = perfmonctl( pid, PFM_WRITE_IBRS, ita2_dbreg,
656  ita2_output_param->pfp_ita2_irange.rr_nbr_used );
657  if ( r == -1 ) {
658  SUBDBG( "cannot install code range restriction: %s\n",
659  strerror( errno ) );
660  return ( PAPI_ESYS );
661  }
662  return ( PAPI_OK );
663  break;
664  case PFMLIB_MONTECITO_PMU:
665  mont_output_param =
666  &( this_state->ita_lib_param.mont_param.mont_output_param );
667 
668  used_dbr = mont_output_param->pfp_mont_irange.rr_nbr_used;
669 
670  for ( i = 0; i < used_dbr; i++ ) {
671  mont_dbreg[i].dbreg_num =
672  mont_output_param->pfp_mont_irange.rr_br[i].reg_num;
673  mont_dbreg[i].dbreg_value =
674  mont_output_param->pfp_mont_irange.rr_br[i].reg_value;
675  }
676 
677  r = perfmonctl( pid, PFM_WRITE_IBRS, mont_dbreg,
678  mont_output_param->pfp_mont_irange.rr_nbr_used );
679  if ( r == -1 ) {
680  SUBDBG( "cannot install code range restriction: %s\n",
681  strerror( errno ) );
682  return ( PAPI_ESYS );
683  }
684  return ( PAPI_OK );
685  break;
686  default:
687  PAPIERROR( "PMU type %d is not supported by this component",
688  _perfmon2_pfm_pmu_type );
689  return PAPI_ENOIMPL;
690  }
691 }
692 
693 static int
695 {
696  ia64_control_state_t *this_state = ( ia64_control_state_t * ) current_state;
697  unsigned int i, used_dbr;
698  int r;
699  int pid = ( ( ia64_context_t * ) pctx )->fd;
700 
701  pfmlib_ita2_output_param_t *ita2_output_param;
702  pfarg_dbreg_t ita2_dbreg[PFMON_ITA2_MAX_IBRS];
703  pfmlib_mont_output_param_t *mont_output_param;
704  pfarg_dbreg_t mont_dbreg[PFMON_MONT_MAX_IBRS];
705 
706  memset( mont_dbreg, 0, sizeof ( mont_dbreg ) );
707  memset( ita2_dbreg, 0, sizeof ( ita2_dbreg ) );
708 
709  switch ( _perfmon2_pfm_pmu_type ) {
710  case PFMLIB_ITANIUM2_PMU:
711  ita2_output_param =
712  &( this_state->ita_lib_param.ita2_param.ita2_output_param );
713  used_dbr = ita2_output_param->pfp_ita2_drange.rr_nbr_used;
714 
715  for ( i = 0; i < used_dbr; i++ ) {
716  ita2_dbreg[i].dbreg_num =
717  ita2_output_param->pfp_ita2_drange.rr_br[i].reg_num;
718  ita2_dbreg[i].dbreg_value =
719  ita2_output_param->pfp_ita2_drange.rr_br[i].reg_value;
720  }
721 
722  r = perfmonctl( pid, PFM_WRITE_DBRS, ita2_dbreg,
723  ita2_output_param->pfp_ita2_drange.rr_nbr_used );
724  if ( r == -1 ) {
725  SUBDBG( "cannot install data range restriction: %s\n",
726  strerror( errno ) );
727  return ( PAPI_ESYS );
728  }
729  return ( PAPI_OK );
730  break;
731  case PFMLIB_MONTECITO_PMU:
732  mont_output_param =
733  &( this_state->ita_lib_param.mont_param.mont_output_param );
734  used_dbr = mont_output_param->pfp_mont_drange.rr_nbr_used;
735 
736  for ( i = 0; i < used_dbr; i++ ) {
737  mont_dbreg[i].dbreg_num =
738  mont_output_param->pfp_mont_drange.rr_br[i].reg_num;
739  mont_dbreg[i].dbreg_value =
740  mont_output_param->pfp_mont_drange.rr_br[i].reg_value;
741  }
742 
743  r = perfmonctl( pid, PFM_WRITE_DBRS, mont_dbreg,
744  mont_output_param->pfp_mont_drange.rr_nbr_used );
745  if ( r == -1 ) {
746  SUBDBG( "cannot install data range restriction: %s\n",
747  strerror( errno ) );
748  return PAPI_ESYS;
749  }
750  return PAPI_OK;
751  break;
752  default:
753  PAPIERROR( "PMU type %d is not supported by this component",
754  _perfmon2_pfm_pmu_type );
755  return PAPI_ENOIMPL;
756  }
757 }
758 
759 /* The routines set_{d,i}range() provide places to install the data and / or
760  instruction address range restrictions for counting qualified events.
761  These routines must set up or clear the appropriate local static data structures.
762  The actual work of loading the hardware registers must be done in update_ctl_state().
763  Both drange and irange can be set on the same eventset.
764  If start=end=0, the feature is disabled.
765 */
766 static int
768  _papi_int_option_t * option )
769 {
770  int ret = PAPI_OK;
771  ia64_control_state_t *this_state = ( ia64_control_state_t * ) current_state;
772  pfmw_param_t *evt = &( this_state->evt );
773  pfmlib_input_param_t *inp = &evt->inp;
774  pfmlib_ita2_input_param_t *ita2_inp =
775  &( this_state->ita_lib_param.ita2_param.ita2_input_param );
776  pfmlib_ita2_output_param_t *ita2_outp =
777  &( this_state->ita_lib_param.ita2_param.ita2_output_param );
778  pfmlib_mont_input_param_t *mont_inp =
779  &( this_state->ita_lib_param.mont_param.mont_input_param );
780  pfmlib_mont_output_param_t *mont_outp =
781  &( this_state->ita_lib_param.mont_param.mont_output_param );
782 
783  switch ( _perfmon2_pfm_pmu_type ) {
784  case PFMLIB_ITANIUM2_PMU:
785 
786  if ( ( unsigned long ) option->address_range.start ==
787  ( unsigned long ) option->address_range.end ||
788  ( ( unsigned long ) option->address_range.start == 0 &&
789  ( unsigned long ) option->address_range.end == 0 ) )
790  return ( PAPI_EINVAL );
791  /*
792  * set the privilege mode:
793  * PFM_PLM3 : user level only
794  */
795  memset( &ita2_inp->pfp_ita2_drange, 0,
796  sizeof ( pfmlib_ita2_input_rr_t ) );
797  memset( ita2_outp, 0, sizeof ( pfmlib_ita2_output_param_t ) );
798  inp->pfp_dfl_plm = PFM_PLM3;
799  ita2_inp->pfp_ita2_drange.rr_used = 1;
800  ita2_inp->pfp_ita2_drange.rr_limits[0].rr_start =
801  ( unsigned long ) option->address_range.start;
802  ita2_inp->pfp_ita2_drange.rr_limits[0].rr_end =
803  ( unsigned long ) option->address_range.end;
804  SUBDBG
805  ( "++++ before data range : [0x%016lx-0x%016lx=%ld]: %d pair of debug registers used\n"
806  " start_offset:-0x%lx end_offset:+0x%lx\n",
807  ita2_inp->pfp_ita2_drange.rr_limits[0].rr_start,
808  ita2_inp->pfp_ita2_drange.rr_limits[0].rr_end,
809  ita2_inp->pfp_ita2_drange.rr_limits[0].rr_end -
810  ita2_inp->pfp_ita2_drange.rr_limits[0].rr_start,
811  ita2_outp->pfp_ita2_drange.rr_nbr_used >> 1,
812  ita2_outp->pfp_ita2_drange.rr_infos[0].rr_soff,
813  ita2_outp->pfp_ita2_drange.rr_infos[0].rr_eoff );
814 
815  /*
816  * let the library figure out the values for the PMCS
817  */
818  if ( ( ret = pfmw_dispatch_events( evt ) ) != PFMLIB_SUCCESS ) {
819  SUBDBG( "cannot configure events: %s\n", pfm_strerror( ret ) );
820  }
821 
822  SUBDBG
823  ( "++++ data range : [0x%016lx-0x%016lx=%ld]: %d pair of debug registers used\n"
824  " start_offset:-0x%lx end_offset:+0x%lx\n",
825  ita2_inp->pfp_ita2_drange.rr_limits[0].rr_start,
826  ita2_inp->pfp_ita2_drange.rr_limits[0].rr_end,
827  ita2_inp->pfp_ita2_drange.rr_limits[0].rr_end -
828  ita2_inp->pfp_ita2_drange.rr_limits[0].rr_start,
829  ita2_outp->pfp_ita2_drange.rr_nbr_used >> 1,
830  ita2_outp->pfp_ita2_drange.rr_infos[0].rr_soff,
831  ita2_outp->pfp_ita2_drange.rr_infos[0].rr_eoff );
832 
833 /* if( ita2_inp->pfp_ita2_irange.rr_limits[0].rr_start!=0 || ita2_inp->pfp_ita2_irange.rr_limits[0].rr_end!=0 )
834  if((ret=install_irange(ctx, current_state)) ==PAPI_OK){
835  option->address_range.start_off=ita2_outp->pfp_ita2_irange.rr_infos[0].rr_soff;
836  option->address_range.end_off=ita2_outp->pfp_ita2_irange.rr_infos[0].rr_eoff;
837  }
838 */
839  if ( ( ret = install_drange( ctx, current_state ) ) == PAPI_OK ) {
840  option->address_range.start_off =
841  ita2_outp->pfp_ita2_drange.rr_infos[0].rr_soff;
842  option->address_range.end_off =
843  ita2_outp->pfp_ita2_drange.rr_infos[0].rr_eoff;
844  }
845  return ( ret );
846 
847  break;
848  case PFMLIB_MONTECITO_PMU:
849 
850  if ( ( unsigned long ) option->address_range.start ==
851  ( unsigned long ) option->address_range.end ||
852  ( ( unsigned long ) option->address_range.start == 0 &&
853  ( unsigned long ) option->address_range.end == 0 ) )
854  return ( PAPI_EINVAL );
855  /*
856  * set the privilege mode:
857  * PFM_PLM3 : user level only
858  */
859  memset( &mont_inp->pfp_mont_drange, 0,
860  sizeof ( pfmlib_mont_input_rr_t ) );
861  memset( mont_outp, 0, sizeof ( pfmlib_mont_output_param_t ) );
862  inp->pfp_dfl_plm = PFM_PLM3;
863  mont_inp->pfp_mont_drange.rr_used = 1;
864  mont_inp->pfp_mont_drange.rr_limits[0].rr_start =
865  ( unsigned long ) option->address_range.start;
866  mont_inp->pfp_mont_drange.rr_limits[0].rr_end =
867  ( unsigned long ) option->address_range.end;
868  SUBDBG
869  ( "++++ before data range : [0x%016lx-0x%016lx=%ld]: %d pair of debug registers used\n"
870  " start_offset:-0x%lx end_offset:+0x%lx\n",
871  mont_inp->pfp_mont_drange.rr_limits[0].rr_start,
872  mont_inp->pfp_mont_drange.rr_limits[0].rr_end,
873  mont_inp->pfp_mont_drange.rr_limits[0].rr_end -
874  mont_inp->pfp_mont_drange.rr_limits[0].rr_start,
875  mont_outp->pfp_mont_drange.rr_nbr_used >> 1,
876  mont_outp->pfp_mont_drange.rr_infos[0].rr_soff,
877  mont_outp->pfp_mont_drange.rr_infos[0].rr_eoff );
878  /*
879  * let the library figure out the values for the PMCS
880  */
881  if ( ( ret = pfmw_dispatch_events( evt ) ) != PFMLIB_SUCCESS ) {
882  SUBDBG( "cannot configure events: %s\n", pfm_strerror( ret ) );
883  }
884 
885  SUBDBG
886  ( "++++ data range : [0x%016lx-0x%016lx=%ld]: %d pair of debug registers used\n"
887  " start_offset:-0x%lx end_offset:+0x%lx\n",
888  mont_inp->pfp_mont_drange.rr_limits[0].rr_start,
889  mont_inp->pfp_mont_drange.rr_limits[0].rr_end,
890  mont_inp->pfp_mont_drange.rr_limits[0].rr_end -
891  mont_inp->pfp_mont_drange.rr_limits[0].rr_start,
892  mont_outp->pfp_mont_drange.rr_nbr_used >> 1,
893  mont_outp->pfp_mont_drange.rr_infos[0].rr_soff,
894  mont_outp->pfp_mont_drange.rr_infos[0].rr_eoff );
895 
896 /* if( ita2_inp->pfp_ita2_irange.rr_limits[0].rr_start!=0 || ita2_inp->pfp_ita2_irange.rr_limits[0].rr_end!=0 )
897  if((ret=install_irange(ctx, current_state)) ==PAPI_OK){
898  option->address_range.start_off=ita2_outp->pfp_ita2_irange.rr_infos[0].rr_soff;
899  option->address_range.end_off=ita2_outp->pfp_ita2_irange.rr_infos[0].rr_eoff;
900  }
901 */
902  if ( ( ret = install_drange( ctx, current_state ) ) == PAPI_OK ) {
903  option->address_range.start_off =
904  mont_outp->pfp_mont_drange.rr_infos[0].rr_soff;
905  option->address_range.end_off =
906  mont_outp->pfp_mont_drange.rr_infos[0].rr_eoff;
907  }
908  return ( ret );
909 
910  break;
911  default:
912  PAPIERROR( "PMU type %d is not supported by this component",
913  _perfmon2_pfm_pmu_type );
914  return PAPI_ENOIMPL;
915  }
916 }
917 
918 static int
920  _papi_int_option_t * option )
921 {
922  int ret = PAPI_OK;
923  ia64_control_state_t *this_state = ( ia64_control_state_t * ) current_state;
924  pfmw_param_t *evt = &( this_state->evt );
925  pfmlib_input_param_t *inp = &evt->inp;
926  pfmlib_ita2_input_param_t *ita2_inp =
927  &( this_state->ita_lib_param.ita2_param.ita2_input_param );
928  pfmlib_ita2_output_param_t *ita2_outp =
929  &( this_state->ita_lib_param.ita2_param.ita2_output_param );
930  pfmlib_mont_input_param_t *mont_inp =
931  &( this_state->ita_lib_param.mont_param.mont_input_param );
932  pfmlib_mont_output_param_t *mont_outp =
933  &( this_state->ita_lib_param.mont_param.mont_output_param );
934 
935  switch ( _perfmon2_pfm_pmu_type ) {
936  case PFMLIB_ITANIUM2_PMU:
937 
938  if ( ( unsigned long ) option->address_range.start ==
939  ( unsigned long ) option->address_range.end ||
940  ( ( unsigned long ) option->address_range.start == 0 &&
941  ( unsigned long ) option->address_range.end == 0 ) )
942  return ( PAPI_EINVAL );
943  /*
944  * set the privilege mode:
945  * PFM_PLM3 : user level only
946  */
947  memset( &ita2_inp->pfp_ita2_irange, 0,
948  sizeof ( pfmlib_ita2_input_rr_t ) );
949  memset( ita2_outp, 0, sizeof ( pfmlib_ita2_output_param_t ) );
950  inp->pfp_dfl_plm = PFM_PLM3;
951  ita2_inp->pfp_ita2_irange.rr_used = 1;
952  ita2_inp->pfp_ita2_irange.rr_limits[0].rr_start =
953  ( unsigned long ) option->address_range.start;
954  ita2_inp->pfp_ita2_irange.rr_limits[0].rr_end =
955  ( unsigned long ) option->address_range.end;
956  SUBDBG
957  ( "++++ before code range : [0x%016lx-0x%016lx=%ld]: %d pair of debug registers used\n"
958  " start_offset:-0x%lx end_offset:+0x%lx\n",
959  ita2_inp->pfp_ita2_irange.rr_limits[0].rr_start,
960  ita2_inp->pfp_ita2_irange.rr_limits[0].rr_end,
961  ita2_inp->pfp_ita2_irange.rr_limits[0].rr_end -
962  ita2_inp->pfp_ita2_irange.rr_limits[0].rr_start,
963  ita2_outp->pfp_ita2_irange.rr_nbr_used >> 1,
964  ita2_outp->pfp_ita2_irange.rr_infos[0].rr_soff,
965  ita2_outp->pfp_ita2_irange.rr_infos[0].rr_eoff );
966 
967  /*
968  * let the library figure out the values for the PMCS
969  */
970  if ( ( ret = pfmw_dispatch_events( evt ) ) != PFMLIB_SUCCESS ) {
971  SUBDBG( "cannot configure events: %s\n", pfm_strerror( ret ) );
972  }
973 
974  SUBDBG
975  ( "++++ code range : [0x%016lx-0x%016lx=%ld]: %d pair of debug registers used\n"
976  " start_offset:-0x%lx end_offset:+0x%lx\n",
977  ita2_inp->pfp_ita2_irange.rr_limits[0].rr_start,
978  ita2_inp->pfp_ita2_irange.rr_limits[0].rr_end,
979  ita2_inp->pfp_ita2_irange.rr_limits[0].rr_end -
980  ita2_inp->pfp_ita2_irange.rr_limits[0].rr_start,
981  ita2_outp->pfp_ita2_irange.rr_nbr_used >> 1,
982  ita2_outp->pfp_ita2_irange.rr_infos[0].rr_soff,
983  ita2_outp->pfp_ita2_irange.rr_infos[0].rr_eoff );
984  if ( ( ret = install_irange( ctx, current_state ) ) == PAPI_OK ) {
985  option->address_range.start_off =
986  ita2_outp->pfp_ita2_irange.rr_infos[0].rr_soff;
987  option->address_range.end_off =
988  ita2_outp->pfp_ita2_irange.rr_infos[0].rr_eoff;
989  }
990 
991  break;
992  case PFMLIB_MONTECITO_PMU:
993 
994  if ( ( unsigned long ) option->address_range.start ==
995  ( unsigned long ) option->address_range.end ||
996  ( ( unsigned long ) option->address_range.start == 0 &&
997  ( unsigned long ) option->address_range.end == 0 ) )
998  return ( PAPI_EINVAL );
999  /*
1000  * set the privilege mode:
1001  * PFM_PLM3 : user level only
1002  */
1003  memset( &mont_inp->pfp_mont_irange, 0,
1004  sizeof ( pfmlib_mont_input_rr_t ) );
1005  memset( mont_outp, 0, sizeof ( pfmlib_mont_output_param_t ) );
1006  inp->pfp_dfl_plm = PFM_PLM3;
1007  mont_inp->pfp_mont_irange.rr_used = 1;
1008  mont_inp->pfp_mont_irange.rr_limits[0].rr_start =
1009  ( unsigned long ) option->address_range.start;
1010  mont_inp->pfp_mont_irange.rr_limits[0].rr_end =
1011  ( unsigned long ) option->address_range.end;
1012  SUBDBG
1013  ( "++++ before code range : [0x%016lx-0x%016lx=%ld]: %d pair of debug registers used\n"
1014  " start_offset:-0x%lx end_offset:+0x%lx\n",
1015  mont_inp->pfp_mont_irange.rr_limits[0].rr_start,
1016  mont_inp->pfp_mont_irange.rr_limits[0].rr_end,
1017  mont_inp->pfp_mont_irange.rr_limits[0].rr_end -
1018  mont_inp->pfp_mont_irange.rr_limits[0].rr_start,
1019  mont_outp->pfp_mont_irange.rr_nbr_used >> 1,
1020  mont_outp->pfp_mont_irange.rr_infos[0].rr_soff,
1021  mont_outp->pfp_mont_irange.rr_infos[0].rr_eoff );
1022 
1023  /*
1024  * let the library figure out the values for the PMCS
1025  */
1026  if ( ( ret = pfmw_dispatch_events( evt ) ) != PFMLIB_SUCCESS ) {
1027  SUBDBG( "cannot configure events: %s\n", pfm_strerror( ret ) );
1028  }
1029 
1030  SUBDBG
1031  ( "++++ code range : [0x%016lx-0x%016lx=%ld]: %d pair of debug registers used\n"
1032  " start_offset:-0x%lx end_offset:+0x%lx\n",
1033  mont_inp->pfp_mont_irange.rr_limits[0].rr_start,
1034  mont_inp->pfp_mont_irange.rr_limits[0].rr_end,
1035  mont_inp->pfp_mont_irange.rr_limits[0].rr_end -
1036  mont_inp->pfp_mont_irange.rr_limits[0].rr_start,
1037  mont_outp->pfp_mont_irange.rr_nbr_used >> 1,
1038  mont_outp->pfp_mont_irange.rr_infos[0].rr_soff,
1039  mont_outp->pfp_mont_irange.rr_infos[0].rr_eoff );
1040  if ( ( ret = install_irange( ctx, current_state ) ) == PAPI_OK ) {
1041  option->address_range.start_off =
1042  mont_outp->pfp_mont_irange.rr_infos[0].rr_soff;
1043  option->address_range.end_off =
1044  mont_outp->pfp_mont_irange.rr_infos[0].rr_eoff;
1045  }
1046 
1047  break;
1048  default:
1049  PAPIERROR( "PMU type %d is not supported by this component",
1050  _perfmon2_pfm_pmu_type );
1051  return PAPI_ENOIMPL;
1052  }
1053 
1054  return ret;
1055 }
1056 
1057 static int
1059 {
1060  unsigned int tmp;
1061  if ( pfm_get_num_counters( &tmp ) != PFMLIB_SUCCESS )
1062  return ( PAPI_ESYS );
1063  *num = tmp;
1064  return ( PAPI_OK );
1065 }
1066 
1067 static int
1069 {
1070  unsigned int tmp;
1071  if ( pfm_get_num_events( &tmp ) != PFMLIB_SUCCESS )
1072  return ( PAPI_ESYS );
1073  *num = tmp;
1074  return ( PAPI_OK );
1075 }
1076 
1077 
1078 /* Globals declared extern elsewhere */
1079 
1082 
1083 unsigned int PAPI_NATIVE_EVENT_AND_MASK = 0x000003ff;
1084 unsigned int PAPI_NATIVE_EVENT_SHIFT = 0;
1085 unsigned int PAPI_NATIVE_UMASK_AND_MASK = 0x03fffc00;
1086 unsigned int PAPI_NATIVE_UMASK_MAX = 16;
1087 unsigned int PAPI_NATIVE_UMASK_SHIFT = 10;
1088 
1089 /* Static locals */
1090 
1091 int _perfmon2_pfm_pmu_type = -1;
1092 
1093 /*
1094 static papi_svector_t _linux_ia64_table[] = {
1095  {(void (*)())_papi_hwd_update_shlib_info, VEC_PAPI_HWD_UPDATE_SHLIB_INFO},
1096  {(void (*)())_papi_hwd_init, VEC_PAPI_HWD_INIT},
1097  {(void (*)())_papi_hwd_init_control_state, VEC_PAPI_HWD_INIT_CONTROL_STATE},
1098  {(void (*)())_papi_hwd_dispatch_timer, VEC_PAPI_HWD_DISPATCH_TIMER},
1099  {(void (*)())_papi_hwd_ctl, VEC_PAPI_HWD_CTL},
1100  {(void (*)())_papi_hwd_get_real_usec, VEC_PAPI_HWD_GET_REAL_USEC},
1101  {(void (*)())_papi_hwd_get_real_cycles, VEC_PAPI_HWD_GET_REAL_CYCLES},
1102  {(void (*)())_papi_hwd_get_virt_cycles, VEC_PAPI_HWD_GET_VIRT_CYCLES},
1103  {(void (*)())_papi_hwd_get_virt_usec, VEC_PAPI_HWD_GET_VIRT_USEC},
1104  {(void (*)())_papi_hwd_update_control_state,VEC_PAPI_HWD_UPDATE_CONTROL_STATE},
1105  {(void (*)())_papi_hwd_start, VEC_PAPI_HWD_START },
1106  {(void (*)())_papi_hwd_stop, VEC_PAPI_HWD_STOP },
1107  {(void (*)())_papi_hwd_read, VEC_PAPI_HWD_READ },
1108  {(void (*)())_papi_hwd_shutdown, VEC_PAPI_HWD_SHUTDOWN },
1109  {(void (*)())_papi_hwd_reset, VEC_PAPI_HWD_RESET},
1110  {(void (*)())_papi_hwd_set_profile, VEC_PAPI_HWD_SET_PROFILE},
1111  {(void (*)())_papi_hwd_stop_profiling, VEC_PAPI_HWD_STOP_PROFILING},
1112  {(void (*)())_papi_hwd_get_dmem_info, VEC_PAPI_HWD_GET_DMEM_INFO},
1113  {(void (*)())_papi_hwd_set_overflow, VEC_PAPI_HWD_SET_OVERFLOW},
1114  {(void (*)())_papi_hwd_ntv_enum_events, VEC_PAPI_HWD_NTV_ENUM_EVENTS},
1115  {(void (*)())_papi_hwd_ntv_code_to_name, VEC_PAPI_HWD_NTV_CODE_TO_NAME},
1116  {(void (*)())_papi_hwd_ntv_code_to_descr, VEC_PAPI_HWD_NTV_CODE_TO_DESCR},
1117  {NULL, VEC_PAPI_END}
1118 };
1119 */
1120 
1123  {"L1D_READ_MISSES_RETIRED", "L2_INST_DEMAND_READS"}, {0}},
1124  {PAPI_L1_ICM, 0, {"L2_INST_DEMAND_READS"}, {0}},
1125  {PAPI_L1_DCM, 0, {"L1D_READ_MISSES_RETIRED"}, {0}},
1126  {PAPI_L2_TCM, 0, {"L2_MISSES"}, {0}},
1127  {PAPI_L2_DCM, DERIVED_SUB, {"L2_MISSES", "L3_READS_INST_READS_ALL"}, {0}},
1128  {PAPI_L2_ICM, 0, {"L3_READS_INST_READS_ALL"}, {0}},
1129  {PAPI_L3_TCM, 0, {"L3_MISSES"}, {0}},
1130  {PAPI_L3_ICM, 0, {"L3_READS_INST_READS_MISS"}, {0}},
1132  {"L3_READS_DATA_READS_MISS", "L3_WRITES_DATA_WRITES_MISS"}, {0}},
1133  {PAPI_L3_LDM, 0, {"L3_READS_DATA_READS_MISS"}, {0}},
1134  {PAPI_L3_STM, 0, {"L3_WRITES_DATA_WRITES_MISS"}, {0}},
1135  {PAPI_L1_LDM, 0, {"L1D_READ_MISSES_RETIRED"}, {0}},
1136  {PAPI_L2_LDM, 0, {"L3_READS_DATA_READS_ALL"}, {0}},
1137  {PAPI_L2_STM, 0, {"L3_WRITES_ALL_WRITES_ALL"}, {0}},
1139  {"L3_READS_DATA_READS_HIT", "L3_WRITES_DATA_WRITES_HIT"}, {0}},
1140  {PAPI_L1_DCH, DERIVED_SUB, {"L1D_READS_RETIRED", "L1D_READ_MISSES_RETIRED"},
1141  {0}},
1142  {PAPI_L1_DCA, 0, {"L1D_READS_RETIRED"}, {0}},
1143  {PAPI_L2_DCA, 0, {"L2_DATA_REFERENCES_ALL"}, {0}},
1145  {"L3_READS_DATA_READS_ALL", "L3_WRITES_DATA_WRITES_ALL"}, {0}},
1146  {PAPI_L2_DCR, 0, {"L2_DATA_REFERENCES_READS"}, {0}},
1147  {PAPI_L3_DCR, 0, {"L3_READS_DATA_READS_ALL"}, {0}},
1148  {PAPI_L2_DCW, 0, {"L2_DATA_REFERENCES_WRITES"}, {0}},
1149  {PAPI_L3_DCW, 0, {"L3_WRITES_DATA_WRITES_ALL"}, {0}},
1150  {PAPI_L3_ICH, 0, {"L3_READS_INST_READS_HIT"}, {0}},
1151  {PAPI_L1_ICR, DERIVED_ADD, {"L1I_PREFETCH_READS", "L1I_DEMAND_READS"}, {0}},
1153  {"L2_INST_DEMAND_READS", "L2_INST_PREFETCH_READS"}, {0}},
1154  {PAPI_L3_ICR, 0, {"L3_READS_INST_READS_ALL"}, {0}},
1155  {PAPI_TLB_DM, 0, {"DTLB_MISSES"}, {0}},
1156  {PAPI_TLB_IM, 0, {"ITLB_MISSES_FETCH"}, {0}},
1157  {PAPI_MEM_SCY, 0, {"MEMORY_CYCLE"}, {0}},
1158  {PAPI_STL_ICY, 0, {"UNSTALLED_BACKEND_CYCLE"}, {0}},
1159  {PAPI_BR_INS, 0, {"BRANCH_EVENT"}, {0}},
1160  {PAPI_BR_PRC, 0, {"BRANCH_PREDICTOR_ALL_CORRECT_PREDICTIONS"}, {0}},
1162  {"BRANCH_PREDICTOR_ALL_WRONG_PATH", "BRANCH_PREDICTOR_ALL_WRONG_TARGET"},
1163  {0}},
1164  {PAPI_TOT_CYC, 0, {"CPU_CYCLES"}, {0}},
1165  {PAPI_FP_OPS, DERIVED_ADD, {"FP_OPS_RETIRED_HI", "FP_OPS_RETIRED_LO"}, {0}},
1166  {PAPI_TOT_INS, 0, {"IA64_INST_RETIRED"}, {0}},
1167  {PAPI_LD_INS, 0, {"LOADS_RETIRED"}, {0}},
1168  {PAPI_SR_INS, 0, {"STORES_RETIRED"}, {0}},
1169  {PAPI_LST_INS, DERIVED_ADD, {"LOADS_RETIRED", "STORES_RETIRED"}, {0}},
1170  {0, 0, {0}, {0}}
1171 };
1172 
1174  {PAPI_CA_SNP, 0, {"BUS_SNOOPS_SELF"}, {0}},
1176  {"BUS_MEM_READ_BRIL_SELF", "BUS_MEM_READ_BIL_SELF"}, {0}},
1177  {PAPI_TLB_TL, DERIVED_ADD, {"ITLB_MISSES_FETCH_L2ITLB", "L2DTLB_MISSES"},
1178  {0}},
1179  {PAPI_STL_ICY, 0, {"DISP_STALLED"}, {0}},
1180  {PAPI_STL_CCY, 0, {"BACK_END_BUBBLE_ALL"}, {0}},
1181  {PAPI_TOT_IIS, 0, {"INST_DISPERSED"}, {0}},
1182  {PAPI_RES_STL, 0, {"BE_EXE_BUBBLE_ALL"}, {0}},
1183  {PAPI_FP_STAL, 0, {"BE_EXE_BUBBLE_FRALL"}, {0}},
1185  {"L2_DATA_REFERENCES_L2_DATA_READS", "L2_INST_DEMAND_READS",
1186  "L2_INST_PREFETCHES"}, {0}},
1187  {PAPI_L1_TCM, DERIVED_ADD, {"L2_INST_DEMAND_READS", "L1D_READ_MISSES_ALL"},
1188  {0}},
1189  {PAPI_L1_ICM, 0, {"L2_INST_DEMAND_READS"}, {0}},
1190  {PAPI_L1_DCM, 0, {"L1D_READ_MISSES_ALL"}, {0}},
1191  {PAPI_L2_TCM, 0, {"L2_MISSES"}, {0}},
1192  {PAPI_L2_DCM, DERIVED_SUB, {"L2_MISSES", "L3_READS_INST_FETCH_ALL"}, {0}},
1193  {PAPI_L2_ICM, 0, {"L3_READS_INST_FETCH_ALL"}, {0}},
1194  {PAPI_L3_TCM, 0, {"L3_MISSES"}, {0}},
1195  {PAPI_L3_ICM, 0, {"L3_READS_INST_FETCH_MISS"}, {0}},
1197  {"L3_READS_DATA_READ_MISS", "L3_WRITES_DATA_WRITE_MISS"}, {0}},
1198  {PAPI_L3_LDM, 0, {"L3_READS_ALL_MISS"}, {0}},
1199  {PAPI_L3_STM, 0, {"L3_WRITES_DATA_WRITE_MISS"}, {0}},
1200  {PAPI_L1_LDM, DERIVED_ADD, {"L1D_READ_MISSES_ALL", "L2_INST_DEMAND_READS"},
1201  {0}},
1202  {PAPI_L2_LDM, 0, {"L3_READS_ALL_ALL"}, {0}},
1203  {PAPI_L2_STM, 0, {"L3_WRITES_ALL_ALL"}, {0}},
1204  {PAPI_L1_DCH, DERIVED_SUB, {"L1D_READS_SET1", "L1D_READ_MISSES_ALL"}, {0}},
1205  {PAPI_L2_DCH, DERIVED_SUB, {"L2_DATA_REFERENCES_L2_ALL", "L2_MISSES"}, {0}},
1207  {"L3_READS_DATA_READ_HIT", "L3_WRITES_DATA_WRITE_HIT"}, {0}},
1208  {PAPI_L1_DCA, 0, {"L1D_READS_SET1"}, {0}},
1209  {PAPI_L2_DCA, 0, {"L2_DATA_REFERENCES_L2_ALL"}, {0}},
1211  {"L3_READS_DATA_READ_ALL", "L3_WRITES_DATA_WRITE_ALL"}, {0}},
1212  {PAPI_L1_DCR, 0, {"L1D_READS_SET1"}, {0}},
1213  {PAPI_L2_DCR, 0, {"L2_DATA_REFERENCES_L2_DATA_READS"}, {0}},
1214  {PAPI_L3_DCR, 0, {"L3_READS_DATA_READ_ALL"}, {0}},
1215  {PAPI_L2_DCW, 0, {"L2_DATA_REFERENCES_L2_DATA_WRITES"}, {0}},
1216  {PAPI_L3_DCW, 0, {"L3_WRITES_DATA_WRITE_ALL"}, {0}},
1217  {PAPI_L3_ICH, 0, {"L3_READS_DINST_FETCH_HIT"}, {0}},
1218  {PAPI_L1_ICR, DERIVED_ADD, {"L1I_PREFETCHES", "L1I_READS"}, {0}},
1219  {PAPI_L2_ICR, DERIVED_ADD, {"L2_INST_DEMAND_READS", "L2_INST_PREFETCHES"},
1220  {0}},
1221  {PAPI_L3_ICR, 0, {"L3_READS_INST_FETCH_ALL"}, {0}},
1222  {PAPI_L1_ICA, DERIVED_ADD, {"L1I_PREFETCHES", "L1I_READS"}, {0}},
1223  {PAPI_L2_TCH, DERIVED_SUB, {"L2_REFERENCES", "L2_MISSES"}, {0}},
1224  {PAPI_L3_TCH, DERIVED_SUB, {"L3_REFERENCES", "L3_MISSES"}, {0}},
1225  {PAPI_L2_TCA, 0, {"L2_REFERENCES"}, {0}},
1226  {PAPI_L3_TCA, 0, {"L3_REFERENCES"}, {0}},
1227  {PAPI_L3_TCR, 0, {"L3_READS_ALL_ALL"}, {0}},
1228  {PAPI_L3_TCW, 0, {"L3_WRITES_ALL_ALL"}, {0}},
1229  {PAPI_TLB_DM, 0, {"L2DTLB_MISSES"}, {0}},
1230  {PAPI_TLB_IM, 0, {"ITLB_MISSES_FETCH_L2ITLB"}, {0}},
1231  {PAPI_BR_INS, 0, {"BRANCH_EVENT"}, {0}},
1232  {PAPI_BR_PRC, 0, {"BR_MISPRED_DETAIL_ALL_CORRECT_PRED"}, {0}},
1234  {"BR_MISPRED_DETAIL_ALL_WRONG_PATH", "BR_MISPRED_DETAIL_ALL_WRONG_TARGET"},
1235  {0}},
1236  {PAPI_TOT_CYC, 0, {"CPU_CYCLES"}, {0}},
1237  {PAPI_FP_OPS, 0, {"FP_OPS_RETIRED"}, {0}},
1238  {PAPI_TOT_INS, DERIVED_ADD, {"IA64_INST_RETIRED", "IA32_INST_RETIRED"},
1239  {0}},
1240  {PAPI_LD_INS, 0, {"LOADS_RETIRED"}, {0}},
1241  {PAPI_SR_INS, 0, {"STORES_RETIRED"}, {0}},
1242  {PAPI_L2_ICA, 0, {"L2_INST_DEMAND_READS"}, {0}},
1243  {PAPI_L3_ICA, 0, {"L3_READS_INST_FETCH_ALL"}, {0}},
1244  {PAPI_L1_TCR, DERIVED_ADD, {"L1D_READS_SET0", "L1I_READS"}, {0}},
1245  {PAPI_L1_TCA, DERIVED_ADD, {"L1D_READS_SET0", "L1I_READS"}, {0}},
1246  {PAPI_L2_TCW, 0, {"L2_DATA_REFERENCES_L2_DATA_WRITES"}, {0}},
1247  {0, 0, {0}, {0}}
1248 };
1249 
1251 /* not sure */
1252  {PAPI_CA_SNP, 0, {"BUS_SNOOP_STALL_CYCLES_ANY"}, {0}},
1254  {"BUS_MEM_READ_BRIL_SELF", "BUS_MEM_READ_BIL_SELF"}, {0}},
1255 /* should be OK */
1256  {PAPI_TLB_TL, DERIVED_ADD, {"ITLB_MISSES_FETCH_L2ITLB", "L2DTLB_MISSES"},
1257  {0}},
1258  {PAPI_STL_ICY, 0, {"DISP_STALLED"}, {0}},
1259  {PAPI_STL_CCY, 0, {"BACK_END_BUBBLE_ALL"}, {0}},
1260  {PAPI_TOT_IIS, 0, {"INST_DISPERSED"}, {0}},
1261  {PAPI_RES_STL, 0, {"BE_EXE_BUBBLE_ALL"}, {0}},
1262  {PAPI_FP_STAL, 0, {"BE_EXE_BUBBLE_FRALL"}, {0}},
1263 /* should be OK */
1265  {"L2D_REFERENCES_READS", "L2I_READS_ALL_DMND", "L2I_READS_ALL_PFTCH"},
1266  {0}},
1267 /* what is the correct name here: L2I_READS_ALL_DMND or L2I_DEMANDS_READ ?
1268  * do not have papi_native_avail at this time, going to use L2I_READS_ALL_DMND always
1269  * just replace on demand
1270  */
1271  {PAPI_L1_TCM, DERIVED_ADD, {"L2I_READS_ALL_DMND", "L1D_READ_MISSES_ALL"},
1272  {0}},
1273  {PAPI_L1_ICM, 0, {"L2I_READS_ALL_DMND"}, {0}},
1274  {PAPI_L1_DCM, 0, {"L1D_READ_MISSES_ALL"}, {0}},
1275  {PAPI_L2_TCM, 0, {"L2I_READS_MISS_ALL", "L2D_MISSES"}, {0}},
1276  {PAPI_L2_DCM, DERIVED_SUB, {"L2D_MISSES"}, {0}},
1277  {PAPI_L2_ICM, 0, {"L2I_READS_MISS_ALL"}, {0}},
1278  {PAPI_L3_TCM, 0, {"L3_MISSES"}, {0}},
1279  {PAPI_L3_ICM, 0, {"L3_READS_INST_FETCH_MISS:M:E:S:I"}, {0}},
1281  {"L3_READS_DATA_READ_MISS:M:E:S:I", "L3_WRITES_DATA_WRITE_MISS:M:E:S:I"},
1282  {0}},
1283  {PAPI_L3_LDM, 0, {"L3_READS_ALL_MISS:M:E:S:I"}, {0}},
1284  {PAPI_L3_STM, 0, {"L3_WRITES_DATA_WRITE_MISS:M:E:S:I"}, {0}},
1285 /* why L2_INST_DEMAND_READS has been added here for the Itanium II ?
1286  * OLD: {PAPI_L1_LDM, DERIVED_ADD, {"L1D_READ_MISSES_ALL", "L2_INST_DEMAND_READS", 0, 0}}
1287  */
1288  {PAPI_L1_LDM, 0, {"L1D_READ_MISSES_ALL"}, {0}},
1289  {PAPI_L2_LDM, 0, {"L3_READS_ALL_ALL:M:E:S:I"}, {0}},
1290  {PAPI_L2_STM, 0, {"L3_WRITES_ALL_ALL:M:E:S:I"}, {0}},
1291  {PAPI_L1_DCH, DERIVED_SUB, {"L1D_READS_SET1", "L1D_READ_MISSES_ALL"}, {0}},
1292  {PAPI_L2_DCH, DERIVED_SUB, {"L2D_REFERENCES_ALL", "L2D_MISSES"}, {0}},
1294  {"L3_READS_DATA_READ_HIT:M:E:S:I", "L3_WRITES_DATA_WRITE_HIT:M:E:S:I"},
1295  {0}},
1296  {PAPI_L1_DCA, 0, {"L1D_READS_SET1"}, {0}},
1297  {PAPI_L2_DCA, 0, {"L2D_REFERENCES_ALL"}, {0}},
1298  {PAPI_L3_DCA, 0, {"L3_REFERENCES"}, {0}},
1299  {PAPI_L1_DCR, 0, {"L1D_READS_SET1"}, {0}},
1300  {PAPI_L2_DCR, 0, {"L2D_REFERENCES_READS"}, {0}},
1301  {PAPI_L3_DCR, 0, {"L3_READS_DATA_READ_ALL:M:E:S:I"}, {0}},
1302  {PAPI_L2_DCW, 0, {"L2D_REFERENCES_WRITES"}, {0}},
1303  {PAPI_L3_DCW, 0, {"L3_WRITES_DATA_WRITE_ALL:M:E:S:I"}, {0}},
1304  {PAPI_L3_ICH, 0, {"L3_READS_DINST_FETCH_HIT:M:E:S:I"}, {0}},
1305  {PAPI_L1_ICR, DERIVED_ADD, {"L1I_PREFETCHES", "L1I_READS"}, {0}},
1306  {PAPI_L2_ICR, DERIVED_ADD, {"L2I_READS_ALL_DMND", "L2I_PREFETCHES"}, {0}},
1307  {PAPI_L3_ICR, 0, {"L3_READS_INST_FETCH_ALL:M:E:S:I"}, {0}},
1308  {PAPI_L1_ICA, DERIVED_ADD, {"L1I_PREFETCHES", "L1I_READS"}, {0}},
1309  {PAPI_L2_TCH, DERIVED_SUB, {"L2I_READS_HIT_ALL", "L2D_INSERT_HITS"}, {0}},
1310  {PAPI_L3_TCH, DERIVED_SUB, {"L3_REFERENCES", "L3_MISSES"}, {0}},
1311  {PAPI_L2_TCA, DERIVED_ADD, {"L2I_READS_ALL_ALL", "L2D_REFERENCES_ALL"},
1312  {0}},
1313  {PAPI_L3_TCA, 0, {"L3_REFERENCES"}, {0}},
1314  {PAPI_L3_TCR, 0, {"L3_READS_ALL_ALL:M:E:S:I"}, {0}},
1315  {PAPI_L3_TCW, 0, {"L3_WRITES_ALL_ALL:M:E:S:I"}, {0}},
1316  {PAPI_TLB_DM, 0, {"L2DTLB_MISSES"}, {0}},
1317  {PAPI_TLB_IM, 0, {"ITLB_MISSES_FETCH_L2ITLB"}, {0}},
1318  {PAPI_BR_INS, 0, {"BRANCH_EVENT"}, {0}},
1319  {PAPI_BR_PRC, 0, {"BR_MISPRED_DETAIL_ALL_CORRECT_PRED"}, {0}},
1321  {"BR_MISPRED_DETAIL_ALL_WRONG_PATH", "BR_MISPRED_DETAIL_ALL_WRONG_TARGET"},
1322  {0}},
1323  {PAPI_TOT_CYC, 0, {"CPU_OP_CYCLES_ALL"}, {0}},
1324  {PAPI_FP_OPS, 0, {"FP_OPS_RETIRED"}, {0}},
1325 // {PAPI_TOT_INS, DERIVED_ADD, {"IA64_INST_RETIRED", "IA32_INST_RETIRED"}, {0}},
1326  {PAPI_TOT_INS, 0, {"IA64_INST_RETIRED"}, {0}},
1327  {PAPI_LD_INS, 0, {"LOADS_RETIRED"}, {0}},
1328  {PAPI_SR_INS, 0, {"STORES_RETIRED"}, {0}},
1329  {PAPI_L2_ICA, 0, {"L2I_DEMAND_READS"}, {0}},
1330  {PAPI_L3_ICA, 0, {"L3_READS_INST_FETCH_ALL:M:E:S:I"}, {0}},
1331  {PAPI_L1_TCR, 0, {"L2I_READS_ALL_ALL"}, {0}},
1332 /* Why are TCA READS+READS_SET0? I used the same as PAPI_L1_TCR, because its an write through cache
1333  * OLD: {PAPI_L1_TCA, DERIVED_ADD, {"L1D_READS_SET0", "L1I_READS"}, {0}},
1334  */
1336  {"L1I_PREFETCHES", "L1I_READS", "L1D_READS_SET0"}, {0}},
1337  {PAPI_L2_TCW, 0, {"L2D_REFERENCES_WRITES"}, {0}},
1338  {0, 0, {0}, {0}}
1339 };
1340 
1341 /* This component should never malloc anything. All allocation should be
1342  done by the high level API. */
1343 
1344 
1345 /*****************************************************************************
1346  * Code to support unit masks; only needed by Montecito and above *
1347  *****************************************************************************/
1348 static int _ia64_modify_event( unsigned int event, int modifier );
1349 
1350 /* Break a PAPI native event code into its composite event code and pfm mask bits */
1351 static int
1352 _pfm_decode_native_event( unsigned int EventCode, unsigned int *event,
1353  unsigned int *umask )
1354 {
1355  unsigned int tevent, major, minor;
1356 
1357  tevent = EventCode & PAPI_NATIVE_AND_MASK;
1358  major = ( tevent & PAPI_NATIVE_EVENT_AND_MASK ) >> PAPI_NATIVE_EVENT_SHIFT;
1359  if ( major >= ( unsigned int ) _ia64_vector.cmp_info.num_native_events )
1360  return ( PAPI_ENOEVNT );
1361 
1362  minor = ( tevent & PAPI_NATIVE_UMASK_AND_MASK ) >> PAPI_NATIVE_UMASK_SHIFT;
1363  *event = major;
1364  *umask = minor;
1365  SUBDBG( "EventCode 0x%08x is event %d, umask %#x\n", EventCode, major,
1366  minor );
1367  return ( PAPI_OK );
1368 }
1369 
1370 /* This routine is used to step through all possible combinations of umask
1371  values. It assumes that mask contains a valid combination of array indices
1372  for this event. */
1373 static int
1374 encode_native_event_raw( unsigned int event, unsigned int mask )
1375 {
1376  unsigned int tmp = event << PAPI_NATIVE_EVENT_SHIFT;
1377  SUBDBG( "Old native index was 0x%08x with 0x%08x mask\n", tmp, mask );
1378  tmp = tmp | ( mask << PAPI_NATIVE_UMASK_SHIFT );
1379  SUBDBG( "New encoding is 0x%08x\n", tmp | PAPI_NATIVE_MASK );
1380  return ( tmp | PAPI_NATIVE_MASK );
1381 }
1382 
1383 /* convert a collection of pfm mask bits into an array of pfm mask indices */
1384 static int
1385 prepare_umask( unsigned int foo, unsigned int *values )
1386 {
1387  unsigned int tmp = foo, i, j = 0;
1388 
1389  SUBDBG( "umask %#x\n", tmp );
1390  if ( foo == 0 )
1391  return 0;
1392  while ( ( i = ffs( tmp ) ) ) {
1393  tmp = tmp ^ ( 1 << ( i - 1 ) );
1394  values[j] = i - 1;
1395  SUBDBG( "umask %d is %d\n", j, values[j] );
1396  j++;
1397  }
1398  return ( j );
1399 }
1400 
1401 int
1402 _papi_pfm_ntv_enum_events( unsigned int *EventCode, int modifier )
1403 {
1404  unsigned int event, umask, num_masks;
1405  int ret;
1406 
1407  if ( modifier == PAPI_ENUM_FIRST ) {
1408  *EventCode = PAPI_NATIVE_MASK; /* assumes first native event is always 0x4000000 */
1409  return ( PAPI_OK );
1410  }
1411 
1412  if ( _pfm_decode_native_event( *EventCode, &event, &umask ) != PAPI_OK )
1413  return ( PAPI_ENOEVNT );
1414 
1415  ret = pfm_get_num_event_masks( event, &num_masks );
1416  SUBDBG( "pfm_get_num_event_masks: event=%d num_masks=%d\n", event,
1417  num_masks );
1418  if ( ret != PFMLIB_SUCCESS ) {
1419  PAPIERROR( "pfm_get_num_event_masks(%d,%p): %s", event, &num_masks,
1420  pfm_strerror( ret ) );
1421  return ( PAPI_ENOEVNT );
1422  }
1423  if ( num_masks > PAPI_NATIVE_UMASK_MAX )
1424  num_masks = PAPI_NATIVE_UMASK_MAX;
1425  SUBDBG( "This is umask %d of %d\n", umask, num_masks );
1426 
1427  if ( modifier == PAPI_ENUM_EVENTS ) {
1428  if ( event < ( unsigned int ) _ia64_vector.cmp_info.num_native_events - 1 ) {
1429  *EventCode = encode_native_event_raw( event + 1, 0 );
1430  return ( PAPI_OK );
1431  }
1432  return ( PAPI_ENOEVNT );
1433  } else if ( modifier == PAPI_NTV_ENUM_UMASK_COMBOS ) {
1434  if ( umask + 1 < ( unsigned ) ( 1 << num_masks ) ) {
1435  *EventCode = encode_native_event_raw( event, umask + 1 );
1436  return ( PAPI_OK );
1437  }
1438  return ( PAPI_ENOEVNT );
1439  } else if ( modifier == PAPI_NTV_ENUM_UMASKS ) {
1440  int thisbit = ffs( umask );
1441 
1442  SUBDBG( "First bit is %d in %08x\b\n", thisbit - 1, umask );
1443  thisbit = 1 << thisbit;
1444 
1445  if ( thisbit & ( ( 1 << num_masks ) - 1 ) ) {
1446  *EventCode = encode_native_event_raw( event, thisbit );
1447  return ( PAPI_OK );
1448  }
1449  return ( PAPI_ENOEVNT );
1450  } else {
1451  while ( event++ <
1452  ( unsigned int ) _ia64_vector.cmp_info.num_native_events - 1 ) {
1453  *EventCode = encode_native_event_raw( event + 1, 0 );
1454  if ( _ia64_modify_event( event + 1, modifier ) )
1455  return ( PAPI_OK );
1456  }
1457  return ( PAPI_ENOEVNT );
1458  }
1459 }
1460 
1461 static int
1462 _papi_pfm_ntv_name_to_code( char *name, unsigned int *event_code )
1463 {
1464  pfmlib_event_t event;
1465  unsigned int i, mask = 0;
1466  int ret;
1467 
1468  SUBDBG( "pfm_find_full_event(%s,%p)\n", name, &event );
1469  ret = pfm_find_full_event( name, &event );
1470  if ( ret == PFMLIB_SUCCESS ) {
1471  /* we can only capture PAPI_NATIVE_UMASK_MAX or fewer masks */
1472  if ( event.num_masks > PAPI_NATIVE_UMASK_MAX ) {
1473  SUBDBG( "num_masks (%d) > max masks (%d)\n", event.num_masks,
1474  PAPI_NATIVE_UMASK_MAX );
1475  return ( PAPI_ENOEVNT );
1476  } else {
1477  /* no mask index can exceed PAPI_NATIVE_UMASK_MAX */
1478  for ( i = 0; i < event.num_masks; i++ ) {
1479  if ( event.unit_masks[i] > PAPI_NATIVE_UMASK_MAX ) {
1480  SUBDBG( "mask index (%d) > max masks (%d)\n",
1481  event.unit_masks[i], PAPI_NATIVE_UMASK_MAX );
1482  return ( PAPI_ENOEVNT );
1483  }
1484  mask |= 1 << event.unit_masks[i];
1485  }
1486  *event_code = encode_native_event_raw( event.event, mask );
1487  SUBDBG( "event_code: %#x event: %d num_masks: %d\n", *event_code,
1488  event.event, event.num_masks );
1489  return ( PAPI_OK );
1490  }
1491  } else if ( ret == PFMLIB_ERR_UMASK ) {
1492  ret = pfm_find_event( name, &event.event );
1493  if ( ret == PFMLIB_SUCCESS ) {
1494  *event_code = encode_native_event_raw( event.event, 0 );
1495  return ( PAPI_OK );
1496  }
1497  }
1498  return ( PAPI_ENOEVNT );
1499 }
1500 
1501 int
1502 _papi_pfm_ntv_code_to_name( unsigned int EventCode, char *ntv_name, int len )
1503 {
1504  int ret;
1505  unsigned int event, umask;
1506  pfmlib_event_t gete;
1507 
1508  memset( &gete, 0, sizeof ( gete ) );
1509 
1510  if ( _pfm_decode_native_event( EventCode, &event, &umask ) != PAPI_OK )
1511  return ( PAPI_ENOEVNT );
1512 
1513  gete.event = event;
1514  gete.num_masks = prepare_umask( umask, gete.unit_masks );
1515  if ( gete.num_masks == 0 )
1516  ret = pfm_get_event_name( gete.event, ntv_name, len );
1517  else
1518  ret = pfm_get_full_event_name( &gete, ntv_name, len );
1519  if ( ret != PFMLIB_SUCCESS ) {
1520  char tmp[PAPI_2MAX_STR_LEN];
1521  pfm_get_event_name( gete.event, tmp, sizeof ( tmp ) );
1522  PAPIERROR
1523  ( "pfm_get_full_event_name(%p(event %d,%s,%d masks),%p,%d): %d -- %s",
1524  &gete, gete.event, tmp, gete.num_masks, ntv_name, len, ret,
1525  pfm_strerror( ret ) );
1526  if ( ret == PFMLIB_ERR_FULL )
1527  return PAPI_EBUF;
1528  return PAPI_ECMP;
1529  }
1530  return PAPI_OK;
1531 }
1532 
1533 int
1534 _papi_pfm_ntv_code_to_descr( unsigned int EventCode, char *ntv_descr, int len )
1535 {
1536  unsigned int event, umask;
1537  char *eventd, **maskd, *tmp;
1538  int i, ret, total_len = 0;
1539  pfmlib_event_t gete;
1540 
1541  memset( &gete, 0, sizeof ( gete ) );
1542 
1543  if ( _pfm_decode_native_event( EventCode, &event, &umask ) != PAPI_OK )
1544  return ( PAPI_ENOEVNT );
1545 
1546  ret = pfm_get_event_description( event, &eventd );
1547  if ( ret != PFMLIB_SUCCESS ) {
1548  PAPIERROR( "pfm_get_event_description(%d,%p): %s",
1549  event, &eventd, pfm_strerror( ret ) );
1550  return ( PAPI_ENOEVNT );
1551  }
1552 
1553  if ( ( gete.num_masks = prepare_umask( umask, gete.unit_masks ) ) ) {
1554  maskd = ( char ** ) malloc( gete.num_masks * sizeof ( char * ) );
1555  if ( maskd == NULL ) {
1556  free( eventd );
1557  return ( PAPI_ENOMEM );
1558  }
1559  for ( i = 0; i < ( int ) gete.num_masks; i++ ) {
1560  ret =
1561  pfm_get_event_mask_description( event, gete.unit_masks[i],
1562  &maskd[i] );
1563  if ( ret != PFMLIB_SUCCESS ) {
1564  PAPIERROR( "pfm_get_event_mask_description(%d,%d,%p): %s",
1565  event, umask, &maskd, pfm_strerror( ret ) );
1566  free( eventd );
1567  for ( ; i >= 0; i-- )
1568  free( maskd[i] );
1569  free( maskd );
1570  return ( PAPI_EINVAL );
1571  }
1572  total_len += strlen( maskd[i] );
1573  }
1574  tmp =
1575  ( char * ) malloc( strlen( eventd ) + strlen( ", masks:" ) +
1576  total_len + gete.num_masks + 1 );
1577  if ( tmp == NULL ) {
1578  for ( i = gete.num_masks - 1; i >= 0; i-- )
1579  free( maskd[i] );
1580  free( maskd );
1581  free( eventd );
1582  }
1583  tmp[0] = '\0';
1584  strcat( tmp, eventd );
1585  strcat( tmp, ", masks:" );
1586  for ( i = 0; i < ( int ) gete.num_masks; i++ ) {
1587  if ( i != 0 )
1588  strcat( tmp, "," );
1589  strcat( tmp, maskd[i] );
1590  free( maskd[i] );
1591  }
1592  free( maskd );
1593  } else {
1594  tmp = ( char * ) malloc( strlen( eventd ) + 1 );
1595  if ( tmp == NULL ) {
1596  free( eventd );
1597  return ( PAPI_ENOMEM );
1598  }
1599  tmp[0] = '\0';
1600  strcat( tmp, eventd );
1601  free( eventd );
1602  }
1603  strncpy( ntv_descr, tmp, len );
1604  if ( strlen( tmp ) > ( unsigned int ) len - 1 )
1605  ret = PAPI_EBUF;
1606  else
1607  ret = PAPI_OK;
1608  free( tmp );
1609  return ( ret );
1610 }
1611 
1612 /*****************************************************************************
1613  *****************************************************************************/
1614 
1615 /* The values defined in this file may be X86-specific (2 general
1616  purpose counters, 1 special purpose counter, etc.*/
1617 
1618 /* PAPI stuff */
1619 
1620 /* Low level functions, should not handle errors, just return codes. */
1621 
1622 /* I want to keep the old way to define the preset search map.
1623  In Itanium2, there are more than 400 native events, if I use the
1624  index directly, it will be difficult for people to debug, so I
1625  still keep the old way to define preset search table, but
1626  I add this function to generate the preset search map in papi3
1627 */
1628 int
1630  itanium_preset_search_t * oldmap, int num_cnt )
1631 {
1632  ( void ) num_cnt; /*unused */
1633  int pnum, i = 0, cnt;
1634  char **findme;
1635  hwi_search_t *psmap;
1636 
1637  /* Count up the presets */
1638  while ( oldmap[i].preset )
1639  i++;
1640  /* Add null entry */
1641  i++;
1642 
1643  psmap = ( hwi_search_t * ) papi_malloc( i * sizeof ( hwi_search_t ) );
1644  if ( psmap == NULL )
1645  return ( PAPI_ENOMEM );
1646  memset( psmap, 0x0, i * sizeof ( hwi_search_t ) );
1647 
1648  pnum = 0; /* preset event counter */
1649  for ( i = 0; i <= PAPI_MAX_PRESET_EVENTS; i++ ) {
1650  if ( oldmap[i].preset == 0 )
1651  break;
1652  pnum++;
1653  psmap[i].event_code = oldmap[i].preset;
1654  psmap[i].data.derived = oldmap[i].derived;
1655  strcpy( psmap[i].data.operation, oldmap[i].operation );
1656  findme = oldmap[i].findme;
1657  cnt = 0;
1658  while ( *findme != NULL ) {
1659  if ( cnt == MAX_COUNTER_TERMS ) {
1660  PAPIERROR( "Count (%d) == MAX_COUNTER_TERMS (%d)\n", cnt,
1662  papi_free( psmap );
1663  return ( PAPI_EBUG );
1664  }
1665  if ( _perfmon2_pfm_pmu_type == PFMLIB_MONTECITO_PMU ) {
1667  ( *findme,
1668  ( unsigned int * ) &psmap[i].data.native[cnt] ) !=
1669  PAPI_OK ) {
1670  PAPIERROR( "_papi_pfm_ntv_name_to_code(%s) failed\n",
1671  *findme );
1672  papi_free( psmap );
1673  return ( PAPI_EBUG );
1674  } else
1675  psmap[i].data.native[cnt] ^= PAPI_NATIVE_MASK;
1676  } else {
1677  if ( pfm_find_event_byname
1678  ( *findme,
1679  ( unsigned int * ) &psmap[i].data.native[cnt] ) !=
1680  PFMLIB_SUCCESS ) {
1681  PAPIERROR( "pfm_find_event_byname(%s) failed\n", *findme );
1682  papi_free( psmap );
1683  return ( PAPI_EBUG );
1684  } else
1685  psmap[i].data.native[cnt] ^= PAPI_NATIVE_MASK;
1686  }
1687 
1688  findme++;
1689  cnt++;
1690  }
1691  psmap[i].data.native[cnt] = PAPI_NULL;
1692  }
1693 
1694  *maploc = psmap;
1695  return ( PAPI_OK );
1696 }
1697 
1698 
1699 static char *
1700 search_cpu_info( FILE * f, char *search_str, char *line )
1701 {
1702  /* This code courtesy of our friends in Germany. Thanks Rudolph Berrendorf! */
1703  /* See the PCL home page for the German version of PAPI. */
1704 
1705  char *s;
1706 
1707  while ( fgets( line, 256, f ) != NULL ) {
1708  if ( strstr( line, search_str ) != NULL ) {
1709  /* ignore all characters in line up to : */
1710  for ( s = line; *s && ( *s != ':' ); ++s );
1711  if ( *s )
1712  return ( s );
1713  }
1714  }
1715  return ( NULL );
1716 
1717  /* End stolen code */
1718 }
1719 
1720 int
1721 _ia64_ita_set_domain( hwd_control_state_t * this_state, int domain )
1722 {
1723  int mode = 0, did = 0, i;
1724  pfmw_param_t *evt = &( ( ia64_control_state_t * ) this_state )->evt;
1725 
1726  if ( domain & PAPI_DOM_USER ) {
1727  did = 1;
1728  mode |= PFM_PLM3;
1729  }
1730 
1731  if ( domain & PAPI_DOM_KERNEL ) {
1732  did = 1;
1733  mode |= PFM_PLM0;
1734  }
1735 
1736  if ( !did )
1737  return ( PAPI_EINVAL );
1738 
1739  PFMW_PEVT_DFLPLM( evt ) = mode;
1740 
1741  /* Bug fix in case we don't call pfmw_dispatch_events after this code */
1742  /* Who did this? This sucks, we should always call it here -PJM */
1743 
1744  for ( i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++ ) {
1745  if ( PFMW_PEVT_PFPPC_REG_NUM( evt, i ) ) {
1746  pfm_ita_pmc_reg_t value;
1747  SUBDBG( "slot %d, register %lud active, config value 0x%lx\n",
1748  i, ( unsigned long ) ( PFMW_PEVT_PFPPC_REG_NUM( evt, i ) ),
1749  PFMW_PEVT_PFPPC_REG_VAL( evt, i ) );
1750 
1751  PFMW_ARCH_REG_PMCVAL( value ) = PFMW_PEVT_PFPPC_REG_VAL( evt, i );
1752  value.pmc_ita_count_reg.pmc_plm = mode;
1753  PFMW_PEVT_PFPPC_REG_VAL( evt, i ) = PFMW_ARCH_REG_PMCVAL( value );
1754 
1755  SUBDBG( "new config value 0x%lx\n",
1756  PFMW_PEVT_PFPPC_REG_VAL( evt, i ) );
1757  }
1758  }
1759 
1760  return PAPI_OK;
1761 }
1762 
1763 int
1764 _ia64_ita2_set_domain( hwd_control_state_t * this_state, int domain )
1765 {
1766  int mode = 0, did = 0, i;
1767  pfmw_param_t *evt = &this_state->evt;
1768 
1769  if ( domain & PAPI_DOM_USER ) {
1770  did = 1;
1771  mode |= PFM_PLM3;
1772  }
1773 
1774  if ( domain & PAPI_DOM_KERNEL ) {
1775  did = 1;
1776  mode |= PFM_PLM0;
1777  }
1778 
1779  if ( !did )
1780  return ( PAPI_EINVAL );
1781 
1782  PFMW_PEVT_DFLPLM( evt ) = mode;
1783 
1784  /* Bug fix in case we don't call pfmw_dispatch_events after this code */
1785  /* Who did this? This sucks, we should always call it here -PJM */
1786 
1787  for ( i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++ ) {
1788  if ( PFMW_PEVT_PFPPC_REG_NUM( evt, i ) ) {
1789  pfm_ita2_pmc_reg_t value;
1790  SUBDBG( "slot %d, register %lud active, config value 0x%lx\n",
1791  i, ( unsigned long ) ( PFMW_PEVT_PFPPC_REG_NUM( evt, i ) ),
1792  PFMW_PEVT_PFPPC_REG_VAL( evt, i ) );
1793 
1794  PFMW_ARCH_REG_PMCVAL( value ) = PFMW_PEVT_PFPPC_REG_VAL( evt, i );
1795  value.pmc_ita2_counter_reg.pmc_plm = mode;
1796  PFMW_PEVT_PFPPC_REG_VAL( evt, i ) = PFMW_ARCH_REG_PMCVAL( value );
1797 
1798  SUBDBG( "new config value 0x%lx\n",
1799  PFMW_PEVT_PFPPC_REG_VAL( evt, i ) );
1800  }
1801  }
1802 
1803  return ( PAPI_OK );
1804 }
1805 
1806 int
1807 _ia64_mont_set_domain( hwd_control_state_t * this_state, int domain )
1808 {
1809  int mode = 0, did = 0, i;
1810  pfmw_param_t *evt = &( ( ia64_control_state_t * ) this_state )->evt;
1811 
1812  if ( domain & PAPI_DOM_USER ) {
1813  did = 1;
1814  mode |= PFM_PLM3;
1815  }
1816 
1817  if ( domain & PAPI_DOM_KERNEL ) {
1818  did = 1;
1819  mode |= PFM_PLM0;
1820  }
1821 
1822  if ( !did )
1823  return ( PAPI_EINVAL );
1824 
1825  PFMW_PEVT_DFLPLM( evt ) = mode;
1826 
1827  /* Bug fix in case we don't call pfmw_dispatch_events after this code */
1828  /* Who did this? This sucks, we should always call it here -PJM */
1829 
1830  for ( i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++ ) {
1831  if ( PFMW_PEVT_PFPPC_REG_NUM( evt, i ) ) {
1832  pfm_mont_pmc_reg_t value;
1833  SUBDBG( "slot %d, register %lud active, config value 0x%lx\n",
1834  i, ( unsigned long ) ( PFMW_PEVT_PFPPC_REG_NUM( evt, i ) ),
1835  PFMW_PEVT_PFPPC_REG_VAL( evt, i ) );
1836 
1837  PFMW_ARCH_REG_PMCVAL( value ) = PFMW_PEVT_PFPPC_REG_VAL( evt, i );
1838  value.pmc_mont_counter_reg.pmc_plm = mode;
1839  PFMW_PEVT_PFPPC_REG_VAL( evt, i ) = PFMW_ARCH_REG_PMCVAL( value );
1840 
1841  SUBDBG( "new config value 0x%lx\n",
1842  PFMW_PEVT_PFPPC_REG_VAL( evt, i ) );
1843  }
1844  }
1845 
1846  return ( PAPI_OK );
1847 }
1848 
1849 int
1850 _ia64_set_domain( hwd_control_state_t * this_state, int domain )
1851 {
1852  switch ( _perfmon2_pfm_pmu_type ) {
1853  case PFMLIB_ITANIUM_PMU:
1854  return ( _ia64_ita_set_domain( this_state, domain ) );
1855  break;
1856  case PFMLIB_ITANIUM2_PMU:
1857  return ( _ia64_ita2_set_domain( this_state, domain ) );
1858  break;
1859  case PFMLIB_MONTECITO_PMU:
1860  return ( _ia64_mont_set_domain( this_state, domain ) );
1861  break;
1862  default:
1863  PAPIERROR( "PMU type %d is not supported by this component",
1864  _perfmon2_pfm_pmu_type );
1865  return ( PAPI_EBUG );
1866  }
1867 }
1868 
1869 static int
1870 set_granularity( hwd_control_state_t * this_state, int domain )
1871 {
1872  ( void ) this_state; /*unused */
1873  switch ( domain ) {
1874  case PAPI_GRN_PROCG:
1875  case PAPI_GRN_SYS:
1876  case PAPI_GRN_SYS_CPU:
1877  case PAPI_GRN_PROC:
1878  return PAPI_ECMP;
1879  case PAPI_GRN_THR:
1880  break;
1881  default:
1882  return PAPI_EINVAL;
1883  }
1884  return PAPI_OK;
1885 }
1886 
1887 int
1889  long long **events, int flags )
1890 {
1891  ( void ) flags; /*unused */
1892  unsigned int i;
1893  pfarg_reg_t readem[_ia64_vector.cmp_info.num_cntrs];
1894 
1895  pfmw_stop( ( ia64_context_t * ) ctx );
1896  memset( readem, 0x0, sizeof readem );
1897 
1898 /* read the 4 counters, the high level function will process the
1899  mapping for papi event to hardware counter
1900 */
1901  for ( i = 0; i < ( unsigned int ) _ia64_vector.cmp_info.num_cntrs; i++ ) {
1902  readem[i].reg_num = PMU_FIRST_COUNTER + i;
1903  }
1904 
1905  if ( pfmw_perfmonctl
1906  ( ( ( ia64_context_t * ) ctx )->tid, ( ( ia64_context_t * ) ctx )->fd,
1907  PFM_READ_PMDS, readem, _ia64_vector.cmp_info.num_cntrs ) == -1 ) {
1908  SUBDBG( "perfmonctl error READ_PMDS errno %d\n", errno );
1909  pfmw_start( ( ia64_context_t * ) ctx );
1910  return PAPI_ESYS;
1911  }
1912 
1913  for ( i = 0; i < ( unsigned int ) _ia64_vector.cmp_info.num_cntrs; i++ ) {
1914  ( ( ia64_control_state_t * ) machdep )->counters[i] =
1915  readem[i].reg_value;
1916  SUBDBG( "read counters is %ld\n", readem[i].reg_value );
1917  }
1918 
1919  pfmw_param_t *pevt = &( ( ( ia64_control_state_t * ) machdep )->evt );
1920  pfm_ita_pmc_reg_t flop_hack;
1921  /* special case, We need to scale FP_OPS_HI */
1922  for ( i = 0; i < PFMW_PEVT_EVTCOUNT( pevt ); i++ ) {
1923  PFMW_ARCH_REG_PMCVAL( flop_hack ) = PFMW_PEVT_PFPPC_REG_VAL( pevt, i );
1924  if ( flop_hack.pmc_ita_count_reg.pmc_es == 0xa )
1925  ( ( ia64_control_state_t * ) machdep )->counters[i] *= 4;
1926  }
1927 
1928  *events = ( ( ia64_control_state_t * ) machdep )->counters;
1929  pfmw_start( ( ia64_context_t * ) ctx );
1930  return PAPI_OK;
1931 }
1932 
1933 
1934 int
1936  long long **events, int flags )
1937 {
1938  ( void ) flags; /*unused */
1939  int i;
1940  pfarg_reg_t readem[_ia64_vector.cmp_info.num_cntrs];
1941 
1942  pfmw_stop( ( ia64_context_t * ) ctx );
1943  memset( readem, 0x0, sizeof readem );
1944 
1945 /* read the 4 counters, the high level function will process the
1946  mapping for papi event to hardware counter
1947 */
1948  for ( i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++ ) {
1949  readem[i].reg_num = PMU_FIRST_COUNTER + i;
1950  }
1951 
1952  if ( pfmw_perfmonctl
1953  ( ( ( ia64_context_t * ) ctx )->tid, ( ( ia64_context_t * ) ctx )->fd,
1954  PFM_READ_PMDS, readem, _ia64_vector.cmp_info.num_cntrs ) == -1 ) {
1955  SUBDBG( "perfmonctl error READ_PMDS errno %d\n", errno );
1956  pfmw_start( ( ia64_context_t * ) ctx );
1957  return PAPI_ESYS;
1958  }
1959 
1960  for ( i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++ ) {
1961  ( ( ia64_control_state_t * ) machdep )->counters[i] =
1962  readem[i].reg_value;
1963  SUBDBG( "read counters is %ld\n", readem[i].reg_value );
1964  }
1965 
1966  *events = ( ( ia64_control_state_t * ) machdep )->counters;
1967  pfmw_start( ( ia64_context_t * ) ctx );
1968  return PAPI_OK;
1969 }
1970 
1971 int
1973  long long **events, int flags )
1974 {
1975  switch ( _perfmon2_pfm_pmu_type ) {
1976  case PFMLIB_ITANIUM_PMU:
1977  return ( _ia64_ita_read( ctx, machdep, events, flags ) );
1978  break;
1979  case PFMLIB_ITANIUM2_PMU:
1980  return ( _ia64_ita23_read( ctx, machdep, events, flags ) );
1981  break;
1982  case PFMLIB_MONTECITO_PMU:
1983  return ( _ia64_ita23_read( ctx, machdep, events, flags ) );
1984  break;
1985  default:
1986  PAPIERROR( "PMU type %d is not supported by this component",
1987  _perfmon2_pfm_pmu_type );
1988  return ( PAPI_EBUG );
1989  }
1990 }
1991 
1992 /* This function should tell your kernel extension that your children
1993  inherit performance register information and propagate the values up
1994  upon child exit and parent wait. */
1995 
1996 static int
1997 set_inherit( int arg )
1998 {
1999  ( void ) arg; /*unused */
2000  return PAPI_ECMP;
2001 }
2002 
2003 static int
2004 set_default_domain( hwd_control_state_t * this_state, int domain )
2005 {
2006  return ( _ia64_set_domain( this_state, domain ) );
2007 }
2008 
2009 static int
2010 set_default_granularity( hwd_control_state_t * this_state, int granularity )
2011 {
2012  return ( set_granularity( this_state, granularity ) );
2013 }
2014 
2015 
2016 
2017 
2018 int
2020 {
2021  ( void ) cidx; /*unused */
2022  int i, retval, type;
2023  unsigned int version;
2024  pfmlib_options_t pfmlib_options;
2025  itanium_preset_search_t *ia_preset_search_map = NULL;
2026 
2027  /* Always initialize globals dynamically to handle forks properly. */
2028 
2029  preset_search_map = NULL;
2030 
2031  /* Opened once for all threads. */
2032  if ( pfm_initialize( ) != PFMLIB_SUCCESS )
2033  return ( PAPI_ESYS );
2034 
2035  if ( pfm_get_version( &version ) != PFMLIB_SUCCESS )
2036  return PAPI_ECMP;
2037 
2038  if ( PFM_VERSION_MAJOR( version ) != PFM_VERSION_MAJOR( PFMLIB_VERSION ) ) {
2039  PAPIERROR( "Version mismatch of libpfm: compiled %#x vs. installed %#x",
2040  PFM_VERSION_MAJOR( PFMLIB_VERSION ),
2041  PFM_VERSION_MAJOR( version ) );
2042  return PAPI_ECMP;
2043  }
2044 
2045  memset( &pfmlib_options, 0, sizeof ( pfmlib_options ) );
2046 #ifdef DEBUG
2047  if ( ISLEVEL( DEBUG_SUBSTRATE ) ) {
2048  pfmlib_options.pfm_debug = 1;
2049  pfmlib_options.pfm_verbose = 1;
2050  }
2051 #endif
2052 
2053  if ( pfm_set_options( &pfmlib_options ) )
2054  return ( PAPI_ESYS );
2055 
2056  if ( pfm_get_pmu_type( &type ) != PFMLIB_SUCCESS )
2057  return ( PAPI_ESYS );
2058 
2059  _perfmon2_pfm_pmu_type = type;
2060 
2061  /* Setup presets */
2062 
2063  switch ( type ) {
2064  case PFMLIB_ITANIUM_PMU:
2065  ia_preset_search_map = ia1_preset_search_map;
2066  break;
2067  case PFMLIB_ITANIUM2_PMU:
2068  ia_preset_search_map = ia2_preset_search_map;
2069  break;
2070  case PFMLIB_MONTECITO_PMU:
2071  ia_preset_search_map = ia3_preset_search_map;
2072  break;
2073  default:
2074  PAPIERROR( "PMU type %d is not supported by this component", type );
2075  return ( PAPI_EBUG );
2076  }
2077 
2078  int ncnt, nnev;
2079 
2080  retval = pfmw_get_num_events( &nnev );
2081  if ( retval != PAPI_OK )
2082  return ( retval );
2083 
2084  retval = pfmw_get_num_counters( &ncnt );
2085  if ( retval != PAPI_OK )
2086  return ( retval );
2087 
2088  sprintf( _ia64_vector.cmp_info.support_version,
2089  "%08x", PFMLIB_VERSION );
2090  sprintf( _ia64_vector.cmp_info.kernel_version,
2091  "%08x", 2 << 16 ); /* 2.0 */
2092 
2093  _ia64_vector.cmp_info.num_native_events = nnev;
2094  _ia64_vector.cmp_info.num_cntrs = ncnt;
2095  _ia64_vector.cmp_info.num_mpx_cntrs = ncnt;
2096 
2097  _ia64_vector.cmp_info.clock_ticks = sysconf( _SC_CLK_TCK );
2098  /* Put the signal handler in use to consume PFM_END_MSG's */
2100  _ia64_vector.cmp_info.CmpIdx );
2101 
2102  retval = mmtimer_setup();
2103  if ( retval )
2104  return ( retval );
2105 
2106  retval =
2107  generate_preset_search_map( &preset_search_map, ia_preset_search_map,
2108  _ia64_vector.cmp_info.num_cntrs );
2109  if ( retval )
2110  return ( retval );
2111 
2112  retval = _papi_hwi_setup_all_presets( preset_search_map, NULL );
2113  if ( retval )
2114  return ( retval );
2115 
2116  /* get_memory_info has a CPU model argument that is not used,
2117  * faking it here with hw_info.model which is not set by this
2118  * component
2119  */
2122  if ( retval )
2123  return ( retval );
2124 
2125  return ( PAPI_OK );
2126 }
2127 
2128 int
2130 {
2131 #if defined(USE_PROC_PTTIMER)
2132  {
2133  char buf[LINE_MAX];
2134  int fd;
2135  sprintf( buf, "/proc/%d/task/%d/stat", getpid( ), mygettid( ) );
2136  fd = open( buf, O_RDONLY );
2137  if ( fd == -1 ) {
2138  PAPIERROR( "open(%s)", buf );
2139  return ( PAPI_ESYS );
2140  }
2141  zero->stat_fd = fd;
2142  }
2143 #endif
2144  return ( pfmw_create_context( zero ) );
2145 }
2146 
2147 /* reset the hardware counters */
2148 int
2150 {
2151  pfmw_param_t *pevt = &( machdep->evt );
2152  pfarg_reg_t writeem[MAX_COUNTERS];
2153  int i;
2154 
2155  pfmw_stop( ctx );
2156  memset( writeem, 0, sizeof writeem );
2157  for ( i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++ ) {
2158  /* Writing doesn't matter, we're just zeroing the counter. */
2159  writeem[i].reg_num = PMU_FIRST_COUNTER + i;
2160  if ( PFMW_PEVT_PFPPC_REG_FLG( pevt, i ) & PFM_REGFL_OVFL_NOTIFY )
2161  writeem[i].reg_value = machdep->pd[i].reg_long_reset;
2162  }
2163  if ( pfmw_perfmonctl
2164  ( ctx->tid, ctx->fd, PFM_WRITE_PMDS, writeem,
2165  _ia64_vector.cmp_info.num_cntrs ) == -1 ) {
2166  PAPIERROR( "perfmonctl(PFM_WRITE_PMDS) errno %d", errno );
2167  return PAPI_ESYS;
2168  }
2169  pfmw_start( ctx );
2170  return ( PAPI_OK );
2171 }
2172 
2173 int
2175 {
2176  int i;
2177  pfmw_param_t *pevt = &( current_state->evt );
2178 
2179  pfmw_stop( ctx );
2180 
2181 /* write PMCS */
2182  if ( pfmw_perfmonctl( ctx->tid, ctx->fd, PFM_WRITE_PMCS,
2183  PFMW_PEVT_PFPPC( pevt ),
2184  PFMW_PEVT_PFPPC_COUNT( pevt ) ) == -1 ) {
2185  PAPIERROR( "perfmonctl(PFM_WRITE_PMCS) errno %d", errno );
2186  return ( PAPI_ESYS );
2187  }
2188  if ( pfmw_perfmonctl
2189  ( ctx->tid, ctx->fd, PFM_WRITE_PMDS, PFMW_PEVT_PFPPD( pevt ),
2190  PFMW_PEVT_EVTCOUNT( pevt ) ) == -1 ) {
2191  PAPIERROR( "perfmonctl(PFM_WRITE_PMDS) errno %d", errno );
2192  return ( PAPI_ESYS );
2193  }
2194 
2195 /* set the initial value of the hardware counter , if PAPI_overflow or
2196  PAPI_profil are called, then the initial value is the threshold
2197 */
2198  for ( i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++ )
2199  current_state->pd[i].reg_num = PMU_FIRST_COUNTER + i;
2200 
2201  if ( pfmw_perfmonctl( ctx->tid, ctx->fd,
2202  PFM_WRITE_PMDS, current_state->pd,
2203  _ia64_vector.cmp_info.num_cntrs ) == -1 ) {
2204  PAPIERROR( "perfmonctl(WRITE_PMDS) errno %d", errno );
2205  return ( PAPI_ESYS );
2206  }
2207 
2208  pfmw_start( ctx );
2209 
2210  return PAPI_OK;
2211 }
2212 
2213 int
2215 {
2216  ( void ) zero; /*unused */
2217  pfmw_stop( ctx );
2218  return PAPI_OK;
2219 }
2220 
2221 static int
2223 {
2224  if ( ns < _papi_os_info.itimer_res_ns ) {
2226  } else {
2227  int leftover_ns = ns % _papi_os_info.itimer_res_ns;
2228  return ns + leftover_ns;
2229  }
2230 }
2231 
2232 int
2233 _ia64_ctl( hwd_context_t * zero, int code, _papi_int_option_t * option )
2234 {
2235  int ret;
2236  switch ( code ) {
2237  case PAPI_DEFDOM:
2238  return ( set_default_domain( option->domain.ESI->ctl_state,
2239  option->domain.domain ) );
2240  case PAPI_DOMAIN:
2241  return ( _ia64_set_domain
2242  ( option->domain.ESI->ctl_state, option->domain.domain ) );
2243  case PAPI_DEFGRN:
2244  return ( set_default_granularity
2245  ( option->granularity.ESI->ctl_state,
2246  option->granularity.granularity ) );
2247  case PAPI_GRANUL:
2248  return ( set_granularity( option->granularity.ESI->ctl_state,
2249  option->granularity.granularity ) );
2250 #if 0
2251  case PAPI_INHERIT:
2252  return ( set_inherit( option->inherit.inherit ) );
2253 #endif
2254  case PAPI_DATA_ADDRESS:
2255  ret =
2257  option->address_range.domain );
2258  if ( ret != PAPI_OK )
2259  return ( ret );
2260  set_drange( zero, option->address_range.ESI->ctl_state, option );
2261  return ( PAPI_OK );
2262  case PAPI_INSTR_ADDRESS:
2263  ret =
2265  option->address_range.domain );
2266  if ( ret != PAPI_OK )
2267  return ( ret );
2268  set_irange( zero, option->address_range.ESI->ctl_state, option );
2269  return ( PAPI_OK );
2270  case PAPI_DEF_ITIMER:{
2271  /* flags are currently ignored, eventually the flags will be able
2272  to specify whether or not we use POSIX itimers (clock_gettimer) */
2273  if ( ( option->itimer.itimer_num == ITIMER_REAL ) &&
2274  ( option->itimer.itimer_sig != SIGALRM ) )
2275  return PAPI_EINVAL;
2276  if ( ( option->itimer.itimer_num == ITIMER_VIRTUAL ) &&
2277  ( option->itimer.itimer_sig != SIGVTALRM ) )
2278  return PAPI_EINVAL;
2279  if ( ( option->itimer.itimer_num == ITIMER_PROF ) &&
2280  ( option->itimer.itimer_sig != SIGPROF ) )
2281  return PAPI_EINVAL;
2282  if ( option->itimer.ns > 0 )
2283  option->itimer.ns = round_requested_ns( option->itimer.ns );
2284  /* At this point, we assume the user knows what he or
2285  she is doing, they maybe doing something arch specific */
2286  return PAPI_OK;
2287  }
2288  case PAPI_DEF_MPX_NS:{
2289  option->multiplex.ns = round_requested_ns( option->multiplex.ns );
2290  return ( PAPI_OK );
2291  }
2292  case PAPI_DEF_ITIMER_NS:{
2293  option->itimer.ns = round_requested_ns( option->itimer.ns );
2294  return ( PAPI_OK );
2295  }
2296  default:
2297  return ( PAPI_EINVAL );
2298  }
2299 }
2300 
2301 int
2303 {
2304 #if defined(USE_PROC_PTTIMER)
2305  close( ctx->stat_fd );
2306 #endif
2307 
2308  return ( pfmw_destroy_context( ctx ) );
2309 }
2310 
2311 static int
2313 {
2314  ( void ) thread; /*unused */
2315  pfmw_smpl_hdr_t *hdr;
2316  pfmw_smpl_entry_t *ent;
2317  unsigned long buf_pos;
2318  unsigned long entry_size;
2319  int ret, reg_num, count, pos;
2320  unsigned int i, EventCode = 0, eventindex, native_index = 0;
2321  ia64_control_state_t *this_state;
2322  pfm_ita_pmd_reg_t *reg;
2323  unsigned long overflow_vector, pc;
2324 
2325 
2326  if ( ( ESI->state & PAPI_PROFILING ) == 0 )
2327  return ( PAPI_EBUG );
2328 
2329  this_state = ( ia64_control_state_t * ) ( ESI->ctl_state );
2330  hdr = ( pfmw_smpl_hdr_t * ) this_state->smpl_vaddr;
2331 
2332  entry_size = sizeof ( pfmw_smpl_entry_t );
2333 
2334  /*
2335  * walk through all the entries recorded in the buffer
2336  */
2337  buf_pos = ( unsigned long ) ( hdr + 1 );
2338  for ( i = 0; i < hdr->hdr_count; i++ ) {
2339  ret = 0;
2340  ent = ( pfmw_smpl_entry_t * ) buf_pos;
2341  /* PFM30 only one PMD overflows in each sample */
2342  overflow_vector = 1 << ent->ovfl_pmd;
2343 
2344  SUBDBG( "Entry %d PID:%d CPU:%d ovfl_vector:0x%lx IIP:0x%016lx\n",
2345  i, ent->pid, ent->cpu, overflow_vector, ent->ip );
2346 
2347  while ( overflow_vector ) {
2348  reg_num = ffs( overflow_vector ) - 1;
2349  /* find the event code */
2350  for ( count = 0; count < ESI->profile.event_counter; count++ ) {
2351  eventindex = ESI->profile.EventIndex[count];
2352  pos = ESI->EventInfoArray[eventindex].pos[0];
2353  if ( pos + PMU_FIRST_COUNTER == reg_num ) {
2354  EventCode = ESI->profile.EventCode[count];
2355  native_index =
2356  ESI->NativeInfoArray[pos].
2357  ni_event & PAPI_NATIVE_AND_MASK;
2358  break;
2359  }
2360  }
2361  /* something is wrong */
2362  if ( count == ESI->profile.event_counter ) {
2363  PAPIERROR
2364  ( "wrong count: %d vs. ESI->profile.event_counter %d\n",
2365  count, ESI->profile.event_counter );
2366  return ( PAPI_EBUG );
2367  }
2368 
2369  /* print entry header */
2370  pc = ent->ip;
2371  if ( pfm_ita_is_dear( native_index ) ) {
2372  reg = ( pfm_ita_pmd_reg_t * ) ( ent + 1 );
2373  reg++;
2374  reg++;
2375  pc = ( reg->pmd17_ita_reg.dear_iaddr << 4 ) | ( reg->
2376  pmd17_ita_reg.
2377  dear_slot );
2378  /* adjust pointer position */
2379  buf_pos += ( hweight64( DEAR_REGS_MASK ) << 3 );
2380  }
2381 
2382  _papi_hwi_dispatch_profile( ESI, ( caddr_t ) pc, ( long long ) 0,
2383  count );
2384  overflow_vector ^= ( unsigned long ) 1 << reg_num;
2385  }
2386  /* move to next entry */
2387  buf_pos += entry_size;
2388  } /* end of if */
2389  return ( PAPI_OK );
2390 }
2391 
2392 static int
2394 {
2395  ( void ) thread; /*unused */
2396  pfmw_smpl_hdr_t *hdr;
2397  pfmw_smpl_entry_t *ent;
2398  unsigned long buf_pos;
2399  unsigned long entry_size;
2400  int ret, reg_num, count, pos;
2401  unsigned int i, EventCode = 0, eventindex, native_index = 0;
2402  ia64_control_state_t *this_state;
2403  pfm_ita2_pmd_reg_t *reg;
2404  unsigned long overflow_vector, pc;
2405 
2406 
2407  if ( ( ESI->state & PAPI_PROFILING ) == 0 )
2408  return ( PAPI_EBUG );
2409 
2410  this_state = ( ia64_control_state_t * ) ( ESI->ctl_state );
2411  hdr = ( pfmw_smpl_hdr_t * ) ( this_state->smpl_vaddr );
2412 
2413  entry_size = sizeof ( pfmw_smpl_entry_t );
2414 
2415  /*
2416  * walk through all the entries recorded in the buffer
2417  */
2418  buf_pos = ( unsigned long ) ( hdr + 1 );
2419  for ( i = 0; i < hdr->hdr_count; i++ ) {
2420  ret = 0;
2421  ent = ( pfmw_smpl_entry_t * ) buf_pos;
2422  /* PFM30 only one PMD overflows in each sample */
2423  overflow_vector = 1 << ent->ovfl_pmd;
2424 
2425  SUBDBG( "Entry %d PID:%d CPU:%d ovfl_vector:0x%lx IIP:0x%016lx\n",
2426  i, ent->pid, ent->cpu, overflow_vector, ent->ip );
2427 
2428  while ( overflow_vector ) {
2429  reg_num = ffs( overflow_vector ) - 1;
2430  /* find the event code */
2431  for ( count = 0; count < ESI->profile.event_counter; count++ ) {
2432  eventindex = ESI->profile.EventIndex[count];
2433  pos = ESI->EventInfoArray[eventindex].pos[0];
2434  if ( pos + PMU_FIRST_COUNTER == reg_num ) {
2435  EventCode = ESI->profile.EventCode[count];
2436  native_index =
2437  ESI->NativeInfoArray[pos].
2438  ni_event & PAPI_NATIVE_AND_MASK;
2439  break;
2440  }
2441  }
2442  /* something is wrong */
2443  if ( count == ESI->profile.event_counter ) {
2444  PAPIERROR
2445  ( "wrong count: %d vs. ESI->profile.event_counter %d\n",
2446  count, ESI->profile.event_counter );
2447  return ( PAPI_EBUG );
2448  }
2449 
2450  /* print entry header */
2451  pc = ent->ip;
2452  if ( pfm_ita2_is_dear( native_index ) ) {
2453  reg = ( pfm_ita2_pmd_reg_t * ) ( ent + 1 );
2454  reg++;
2455  reg++;
2456  pc = ( ( reg->pmd17_ita2_reg.dear_iaddr +
2457  reg->pmd17_ita2_reg.dear_bn ) << 4 )
2458  | reg->pmd17_ita2_reg.dear_slot;
2459 
2460  /* adjust pointer position */
2461  buf_pos += ( hweight64( DEAR_REGS_MASK ) << 3 );
2462  }
2463 
2464  _papi_hwi_dispatch_profile( ESI, ( caddr_t ) pc, ( long long ) 0,
2465  count );
2466  overflow_vector ^= ( unsigned long ) 1 << reg_num;
2467  }
2468  /* move to next entry */
2469  buf_pos += entry_size;
2470  } /* end of if */
2471  return ( PAPI_OK );
2472 }
2473 
2474 static int
2476 {
2477  ( void ) thread; /*unused */
2478  pfmw_smpl_hdr_t *hdr;
2479  pfmw_smpl_entry_t *ent;
2480  unsigned long buf_pos;
2481  unsigned long entry_size;
2482  int ret, reg_num, count, pos;
2483  unsigned int i, EventCode = 0, eventindex, native_index = 0;
2484  ia64_control_state_t *this_state;
2485  pfm_mont_pmd_reg_t *reg;
2486  unsigned long overflow_vector, pc;
2487  unsigned int umask;
2488 
2489 
2490  if ( ( ESI->state & PAPI_PROFILING ) == 0 )
2491  return ( PAPI_EBUG );
2492 
2493  this_state = ( ia64_control_state_t * ) ESI->ctl_state;
2494  hdr = ( pfmw_smpl_hdr_t * ) this_state->smpl_vaddr;
2495 
2496  entry_size = sizeof ( pfmw_smpl_entry_t );
2497 
2498  /*
2499  * walk through all the entries recorded in the buffer
2500  */
2501  buf_pos = ( unsigned long ) ( hdr + 1 );
2502  for ( i = 0; i < hdr->hdr_count; i++ ) {
2503  ret = 0;
2504  ent = ( pfmw_smpl_entry_t * ) buf_pos;
2505  /* PFM30 only one PMD overflows in each sample */
2506  overflow_vector = 1 << ent->ovfl_pmd;
2507 
2508  SUBDBG( "Entry %d PID:%d CPU:%d ovfl_vector:0x%lx IIP:0x%016lx\n",
2509  i, ent->pid, ent->cpu, overflow_vector, ent->ip );
2510 
2511  while ( overflow_vector ) {
2512  reg_num = ffs( overflow_vector ) - 1;
2513  /* find the event code */
2514  for ( count = 0; count < ESI->profile.event_counter; count++ ) {
2515  eventindex = ESI->profile.EventIndex[count];
2516  pos = ESI->EventInfoArray[eventindex].pos[0];
2517  if ( pos + PMU_FIRST_COUNTER == reg_num ) {
2518  EventCode = ESI->profile.EventCode[count];
2520  ( ESI->NativeInfoArray[pos].ni_event, &native_index,
2521  &umask ) != PAPI_OK )
2522  return ( PAPI_ENOEVNT );
2523  break;
2524  }
2525  }
2526  /* something is wrong */
2527  if ( count == ESI->profile.event_counter ) {
2528  PAPIERROR
2529  ( "wrong count: %d vs. ESI->profile.event_counter %d\n",
2530  count, ESI->profile.event_counter );
2531  return ( PAPI_EBUG );
2532  }
2533 
2534  /* print entry header */
2535  pc = ent->ip;
2536  if ( pfm_mont_is_dear( native_index ) ) {
2537  reg = ( pfm_mont_pmd_reg_t * ) ( ent + 1 );
2538  reg++;
2539  reg++;
2540  pc = ( ( reg->pmd36_mont_reg.dear_iaddr +
2541  reg->pmd36_mont_reg.dear_bn ) << 4 )
2542  | reg->pmd36_mont_reg.dear_slot;
2543  /* adjust pointer position */
2544  buf_pos += ( hweight64( DEAR_REGS_MASK ) << 3 );
2545  }
2546 
2547  _papi_hwi_dispatch_profile( ESI, ( caddr_t ) pc, ( long long ) 0,
2548  count );
2549  overflow_vector ^= ( unsigned long ) 1 << reg_num;
2550  }
2551  /* move to next entry */
2552  buf_pos += entry_size;
2553  } /* end of if */
2554  return ( PAPI_OK );
2555 }
2556 
2557 static int
2559 {
2560  switch ( _perfmon2_pfm_pmu_type ) {
2561  case PFMLIB_ITANIUM_PMU:
2562  return ( ia64_ita_process_profile_buffer( thread, ESI ) );
2563  break;
2564  case PFMLIB_ITANIUM2_PMU:
2565  return ( ia64_ita2_process_profile_buffer( thread, ESI ) );
2566  break;
2567  case PFMLIB_MONTECITO_PMU:
2568  return ( ia64_mont_process_profile_buffer( thread, ESI ) );
2569  break;
2570  default:
2571  PAPIERROR( "PMU type %d is not supported by this component",
2572  _perfmon2_pfm_pmu_type );
2573  return ( PAPI_EBUG );
2574  }
2575 }
2576 
2577 static void
2579 {
2580  ( void ) n; /*unused */
2581  _papi_hwi_context_t ctx;
2583  caddr_t address;
2584  int cidx = _ia64_vector.cmp_info.CmpIdx;
2585 
2586 #if defined(DEBUG)
2587  if ( thread == NULL ) {
2588  PAPIERROR( "thread == NULL in _papi_hwd_dispatch_timer!" );
2589  return;
2590  }
2591 #endif
2592 
2593  ctx.si = info;
2594  ctx.ucontext = sc;
2595  address = GET_OVERFLOW_ADDRESS( ( ctx ) );
2596 
2597  if ( ( thread == NULL ) || ( thread->running_eventset[cidx] == NULL ) ) {
2598  SUBDBG( "%p, %p\n", thread, thread->running_eventset[cidx] );
2599  return;
2600  }
2601 
2602  if ( thread->running_eventset[cidx]->overflow.
2604  _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address, NULL, 0,
2605  0, &thread, cidx );
2606  return;
2607  }
2608 
2609  pfm_msg_t msg;
2610  int ret, fd;
2611  fd = info->si_fd;
2612  retry:
2613  ret = read( fd, &msg, sizeof ( msg ) );
2614  if ( ret == -1 ) {
2615  if ( errno == EINTR ) {
2616  SUBDBG( "read(%d) interrupted, retrying\n", fd );
2617  goto retry;
2618  } else {
2619  PAPIERROR( "read(%d): errno %d", fd, errno );
2620  }
2621  } else if ( ret != sizeof ( msg ) ) {
2622  PAPIERROR( "read(%d): short %d vs. %d bytes", fd, ret, sizeof ( msg ) );
2623  ret = -1;
2624  }
2625 #if defined(HAVE_PFM_MSG_TYPE)
2626  if ( msg.type == PFM_MSG_END ) {
2627  SUBDBG( "PFM_MSG_END\n" );
2628  return;
2629  }
2630  if ( msg.type != PFM_MSG_OVFL ) {
2631  PAPIERROR( "unexpected msg type %d", msg.type );
2632  return;
2633  }
2634 #else
2635  if ( msg.pfm_gen_msg.msg_type == PFM_MSG_END ) {
2636  SUBDBG( "PFM_MSG_END\n" );
2637  return;
2638  }
2639  if ( msg.pfm_gen_msg.msg_type != PFM_MSG_OVFL ) {
2640  PAPIERROR( "unexpected msg type %d", msg.pfm_gen_msg.msg_type );
2641  return;
2642  }
2643 #endif
2644  if ( ret != -1 ) {
2645  if ( ( thread->running_eventset[cidx]->state & PAPI_PROFILING ) &&
2646  !( thread->running_eventset[cidx]->profile.
2649  thread->running_eventset[cidx] );
2650  else
2651  _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address,
2652  NULL,
2653  msg.pfm_ovfl_msg.
2654  msg_ovfl_pmds[0] >>
2655  PMU_FIRST_COUNTER, 0,
2656  &thread, cidx );
2657  }
2658  if ( pfmw_perfmonctl( 0, fd, PFM_RESTART, 0, 0 ) == -1 ) {
2659  PAPIERROR( "perfmonctl(PFM_RESTART) errno %d, %s", errno,
2660  strerror( errno ) );
2661  return;
2662  }
2663 }
2664 
2665 void
2666 _ia64_dispatch_timer( int signal, hwd_siginfo_t * info, void *context )
2667 {
2668  ia64_dispatch_sigprof( signal, info, context );
2669 }
2670 
2671 static int
2672 set_notify( EventSetInfo_t * ESI, int index, int value )
2673 {
2674  int *pos, count, i;
2675  unsigned int hwcntr;
2676  pfmw_param_t *pevt =
2677  &( ( ( ia64_control_state_t * ) ESI->ctl_state )->evt );
2678 
2679  pos = ESI->EventInfoArray[index].pos;
2680  count = 0;
2681  while ( pos[count] != -1 && count < _ia64_vector.cmp_info.num_cntrs ) {
2682  hwcntr = pos[count] + PMU_FIRST_COUNTER;
2683  for ( i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++ ) {
2684  if ( PFMW_PEVT_PFPPC_REG_NUM( pevt, i ) == hwcntr ) {
2685  SUBDBG( "Found hw counter %d in %d, flags %d\n", hwcntr, i,
2686  value );
2687  PFMW_PEVT_PFPPC_REG_FLG( pevt, i ) = value;
2688 /*
2689  #ifdef PFM30
2690  if (value)
2691  pevt->pc[i].reg_reset_pmds[0] = 1UL << pevt->pc[i].reg_num;
2692  else
2693  pevt->pc[i].reg_reset_pmds[0] = 0;
2694  #endif
2695 */
2696  break;
2697  }
2698  }
2699  count++;
2700  }
2701  return ( PAPI_OK );
2702 }
2703 
2704 int
2706 {
2707  int cidx = _ia64_vector.cmp_info.CmpIdx;
2708 
2709  pfmw_stop( thread->context[cidx] );
2710  return ( ia64_process_profile_buffer( thread, ESI ) );
2711 }
2712 
2713 
2714 int
2715 _ia64_set_profile( EventSetInfo_t * ESI, int EventIndex, int threshold )
2716 {
2717  int cidx = _ia64_vector.cmp_info.CmpIdx;
2718  hwd_control_state_t *this_state = ESI->ctl_state;
2719  hwd_context_t *ctx = ESI->master->context[cidx];
2720  int ret;
2721 
2722  ret = _ia64_vector.set_overflow( ESI, EventIndex, threshold );
2723  if ( ret != PAPI_OK )
2724  return ret;
2725  ret = pfmw_destroy_context( ctx );
2726  if ( ret != PAPI_OK )
2727  return ret;
2728  if ( threshold == 0 )
2729  ret = pfmw_create_context( ctx );
2730  else
2731  ret =
2732  pfmw_recreate_context( ESI, ctx, &this_state->smpl_vaddr,
2733  EventIndex );
2734 
2735 //#warning "This should be handled in the high level layers"
2736  ESI->state ^= PAPI_OVERFLOWING;
2738 
2739  return ( ret );
2740 }
2741 
2742 int
2743 _ia64_set_overflow( EventSetInfo_t * ESI, int EventIndex, int threshold )
2744 {
2745  hwd_control_state_t *this_state = ESI->ctl_state;
2746  int j, retval = PAPI_OK, *pos;
2747  int cidx = _ia64_vector.cmp_info.CmpIdx;
2748 
2749  pos = ESI->EventInfoArray[EventIndex].pos;
2750  j = pos[0];
2751  SUBDBG( "Hardware counter %d used in overflow, threshold %d\n", j,
2752  threshold );
2753 
2754  if ( threshold == 0 ) {
2755  /* Remove the signal handler */
2756 
2757  retval = _papi_hwi_stop_signal( _ia64_vector.cmp_info.hardware_intr_sig );
2758  if ( retval != PAPI_OK )
2759  return ( retval );
2760 
2761  /* Remove the overflow notifier on the proper event. */
2762 
2763  set_notify( ESI, EventIndex, 0 );
2764 
2765  this_state->pd[j].reg_value = 0;
2766  this_state->pd[j].reg_long_reset = 0;
2767  this_state->pd[j].reg_short_reset = 0;
2768  } else {
2769  retval =
2771  cidx );
2772  if ( retval != PAPI_OK )
2773  return ( retval );
2774 
2775  /* Set the overflow notifier on the proper event. Remember that selector */
2776 
2777  set_notify( ESI, EventIndex, PFM_REGFL_OVFL_NOTIFY );
2778 
2779  this_state->pd[j].reg_value =
2780  ( ~0UL ) - ( unsigned long ) threshold + 1;
2781  this_state->pd[j].reg_short_reset =
2782  ( ~0UL ) - ( unsigned long ) threshold + 1;
2783  this_state->pd[j].reg_long_reset =
2784  ( ~0UL ) - ( unsigned long ) threshold + 1;
2785 
2786  }
2787  return ( retval );
2788 }
2789 
2790 int
2791 _ia64_ntv_code_to_name( unsigned int EventCode, char *ntv_name, int len )
2792 {
2793  if ( _perfmon2_pfm_pmu_type == PFMLIB_MONTECITO_PMU )
2794  return ( _papi_pfm_ntv_code_to_name( EventCode, ntv_name, len ) );
2795  else {
2796  char name[PAPI_MAX_STR_LEN];
2797  int ret = 0;
2798 
2799  pfmw_get_event_name( name, EventCode ^ PAPI_NATIVE_MASK );
2800 
2801  if ( ret != PAPI_OK )
2802  return ( PAPI_ENOEVNT );
2803 
2804  strncpy( ntv_name, name, len );
2805  return ( PAPI_OK );
2806  }
2807 }
2808 
2809 int
2810 _ia64_ntv_code_to_descr( unsigned int EventCode, char *ntv_descr, int len )
2811 {
2812  if ( _perfmon2_pfm_pmu_type == PFMLIB_MONTECITO_PMU )
2813  return ( _papi_pfm_ntv_code_to_descr( EventCode, ntv_descr, len ) );
2814  else {
2815 #if defined(HAVE_PFM_GET_EVENT_DESCRIPTION)
2816  pfmw_get_event_description( EventCode ^ PAPI_NATIVE_MASK, ntv_descr,
2817  len );
2818  return ( PAPI_OK );
2819 #else
2820  return ( _ia64_ntv_code_to_name( EventCode, ntv_descr, len ) );
2821 #endif
2822  }
2823 }
2824 
2825 static int
2826 _ia64_modify_event( unsigned int event, int modifier )
2827 {
2828  switch ( modifier ) {
2829  case PAPI_NTV_ENUM_IARR:
2830  return ( pfmw_support_iarr( event ) );
2831  case PAPI_NTV_ENUM_DARR:
2832  return ( pfmw_support_darr( event ) );
2833  case PAPI_NTV_ENUM_OPCM:
2834  return ( pfmw_support_opcm( event ) );
2835  case PAPI_NTV_ENUM_DEAR:
2836  return ( pfmw_is_dear( event ) );
2837  case PAPI_NTV_ENUM_IEAR:
2838  return ( pfmw_is_iear( event ) );
2839  default:
2840  return ( 1 );
2841  }
2842 }
2843 
2844 int
2845 _ia64_ntv_enum_events( unsigned int *EventCode, int modifier )
2846 {
2847  if ( _perfmon2_pfm_pmu_type == PFMLIB_MONTECITO_PMU )
2848  return ( _papi_pfm_ntv_enum_events( EventCode, modifier ) );
2849  else {
2850  int index = *EventCode & PAPI_NATIVE_AND_MASK;
2851 
2852  if ( modifier == PAPI_ENUM_FIRST ) {
2853  *EventCode = PAPI_NATIVE_MASK;
2854  return ( PAPI_OK );
2855  }
2856 
2857  while ( index++ < _ia64_vector.cmp_info.num_native_events - 1 ) {
2858  *EventCode += 1;
2859  if ( _ia64_modify_event
2860  ( ( *EventCode ^ PAPI_NATIVE_MASK ), modifier ) )
2861  return ( PAPI_OK );
2862  }
2863  return ( PAPI_ENOEVNT );
2864  }
2865 }
2866 
2867 int
2869 {
2870  pfmw_param_t *evt;
2871  pfmw_ita1_param_t *param;
2873 
2874  ptr = ( ia64_control_state_t * ) this_state;
2875  evt = &( ptr->evt );
2876 
2877  param = &( ptr->ita_lib_param.ita_param );
2878  memset( evt, 0, sizeof ( pfmw_param_t ) );
2879  memset( param, 0, sizeof ( pfmw_ita1_param_t ) );
2880 
2881  _ia64_ita_set_domain( this_state, _ia64_vector.cmp_info.default_domain );
2882 /* set library parameter pointer */
2883 
2884  return ( PAPI_OK );
2885 }
2886 
2887 int
2889 {
2890  pfmw_param_t *evt;
2891  pfmw_ita2_param_t *param;
2893 
2894  ptr = ( ia64_control_state_t * ) this_state;
2895  evt = &( ptr->evt );
2896 
2897  param = &( ptr->ita_lib_param.ita2_param );
2898  memset( evt, 0, sizeof ( pfmw_param_t ) );
2899  memset( param, 0, sizeof ( pfmw_ita2_param_t ) );
2900 
2901  _ia64_ita2_set_domain( this_state, _ia64_vector.cmp_info.default_domain );
2902 /* set library parameter pointer */
2903  evt->mod_inp = &( param->ita2_input_param );
2904  evt->mod_outp = &( param->ita2_output_param );
2905 
2906  return ( PAPI_OK );
2907 }
2908 
2909 int
2911 {
2912  pfmw_param_t *evt;
2913  pfmw_mont_param_t *param;
2915 
2916  ptr = ( ia64_control_state_t * ) this_state;
2917  evt = &( ptr->evt );
2918 
2919  param = &( ptr->ita_lib_param.mont_param );
2920  memset( evt, 0, sizeof ( pfmw_param_t ) );
2921  memset( param, 0, sizeof ( pfmw_mont_param_t ) );
2922 
2923  _ia64_mont_set_domain( this_state, _ia64_vector.cmp_info.default_domain );
2924 /* set library parameter pointer */
2925  evt->mod_inp = &( param->mont_input_param );
2926  evt->mod_outp = &( param->mont_output_param );
2927 
2928  return ( PAPI_OK );
2929 }
2930 
2931 int
2933 {
2934  switch ( _perfmon2_pfm_pmu_type ) {
2935  case PFMLIB_ITANIUM_PMU:
2936  return ( _ia64_ita_init_control_state( this_state ) );
2937  break;
2938  case PFMLIB_ITANIUM2_PMU:
2939  return ( _ia64_ita2_init_control_state( this_state ) );
2940  break;
2941  case PFMLIB_MONTECITO_PMU:
2942  return ( _ia64_mont_init_control_state( this_state ) );
2943  break;
2944  default:
2945  PAPIERROR( "PMU type %d is not supported by this component",
2946  _perfmon2_pfm_pmu_type );
2947  return ( PAPI_EBUG );
2948  }
2949 }
2950 
2951 void
2953  NativeInfo_t * nativeInfo )
2954 {
2955  ( void ) this_state; /*unused */
2956  ( void ) nativeInfo; /*unused */
2957  return;
2958 }
2959 
2960 int
2962  NativeInfo_t * native, int count,
2963  hwd_context_t * zero )
2964 {
2965  ( void ) zero; /*unused */
2966  int org_cnt;
2967  pfmw_param_t *evt = &this_state->evt;
2968  pfmw_param_t copy_evt;
2969  unsigned int i, j, event, umask, EventCode;
2970  pfmlib_event_t gete;
2971  char name[128];
2972 
2973  if ( count == 0 ) {
2974  for ( i = 0; i < ( unsigned int ) _ia64_vector.cmp_info.num_cntrs; i++ )
2975  PFMW_PEVT_EVENT( evt, i ) = 0;
2976  PFMW_PEVT_EVTCOUNT( evt ) = 0;
2977  memset( PFMW_PEVT_PFPPC( evt ), 0, sizeof ( PFMW_PEVT_PFPPC( evt ) ) );
2978  memset( &evt->inp.pfp_unavail_pmcs, 0, sizeof ( pfmlib_regmask_t ) );
2979  return ( PAPI_OK );
2980  }
2981 
2982 /* save the old data */
2983  org_cnt = PFMW_PEVT_EVTCOUNT( evt );
2984 
2985  memcpy( &copy_evt, evt, sizeof ( pfmw_param_t ) );
2986 
2987  for ( i = 0; i < ( unsigned int ) _ia64_vector.cmp_info.num_cntrs; i++ )
2988  PFMW_PEVT_EVENT( evt, i ) = 0;
2989  PFMW_PEVT_EVTCOUNT( evt ) = 0;
2990  memset( PFMW_PEVT_PFPPC( evt ), 0, sizeof ( PFMW_PEVT_PFPPC( evt ) ) );
2991  memset( &evt->inp.pfp_unavail_pmcs, 0, sizeof ( pfmlib_regmask_t ) );
2992 
2993  SUBDBG( " original count is %d\n", org_cnt );
2994 
2995 /* add new native events to the evt structure */
2996  for ( i = 0; i < ( unsigned int ) count; i++ ) {
2997  memset( &gete, 0, sizeof ( gete ) );
2998  EventCode = native[i].ni_event;
2999  _papi_pfm_ntv_code_to_name( EventCode, name, 128 );
3000  if ( _pfm_decode_native_event( EventCode, &event, &umask ) != PAPI_OK )
3001  return ( PAPI_ENOEVNT );
3002 
3003  SUBDBG( " evtcode=%#x evtindex=%d name: %s\n", EventCode, event,
3004  name );
3005 
3006  PFMW_PEVT_EVENT( evt, i ) = event;
3007  evt->inp.pfp_events[i].num_masks = 0;
3008  gete.event = event;
3009  gete.num_masks = prepare_umask( umask, gete.unit_masks );
3010  if ( gete.num_masks ) {
3011  evt->inp.pfp_events[i].num_masks = gete.num_masks;
3012  for ( j = 0; j < gete.num_masks; j++ )
3013  evt->inp.pfp_events[i].unit_masks[j] = gete.unit_masks[j];
3014  }
3015  }
3016  PFMW_PEVT_EVTCOUNT( evt ) = count;
3017  /* Recalcuate the pfmlib_param_t structure, may also signal conflict */
3018  if ( pfmw_dispatch_events( evt ) ) {
3019  SUBDBG( "pfmw_dispatch_events fail\n" );
3020  /* recover the old data */
3021  PFMW_PEVT_EVTCOUNT( evt ) = org_cnt;
3022  /*for (i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++)
3023  PFMW_PEVT_EVENT(evt,i) = events[i];
3024  */
3025  memcpy( evt, &copy_evt, sizeof ( pfmw_param_t ) );
3026  return ( PAPI_ECNFLCT );
3027  }
3028  SUBDBG( "event_count=%d\n", PFMW_PEVT_EVTCOUNT( evt ) );
3029 
3030  for ( i = 0; i < PFMW_PEVT_EVTCOUNT( evt ); i++ ) {
3031  native[i].ni_position = PFMW_PEVT_PFPPC_REG_NUM( evt, i )
3033  SUBDBG( "event_code is %d, reg_num is %d\n",
3034  native[i].ni_event & PAPI_NATIVE_AND_MASK,
3035  native[i].ni_position );
3036  }
3037 
3038  return ( PAPI_OK );
3039 }
3040 
3041 int
3043  NativeInfo_t * native, int count,
3044  hwd_context_t * zero )
3045 {
3046  ( void ) zero; /*unused */
3047  int index, org_cnt;
3048  unsigned int i;
3049  pfmw_param_t *evt = &this_state->evt;
3050  pfmw_param_t copy_evt;
3051 
3052  if ( count == 0 ) {
3053  for ( i = 0; i < ( unsigned int ) _ia64_vector.cmp_info.num_cntrs; i++ )
3054  PFMW_PEVT_EVENT( evt, i ) = 0;
3055  PFMW_PEVT_EVTCOUNT( evt ) = 0;
3056  memset( PFMW_PEVT_PFPPC( evt ), 0, sizeof ( PFMW_PEVT_PFPPC( evt ) ) );
3057  memset( &evt->inp.pfp_unavail_pmcs, 0, sizeof ( pfmlib_regmask_t ) );
3058  return ( PAPI_OK );
3059  }
3060 
3061 /* save the old data */
3062  org_cnt = PFMW_PEVT_EVTCOUNT( evt );
3063 
3064  memcpy( &copy_evt, evt, sizeof ( pfmw_param_t ) );
3065  for ( i = 0; i < ( unsigned int ) _ia64_vector.cmp_info.num_cntrs; i++ )
3066  PFMW_PEVT_EVENT( evt, i ) = 0;
3067  PFMW_PEVT_EVTCOUNT( evt ) = 0;
3068  memset( PFMW_PEVT_PFPPC( evt ), 0, sizeof ( PFMW_PEVT_PFPPC( evt ) ) );
3069  memset( &evt->inp.pfp_unavail_pmcs, 0, sizeof ( pfmlib_regmask_t ) );
3070 
3071  SUBDBG( " original count is %d\n", org_cnt );
3072 
3073 /* add new native events to the evt structure */
3074  for ( i = 0; i < ( unsigned int ) count; i++ ) {
3075  index = native[i].ni_event & PAPI_NATIVE_AND_MASK;
3076  PFMW_PEVT_EVENT( evt, i ) = index;
3077  }
3078  PFMW_PEVT_EVTCOUNT( evt ) = count;
3079  /* Recalcuate the pfmlib_param_t structure, may also signal conflict */
3080  if ( pfmw_dispatch_events( evt ) ) {
3081  SUBDBG( "pfmw_dispatch_events fail\n" );
3082  /* recover the old data */
3083  PFMW_PEVT_EVTCOUNT( evt ) = org_cnt;
3084  /*for (i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++)
3085  PFMW_PEVT_EVENT(evt,i) = events[i];
3086  */
3087  memcpy( evt, &copy_evt, sizeof ( pfmw_param_t ) );
3088  return ( PAPI_ECNFLCT );
3089  }
3090  SUBDBG( "event_count=%d\n", PFMW_PEVT_EVTCOUNT( evt ) );
3091 
3092  for ( i = 0; i < PFMW_PEVT_EVTCOUNT( evt ); i++ ) {
3093  native[i].ni_position = PFMW_PEVT_PFPPC_REG_NUM( evt, i )
3095  SUBDBG( "event_code is %d, reg_num is %d\n",
3096  native[i].ni_event & PAPI_NATIVE_AND_MASK,
3097  native[i].ni_position );
3098  }
3099 
3100  return ( PAPI_OK );
3101 }
3102 
3103 int
3105  NativeInfo_t * native, int count,
3106  hwd_context_t * zero )
3107 {
3108  switch ( _perfmon2_pfm_pmu_type ) {
3109  case PFMLIB_ITANIUM_PMU:
3111  ( this_state, native, count, zero ) );
3112  break;
3113  case PFMLIB_ITANIUM2_PMU:
3115  ( this_state, native, count, zero ) );
3116  break;
3117  case PFMLIB_MONTECITO_PMU:
3119  ( this_state, native, count, zero ) );
3120  break;
3121  default:
3122  PAPIERROR( "PMU type %d is not supported by this component",
3123  _perfmon2_pfm_pmu_type );
3124  return ( PAPI_EBUG );
3125  }
3126 }
3127 
3128 papi_vector_t _ia64_vector = {
3129  .cmp_info = {
3130  .name = "perfmon-ia64.c",
3131  .version = "5.0",
3132 
3133  /* default component information (unspecified values initialized to 0) */
3134  .default_domain = PAPI_DOM_USER,
3135  .available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL,
3136  .default_granularity = PAPI_GRN_THR,
3137  .available_granularities = PAPI_GRN_THR,
3138  .hardware_intr_sig = PAPI_INT_SIGNAL,
3139  .hardware_intr = 1,
3140  /* component specific cmp_info initializations */
3141  .fast_real_timer = 1,
3142  .fast_virtual_timer = 0,
3143  .attach = 0,
3144  .attach_must_ptrace = 0,
3145  .kernel_profile = 1,
3146  .cntr_umasks = 1;
3147  },
3148 
3149  /* sizes of framework-opaque component-private structures */
3150  .size = {
3151  .context = sizeof ( ia64_context_t ),
3152  .control_state = sizeof ( ia64_control_state_t ),
3153  .reg_value = sizeof ( ia64_register_t ),
3154  .reg_alloc = sizeof ( ia64_reg_alloc_t ),
3155  }
3156  ,
3157 
3158  /* function pointers in this component */
3159  .init_control_state = _ia64_init_control_state,
3160  .start = _ia64_start,
3161  .stop = _ia64_stop,
3162  .read = _ia64_read,
3163  .shutdown_thread = _ia64_shutdown,
3164  .ctl = _ia64_ctl,
3165  .update_control_state = _ia64_update_control_state,
3166  .set_domain = _ia64_set_domain,
3167  .reset = _ia64_reset,
3168  .set_overflow = _ia64_set_overflow,
3169  .set_profile = _ia64_set_profile,
3170  .stop_profiling = _ia64_stop_profiling,
3171  .init_component = _ia64_init_component,
3172  .dispatch_timer = _ia64_dispatch_timer,
3173  .init_thread = _ia64_init,
3174 
3175  .ntv_enum_events = _ia64_ntv_enum_events,
3176  .ntv_code_to_name = _ia64_ntv_code_to_name,
3177  .ntv_code_to_descr = _ia64_ntv_code_to_descr,
3178 
3179 };
pfmlib_input_param_t inp
Definition: perfmon-ia64.h:73
#define PAPI_TLB_TL
Definition: fpapi.h:157
char name[PAPI_MAX_STR_LEN]
Definition: papi.h:625
int _ia64_ntv_enum_events(unsigned int *EventCode, int modifier)
sprintf(splash[splash_line++],"\tIozone: Performance Test of File I/O\n")
pfmw_ita_param_t ita_lib_param
Definition: perfmon-ia64.h:114
ssize_t read(int fd, void *buf, size_t count)
Definition: appio.c:225
memset(eventId, 0, size)
#define PAPI_TLB_IM
Definition: fpapi.h:156
int _ia64_stop_profiling(ThreadInfo_t *thread, EventSetInfo_t *ESI)
int _ia64_mont_update_control_state(hwd_control_state_t *this_state, NativeInfo_t *native, int count, hwd_context_t *zero)
static int prepare_umask(unsigned int foo, unsigned int *values)
#define PAPI_NATIVE_MASK
#define PAPI_L2_TCM
Definition: fpapi.h:142
#define DERIVED_SUB
Definition: papi_internal.h:74
_papi_int_inherit_t inherit
int errno
#define PAPI_CA_SNP
Definition: fpapi.h:144
static int pfmw_recreate_context(EventSetInfo_t *ESI, hwd_context_t *thr_ctx, void **smpl_vaddr, int EventIndex)
Definition: perfmon-ia64.c:281
#define PAPI_LD_INS
Definition: fpapi.h:188
pfmlib_output_param_t outp
Definition: perfmon-ia64.h:74
int close(int fd)
Definition: appio.c:175
double f(double a)
Definition: cpi.c:23
#define PAPI_ENOMEM
Definition: fpapi.h:107
#define PAPI_GRN_SYS_CPU
Definition: fpapi.h:72
static itanium_preset_search_t ia1_preset_search_map[]
#define PFMON_MONT_MAX_IBRS
Definition: perfmon-ia64.c:60
#define PAPI_L3_TCR
Definition: fpapi.h:228
#define PAPI_ENOIMPL
Definition: fpapi.h:124
static void pfmw_stop(hwd_context_t *ctx)
Definition: perfmon-ia64.c:93
int _ia64_ctl(hwd_context_t *zero, int code, _papi_int_option_t *option)
static void pfmw_start(hwd_context_t *ctx)
Definition: perfmon-ia64.c:87
#define PAPI_L2_TCW
Definition: fpapi.h:230
long long flags
Definition: iozone.c:12330
#define PAPI_DEF_ITIMER_NS
Definition: papi.h:453
#define PAPI_NULL
Definition: fpapi.h:13
#define PAPI_L1_ICA
Definition: fpapi.h:211
EventSetInfo_t * ESI
#define MONT_DEAR_REGS_MASK
Definition: perfmon-ia64.h:168
#define papi_free(a)
Definition: papi_memory.h:35
#define PAPI_L1_ICM
Definition: fpapi.h:136
unsigned int event_code
Definition: papi_preset.h:14
int _ia64_init(hwd_context_t *zero)
#define PFMW_PEVT_DFLPLM(evt)
Definition: perfmon-ia64.c:50
static int set_pmds_to_write(EventSetInfo_t *ESI, int index, unsigned long value)
Definition: perfmon-ia64.c:253
static void pfmw_get_event_description(unsigned int idx, char *dest, int len)
Definition: perfmon-ia64.c:393
#define PAPI_INSTR_ADDRESS
Definition: papi.h:451
static int ia64_process_profile_buffer(ThreadInfo_t *thread, EventSetInfo_t *ESI)
int _ia64_mont_set_domain(hwd_control_state_t *this_state, int domain)
#define PAPI_MAX_STR_LEN
Definition: fpapi.h:43
#define PAPI_RES_STL
Definition: fpapi.h:192
int _papi_pfm_ntv_code_to_descr(unsigned int EventCode, char *ntv_descr, int len)
_papi_int_addr_range_t address_range
#define papi_malloc(a)
Definition: papi_memory.h:34
char operation[MAX_COUNTERS *5]
Definition: perfmon-ia64.h:136
int _ia64_shutdown(hwd_context_t *ctx)
int _ia64_ita_init_control_state(hwd_control_state_t *this_state)
#define PAPI_L1_TCM
Definition: fpapi.h:141
static char * search_cpu_info(FILE *f, char *search_str, char *line)
#define PAPI_ENOEVNT
Definition: fpapi.h:112
int ia64_reg_alloc_t
Definition: perfmon-ia64.h:63
#define PAPI_TOT_INS
Definition: fpapi.h:185
int ns
Definition: iozone.c:20358
#define PAPI_DATA_ADDRESS
Definition: papi.h:450
#define PAPI_L3_STM
Definition: fpapi.h:150
int _ia64_init_component(int cidx)
int fd
Definition: iozone.c:1291
static int _papi_pfm_ntv_name_to_code(char *name, unsigned int *event_code)
static int pfmw_get_num_counters(int *num)
pfm_default_smpl_entry_t pfmw_smpl_entry_t
Definition: perfmon-ia64.c:84
static int _perfmon2_pfm_pmu_type
Definition: perfmon.c:50
#define MAX_COUNTERS
Definition: perfctr-x86.h:8
static int pfmw_perfmonctl(pid_t tid, int fd, int cmd, void *arg, int narg)
Definition: perfmon-ia64.c:99
device[deviceId] domain[domainId] event
Definition: linux-cuda.c:306
static int set_irange(hwd_context_t *ctx, hwd_control_state_t *current_state, _papi_int_option_t *option)
Definition: perfmon-ia64.c:919
void _ia64_remove_native(hwd_control_state_t *this_state, NativeInfo_t *nativeInfo)
pfmw_ita1_param_t ita_param
Definition: perfmon-ia64.h:100
#define PAPI_L3_DCR
Definition: fpapi.h:204
int incr
Definition: fileop.c:82
#define PAPI_TLB_DM
Definition: fpapi.h:155
#define PFMON_ITA2_MAX_IBRS
Definition: perfmon-ia64.c:63
pfmlib_mont_input_param_t mont_input_param
Definition: perfmon-ia64.h:81
papi_vector_t _ia64_vector
return PAPI_OK
Definition: linux-nvml.c:458
int count
Definition: iozone.c:22422
#define PAPI_FP_OPS
Definition: fpapi.h:237
#define PAPI_L2_DCH
Definition: fpapi.h:198
static int ia64_ita_process_profile_buffer(ThreadInfo_t *thread, EventSetInfo_t *ESI)
static int install_drange(hwd_context_t *pctx, hwd_control_state_t *current_state)
Definition: perfmon-ia64.c:694
static int pfmw_create_context(hwd_context_t *thr_ctx)
Definition: perfmon-ia64.c:233
#define PAPI_LST_INS
Definition: fpapi.h:195
#define PAPI_GRN_SYS
Definition: fpapi.h:71
#define DERIVED_ADD
Definition: papi_internal.h:70
static pid_t mygettid(void)
Definition: darwin-common.h:11
static int preset
Definition: event_info.c:38
#define PAPI_L3_DCA
Definition: fpapi.h:201
#define PAPI_DOM_KERNEL
Definition: fpapi.h:22
#define PAPI_GRN_PROC
Definition: fpapi.h:69
void
Definition: iozone.c:18627
return PAPI_EINVAL
Definition: linux-nvml.c:408
#define PFMW_PEVT_PFPPC_REG_VAL(evt, idx)
Definition: perfmon-ia64.c:55
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
int _ia64_reset(hwd_context_t *ctx, hwd_control_state_t *machdep)
#define printf
Definition: papi_test.h:125
int _papi_pfm_ntv_enum_events(unsigned int *EventCode, int modifier)
#define PFMW_PEVT_PFPPC_REG_FLG(evt, idx)
Definition: perfmon-ia64.c:56
#define PAPI_OVERFLOWING
Definition: fpapi.h:33
void double value
Definition: iozone.c:18781
#define PAPI_L3_TCW
Definition: fpapi.h:231
#define PAPI_PROFILING
Definition: fpapi.h:34
#define PAPI_INHERIT
Definition: papi.h:456
#define PAPI_ECNFLCT
Definition: fpapi.h:113
char kernel_version[PAPI_MIN_STR_LEN]
Definition: papi.h:631
Return codes and api definitions.
void * mod_outp
Definition: perfmon-ia64.h:76
int _papi_pfm_ntv_code_to_name(unsigned int EventCode, char *ntv_name, int len)
#define PAPI_BR_INS
Definition: fpapi.h:190
#define PAPI_L1_ICR
Definition: fpapi.h:214
_papi_int_itimer_t itimer
#define PAPI_L3_TCH
Definition: fpapi.h:222
static itanium_preset_search_t ia3_preset_search_map[]
pfarg_reg_t pc[NUM_PMCS]
Definition: perfmon-ia64.h:72
long long ret
Definition: iozone.c:1346
#define PFMW_PEVT_PFPPD(evt)
Definition: perfmon-ia64.c:52
#define PAPI_L1_DCR
Definition: fpapi.h:202
static int pfmw_is_dear(unsigned int i)
Definition: perfmon-ia64.c:405
pfm_default_smpl_hdr_t pfmw_smpl_hdr_t
Definition: perfmon-ia64.c:83
#define PAPI_2MAX_STR_LEN
Definition: papi.h:464
static int pfmw_get_num_events(int *num)
#define PAPI_CA_INV
Definition: fpapi.h:147
unsigned int PAPI_NATIVE_UMASK_SHIFT
#define PAPI_L2_DCW
Definition: fpapi.h:206
static int pfmw_destroy_context(hwd_context_t *thr_ctx)
Definition: perfmon-ia64.c:106
#define PFMW_ARCH_REG_PMCVAL(reg)
Definition: perfmon-ia64.c:57
static int pfmw_is_iear(unsigned int i)
Definition: perfmon-ia64.c:425
int open(const char *pathname, int flags, mode_t mode)
Definition: appio.c:184
unsigned int PAPI_NATIVE_UMASK_MAX
unsigned int PAPI_NATIVE_EVENT_AND_MASK
int _papi_hwi_setup_all_presets(hwi_search_t *findem, int cidx)
Definition: papi_preset.c:37
int i
Definition: fileop.c:140
EventSetOverflowInfo_t overflow
#define PAPI_GRN_PROCG
Definition: fpapi.h:70
char buf[200]
Definition: iozone.c:19609
#define PAPI_OVERFLOW_HARDWARE
Definition: papi.h:410
#define PAPI_TOT_CYC
Definition: fpapi.h:194
PAPI_os_info_t _papi_os_info
Definition: aix.c:1210
int _linux_get_memory_info(PAPI_hw_info_t *hwinfo, int cpu_type)
Definition: linux-memory.c:912
#define PAPI_SR_INS
Definition: fpapi.h:189
struct _ThreadInfo * master
#define PFMW_PEVT_PFPPC(evt)
Definition: perfmon-ia64.c:51
#define PAPI_L2_DCM
Definition: fpapi.h:137
static int pid
#define PAPI_BR_PRC
Definition: fpapi.h:182
free(dummyfile[xx])
static int cidx
Definition: event_info.c:40
#define PAPI_L1_TCA
Definition: fpapi.h:223
#define PFMW_PEVT_EVENT(evt, idx)
Definition: perfmon-ia64.c:48
#define PAPI_ECMP
Definition: fpapi.h:109
static int round_requested_ns(int ns)
hwd_ucontext_t * ucontext
#define PAPI_L3_ICA
Definition: fpapi.h:213
void int num
Definition: iozone.c:22151
static int native
Definition: event_info.c:39
int pfmw_ita1_param_t
Definition: perfmon-ia64.h:93
#define PAPI_L3_ICH
Definition: fpapi.h:210
#define PAPI_L3_DCM
Definition: fpapi.h:139
hwd_context_t ** context
Definition: threads.h:28
pthread_attr_t foo
Definition: iozone.c:18592
int _ia64_ita_set_domain(hwd_control_state_t *this_state, int domain)
void * thread(void *arg)
Definition: kufrin.c:31
static int pfmw_support_darr(unsigned int i)
Definition: perfmon-ia64.c:445
int native[PAPI_EVENTS_IN_DERIVED_EVENT]
Definition: papi_preset.h:16
#define PAPI_DEFDOM
Definition: fpapi.h:49
void *long long tid
Definition: iozone.c:18586
int _ia64_ita2_set_domain(hwd_control_state_t *this_state, int domain)
pfmw_ita2_param_t ita2_param
Definition: perfmon-ia64.h:101
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
s
Definition: iozone.c:20289
#define MAX_COUNTER_TERMS
Definition: aix.h:44
int _ia64_read(hwd_context_t *ctx, hwd_control_state_t *machdep, long long **events, int flags)
unsigned int PAPI_NATIVE_UMASK_AND_MASK
long long
Definition: iozone.c:19827
_papi_int_granularity_t granularity
EventSetInfo_t * ESI
static int ia64_ita2_process_profile_buffer(ThreadInfo_t *thread, EventSetInfo_t *ESI)
void PAPIERROR(char *format,...)
static int encode_native_event_raw(unsigned int event, unsigned int mask)
int _papi_hwi_start_signal(int signal, int need_context, int cidx)
Definition: extras.c:401
#define PMU_FIRST_COUNTER
Definition: perfmon-ia64.h:96
#define PAPI_L3_ICM
Definition: fpapi.h:140
static int set_inherit(int arg)
#define PAPI_DOMAIN
Definition: fpapi.h:50
static int ia64_mont_process_profile_buffer(ThreadInfo_t *thread, EventSetInfo_t *ESI)
char events[MAX_EVENTS][BUFSIZ]
int mmtimer_setup(void)
Definition: linux-timer.c:116
int _ia64_ita23_read(hwd_context_t *ctx, hwd_control_state_t *machdep, long long **events, int flags)
strcat(command, mountname)
#define PAPI_BR_MSP
Definition: fpapi.h:181
#define PAPI_DEFGRN
Definition: fpapi.h:51
#define PAPI_INT_SIGNAL
Definition: papi_internal.h:53
char operation[PAPI_2MAX_STR_LEN]
Definition: papi_preset.h:17
#define PAPI_L1_DCH
Definition: fpapi.h:197
char * findme[MAX_COUNTERS]
Definition: perfmon-ia64.h:135
int _papi_hwi_stop_signal(int signal)
Definition: extras.c:441
pfmlib_ita2_output_param_t ita2_output_param
Definition: perfmon-ia64.h:89
#define PAPI_L3_LDM
Definition: fpapi.h:149
#define PAPI_L2_DCA
Definition: fpapi.h:200
#define PAPI_GRANUL
Definition: fpapi.h:52
pfmlib_ita2_input_param_t ita2_input_param
Definition: perfmon-ia64.h:88
_papi_int_multiplex_t multiplex
#define PAPI_L3_DCW
Definition: fpapi.h:207
static int _ia64_modify_event(unsigned int event, int modifier)
NativeInfo_t * NativeInfoArray
char version[]
Definition: fileop.c:134
int _ia64_set_profile(EventSetInfo_t *ESI, int EventIndex, int threshold)
EventInfo_t * EventInfoArray
#define PAPI_DEF_MPX_NS
Definition: fpapi.h:53
static int pfmw_support_iarr(unsigned int i)
Definition: perfmon-ia64.c:465
static int pfmw_dispatch_events(pfmw_param_t *evt)
Definition: perfmon-ia64.c:117
#define PAPI_ESYS
Definition: fpapi.h:108
int threshold
hwi_search_t * preset_search_map
#define PAPI_MEM_SCY
Definition: fpapi.h:169
int _ia64_set_overflow(EventSetInfo_t *ESI, int EventIndex, int threshold)
papi_mdi_t _papi_hwi_system_info
Definition: papi_internal.c:57
strcpy(filename, default_filename)
PAPI_hw_info_t hw_info
again struct sockaddr sizeof(struct sockaddr_in))
#define PAPI_L3_TCM
Definition: fpapi.h:143
int _ia64_stop(hwd_context_t *ctx, hwd_control_state_t *zero)
int pos[PAPI_EVENTS_IN_DERIVED_EVENT]
static void check_ibrp_events(hwd_control_state_t *current_state)
Definition: perfmon-ia64.c:505
#define PFMW_PEVT_EVTCOUNT(evt)
Definition: perfmon-ia64.c:47
#define PFMW_PEVT_PFPPC_REG_NUM(evt, idx)
Definition: perfmon-ia64.c:54
int _ia64_start(hwd_context_t *ctx, hwd_control_state_t *current_state)
static itanium_preset_search_t ia2_preset_search_map[]
#define PAPI_TOT_IIS
Definition: fpapi.h:184
int generate_preset_search_map(hwi_search_t **maploc, itanium_preset_search_t *oldmap, int num_cnt)
#define BTB_REGS_MASK
Definition: perfmon-ia64.h:174
int _ia64_set_domain(hwd_control_state_t *this_state, int domain)
struct sigcontext hwd_ucontext_t
Definition: aix-context.h:10
#define PAPI_MAX_PRESET_EVENTS
Definition: fpapi.h:16
int _ia64_ita_update_control_state(hwd_control_state_t *this_state, NativeInfo_t *native, int count, hwd_context_t *zero)
#define PAPI_L2_DCR
Definition: fpapi.h:203
#define PAPI_EBUG
Definition: fpapi.h:111
#define PAPI_L3_TCA
Definition: fpapi.h:225
#define PAPI_L2_TCR
Definition: fpapi.h:227
int _ia64_ita2_init_control_state(hwd_control_state_t *this_state)
static int set_default_domain(hwd_control_state_t *this_state, int domain)
#define PAPI_L1_DCM
Definition: fpapi.h:135
#define PAPI_OVERFLOW_FORCE_SW
Definition: papi.h:409
static int set_drange(hwd_context_t *ctx, hwd_control_state_t *current_state, _papi_int_option_t *option)
Definition: perfmon-ia64.c:767
int _ia64_ntv_code_to_name(unsigned int EventCode, char *ntv_name, int len)
#define PAPI_DEF_ITIMER
Definition: papi.h:452
EventSetInfo_t ** running_eventset
Definition: threads.h:30
pfmlib_mont_output_param_t mont_output_param
Definition: perfmon-ia64.h:82
#define DEAR_REGS_MASK
Definition: perfmon-ia64.h:173
int model
Definition: papi.h:784
char * name
Definition: iozone.c:23648
#define PAPI_L2_STM
Definition: fpapi.h:161
static int install_irange(hwd_context_t *pctx, hwd_control_state_t *current_state)
Definition: perfmon-ia64.c:626
int _ia64_mont_init_control_state(hwd_control_state_t *this_state)
static int total
Definition: rapl_overflow.c:5
void _papi_hwi_dispatch_profile(EventSetInfo_t *ESI, caddr_t pc, long long over, int profile_index)
Definition: extras.c:163
int ia64_register_t
Definition: perfmon-ia64.h:61
int
Definition: iozone.c:18528
static void ia64_dispatch_sigprof(int n, hwd_siginfo_t *info, hwd_ucontext_t *sc)
int x
Definition: fileop.c:78
#define PAPI_L2_TCH
Definition: fpapi.h:221
#define ISLEVEL(a)
Definition: papi_debug.h:54
inline_static ThreadInfo_t * _papi_hwi_lookup_thread(int custom_tid)
Definition: threads.h:92
pfmw_mont_param_t mont_param
Definition: perfmon-ia64.h:102
#define PAPI_STL_CCY
Definition: fpapi.h:174
#define PAPI_EBUF
Definition: fpapi.h:125
#define PAPI_NATIVE_AND_MASK
#define PAPI_FP_STAL
Definition: fpapi.h:193
#define PAPI_PROFIL_FORCE_SW
Definition: papi.h:401
unsigned int event_code
char support_version[PAPI_MIN_STR_LEN]
Definition: papi.h:630
#define PAPI_L1_TCR
Definition: fpapi.h:226
_papi_int_domain_t domain
int _ia64_update_control_state(hwd_control_state_t *this_state, NativeInfo_t *native, int count, hwd_context_t *zero)
hwd_siginfo_t * si
static int pfmw_create_ctx_common(hwd_context_t *ctx)
Definition: perfmon-ia64.c:162
#define PAPI_L2_ICM
Definition: fpapi.h:138
#define PAPI_DOM_USER
Definition: fpapi.h:21
int _papi_hwi_dispatch_overflow_signal(void *papiContext, caddr_t address, int *isHardware, long long overflow_bit, int genOverflowBit, ThreadInfo_t **t, int cidx)
Definition: extras.c:214
#define PAPI_L1_LDM
Definition: fpapi.h:158
unsigned int PAPI_NATIVE_EVENT_SHIFT
static int pfmw_get_event_name(char *name, unsigned int idx)
Definition: perfmon-ia64.c:379
EventSetProfileInfo_t profile
#define PAPI_L2_TCA
Definition: fpapi.h:224
int _ia64_ntv_code_to_descr(unsigned int EventCode, char *ntv_descr, int len)
static int set_default_granularity(hwd_control_state_t *this_state, int granularity)
hwd_control_state_t * ctl_state
long j
Definition: iozone.c:19135
#define PAPI_L2_ICR
Definition: fpapi.h:215
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
static int set_granularity(hwd_control_state_t *this_state, int domain)
static int set_notify(EventSetInfo_t *ESI, int index, int value)
#define GET_OVERFLOW_ADDRESS(ctx)
Definition: aix-context.h:12
#define PAPI_L1_DCA
Definition: fpapi.h:199
#define PAPI_L2_LDM
Definition: fpapi.h:160
pfarg_reg_t pd[NUM_PMDS]
Definition: perfmon-ia64.h:71
#define PFMW_PEVT_PFPPC_COUNT(evt)
Definition: perfmon-ia64.c:53
static int pfmw_support_opcm(unsigned int i)
Definition: perfmon-ia64.c:485
#define PAPI_GRN_THR
Definition: fpapi.h:67
signal(SIGINT, signal_handler)
int _ia64_init_control_state(hwd_control_state_t *this_state)
void * mod_inp
Definition: perfmon-ia64.h:75
int(* set_overflow)(EventSetInfo_t *, int, int)
Definition: papi_vector.h:40
if(gettimeofday(&tp,(struct timezone *) NULL)==-1) perror("gettimeofday")
static int _pfm_decode_native_event(unsigned int EventCode, unsigned int *event, unsigned int *umask)
#define PAPI_L2_ICA
Definition: fpapi.h:212
EventSetInfo_t * ESI
#define PAPI_L3_ICR
Definition: fpapi.h:216
int _ia64_ita_read(hwd_context_t *ctx, hwd_control_state_t *machdep, long long **events, int flags)
int n
Definition: mendes-alt.c:164
void _ia64_dispatch_timer(int signal, hwd_siginfo_t *info, void *context)
#define PAPI_STL_ICY
Definition: fpapi.h:172
#define DEBUG_SUBSTRATE
Definition: papi_debug.h:27
#define PAPI_L3_DCH
Definition: fpapi.h:164
#define MONT_ETB_REGS_MASK
Definition: perfmon-ia64.h:169
char * ptr
Definition: iozone.c:23586