Blame src/components/perfmon_ia64/perfmon-ia64.c

Packit 577717
/*
Packit 577717
* File:    perfmon-ia64.c
Packit 577717
* Author:  Philip Mucci
Packit 577717
*          mucci@cs.utk.edu
Packit 577717
* Mods:	   Kevin London
Packit 577717
*	   london@cs.utk.edu
Packit 577717
*          Per Ekman
Packit 577717
*          pek@pdc.kth.se
Packit 577717
*          Zhou Min
Packit 577717
*          min@cs.utk.edu
Packit 577717
*/
Packit 577717
Packit 577717
Packit 577717
#include "papi.h"
Packit 577717
#include "papi_internal.h"
Packit 577717
#include "papi_vector.h"
Packit 577717
#include "threads.h"
Packit 577717
#include "papi_memory.h"
Packit 577717
#include "papi_lock.h"
Packit 577717
Packit 577717
#include "linux-memory.h"
Packit 577717
#include "linux-timer.h"
Packit 577717
#include "linux-common.h"
Packit 577717
Packit 577717
#if defined(__INTEL_COMPILER)
Packit 577717
Packit 577717
#define hweight64(x)    _m64_popcnt(x)
Packit 577717
Packit 577717
#elif defined(__GNUC__)
Packit 577717
Packit 577717
static inline int
Packit 577717
hweight64( unsigned long x )
Packit 577717
{
Packit 577717
	unsigned long result;
Packit 577717
  __asm__( "popcnt %0=%1": "=r"( result ):"r"( x ) );
Packit 577717
	return ( int ) result;
Packit 577717
}
Packit 577717
Packit 577717
#else
Packit 577717
#error "you need to provide inline assembly from your compiler"
Packit 577717
#endif
Packit 577717
Packit 577717
extern int _perfmon2_pfm_pmu_type;
Packit 577717
extern papi_vector_t _ia64_vector;
Packit 577717
Packit 577717
#define OVFL_SIGNAL SIGPROF
Packit 577717
#define PFMW_PEVT_EVTCOUNT(evt)          (evt->inp.pfp_event_count)
Packit 577717
#define PFMW_PEVT_EVENT(evt,idx)         (evt->inp.pfp_events[idx].event)
Packit 577717
#define PFMW_PEVT_PLM(evt,idx)           (evt->inp.pfp_events[idx].plm)
Packit 577717
#define PFMW_PEVT_DFLPLM(evt)            (evt->inp.pfp_dfl_plm)
Packit 577717
#define PFMW_PEVT_PFPPC(evt)             (evt->pc)
Packit 577717
#define PFMW_PEVT_PFPPD(evt)             (evt->pd)
Packit 577717
#define PFMW_PEVT_PFPPC_COUNT(evt)       (evt->outp.pfp_pmc_count)
Packit 577717
#define PFMW_PEVT_PFPPC_REG_NUM(evt,idx) (evt->outp.pfp_pmcs[idx].reg_num)
Packit 577717
#define PFMW_PEVT_PFPPC_REG_VAL(evt,idx) (evt->pc[idx].reg_value)
Packit 577717
#define PFMW_PEVT_PFPPC_REG_FLG(evt,idx) (evt->pc[idx].reg_flags)
Packit 577717
#define PFMW_ARCH_REG_PMCVAL(reg) (reg.pmc_val)
Packit 577717
#define PFMW_ARCH_REG_PMDVAL(reg) (reg.pmd_val)
Packit 577717
Packit 577717
#define PFMON_MONT_MAX_IBRS	8
Packit 577717
#define PFMON_MONT_MAX_DBRS	8
Packit 577717
Packit 577717
#define PFMON_ITA2_MAX_IBRS	8
Packit 577717
#define PFMON_ITA2_MAX_DBRS	8
Packit 577717
/*
Packit 577717
   #if defined(ITANIUM3)
Packit 577717
      #define PFMW_ARCH_REG_PMCPLM(reg) (reg.pmc_mont_counter_reg.pmc_plm)
Packit 577717
      #define PFMW_ARCH_REG_PMCES(reg)  (reg.pmc_mont_counter_reg.pmc_es)
Packit 577717
      typedef pfm_mont_pmc_reg_t pfmw_arch_pmc_reg_t;
Packit 577717
      typedef pfm_mont_pmd_reg_t pfmw_arch_pmd_reg_t;
Packit 577717
   #elif defined(ITANIUM2)
Packit 577717
      #define PFMW_ARCH_REG_PMCPLM(reg) (reg.pmc_ita2_counter_reg.pmc_plm)
Packit 577717
      #define PFMW_ARCH_REG_PMCES(reg)  (reg.pmc_ita2_counter_reg.pmc_es)
Packit 577717
      typedef pfm_ita2_pmc_reg_t pfmw_arch_pmc_reg_t;
Packit 577717
      typedef pfm_ita2_pmd_reg_t pfmw_arch_pmd_reg_t;
Packit 577717
   #else 
Packit 577717
      #define PFMW_ARCH_REG_PMCPLM(reg) (reg.pmc_ita_count_reg.pmc_plm)
Packit 577717
      #define PFMW_ARCH_REG_PMCES(reg)  (reg.pmc_ita_count_reg.pmc_es)
Packit 577717
      typedef pfm_ita_pmc_reg_t pfmw_arch_pmc_reg_t;
Packit 577717
      typedef pfm_ita_pmd_reg_t pfmw_arch_pmd_reg_t;
Packit 577717
   #endif
Packit 577717
*/
Packit 577717
typedef pfm_default_smpl_hdr_t pfmw_smpl_hdr_t;
Packit 577717
typedef pfm_default_smpl_entry_t pfmw_smpl_entry_t;
Packit 577717
Packit 577717
static  void
Packit 577717
pfmw_start( hwd_context_t * ctx )
Packit 577717
{
Packit 577717
	pfm_self_start( ( ( ia64_context_t * ) ctx )->fd );
Packit 577717
}
Packit 577717
Packit 577717
static  void
Packit 577717
pfmw_stop( hwd_context_t * ctx )
Packit 577717
{
Packit 577717
	pfm_self_stop( ( ( ia64_context_t * ) ctx )->fd );
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
pfmw_perfmonctl( pid_t tid, int fd, int cmd, void *arg, int narg )
Packit 577717
{
Packit 577717
	( void ) tid;			 /*unused */
Packit 577717
	return ( perfmonctl( fd, cmd, arg, narg ) );
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
pfmw_destroy_context( hwd_context_t * thr_ctx )
Packit 577717
{
Packit 577717
	int ret;
Packit 577717
	ret = close( ( ( ia64_context_t * ) thr_ctx )->fd );
Packit 577717
	if ( ret )
Packit 577717
		return PAPI_ESYS;
Packit 577717
	else
Packit 577717
		return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
pfmw_dispatch_events( pfmw_param_t * evt )
Packit 577717
{
Packit 577717
	int ret;
Packit 577717
	unsigned int i;
Packit 577717
/*
Packit 577717
      PFMW_PEVT_DFLPLM(evt) = PFM_PLM3;
Packit 577717
*/
Packit 577717
#ifdef PFMLIB_MONTECITO_PMU
Packit 577717
	if ( _perfmon2_pfm_pmu_type == PFMLIB_MONTECITO_PMU )
Packit 577717
		ret =
Packit 577717
			pfm_dispatch_events( &evt->inp,
Packit 577717
								 ( pfmlib_mont_input_param_t * ) evt->mod_inp,
Packit 577717
								 &evt->outp,
Packit 577717
								 ( pfmlib_mont_output_param_t * ) evt->
Packit 577717
								 mod_outp );
Packit 577717
	else
Packit 577717
#endif
Packit 577717
		ret =
Packit 577717
			pfm_dispatch_events( &evt->inp,
Packit 577717
								 ( pfmlib_ita2_input_param_t * ) evt->mod_inp,
Packit 577717
								 &evt->outp,
Packit 577717
								 ( pfmlib_ita2_output_param_t * ) evt->
Packit 577717
								 mod_outp );
Packit 577717
	if ( ret ) {
Packit 577717
		return PAPI_ESYS;
Packit 577717
	} else {
Packit 577717
		for ( i = 0; i < evt->outp.pfp_pmc_count; i++ ) {
Packit 577717
			evt->pc[i].reg_num = evt->outp.pfp_pmcs[i].reg_num;
Packit 577717
			evt->pc[i].reg_value = evt->outp.pfp_pmcs[i].reg_value;
Packit 577717
		}
Packit 577717
#if defined(HAVE_PFMLIB_OUTPUT_PFP_PMD_COUNT)
Packit 577717
		for ( i = 0; i < evt->outp.pfp_pmd_count; i++ ) {
Packit 577717
			evt->pd[i].reg_num = evt->outp.pfp_pmds[i].reg_num;
Packit 577717
		}
Packit 577717
#else
Packit 577717
		/* This is really broken */
Packit 577717
		for ( i = 0; i < evt->inp.pfp_event_count; i++ ) {
Packit 577717
			evt->pd[i].reg_num = evt->pc[i].reg_num;
Packit 577717
		}
Packit 577717
#endif
Packit 577717
		return PAPI_OK;
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
pfmw_create_ctx_common( hwd_context_t * ctx )
Packit 577717
{
Packit 577717
	pfarg_load_t load_args;
Packit 577717
	int ret;
Packit 577717
Packit 577717
	memset( &load_args, 0, sizeof ( load_args ) );
Packit 577717
	/*
Packit 577717
	 * we want to monitor ourself
Packit 577717
	 */
Packit 577717
Packit 577717
	load_args.load_pid = ( ( ia64_context_t * ) ctx )->tid;
Packit 577717
Packit 577717
	SUBDBG( "PFM_LOAD_CONTEXT FD %d, PID %d\n",
Packit 577717
			( ( ia64_context_t * ) ctx )->fd,
Packit 577717
			( ( ia64_context_t * ) ctx )->tid );
Packit 577717
	if ( perfmonctl
Packit 577717
		 ( ( ( ia64_context_t * ) ctx )->fd, PFM_LOAD_CONTEXT, &load_args,
Packit 577717
		   1 ) == -1 ) {
Packit 577717
		PAPIERROR( "perfmonctl(PFM_LOAD_CONTEXT) errno %d", errno );
Packit 577717
		return ( PAPI_ESYS );
Packit 577717
	}
Packit 577717
	/*
Packit 577717
	 * setup asynchronous notification on the file descriptor
Packit 577717
	 */
Packit 577717
	ret =
Packit 577717
		fcntl( ( ( ia64_context_t * ) ctx )->fd, F_SETFL,
Packit 577717
			   fcntl( ( ( ia64_context_t * ) ctx )->fd, F_GETFL,
Packit 577717
					  0 ) | O_ASYNC );
Packit 577717
	if ( ret == -1 ) {
Packit 577717
		PAPIERROR( "fcntl(%d,F_SETFL,O_ASYNC) errno %d",
Packit 577717
				   ( ( ia64_context_t * ) ctx )->fd, errno );
Packit 577717
		return ( PAPI_ESYS );
Packit 577717
	}
Packit 577717
Packit 577717
	/*
Packit 577717
	 * get ownership of the descriptor
Packit 577717
	 */
Packit 577717
Packit 577717
	ret =
Packit 577717
		fcntl( ( ( ia64_context_t * ) ctx )->fd, F_SETOWN,
Packit 577717
			   ( ( ia64_context_t * ) ctx )->tid );
Packit 577717
	if ( ret == -1 ) {
Packit 577717
		PAPIERROR( "fcntl(%d,F_SETOWN) errno %d",
Packit 577717
				   ( ( ia64_context_t * ) ctx )->fd, errno );
Packit 577717
		return ( PAPI_ESYS );
Packit 577717
	}
Packit 577717
Packit 577717
	ret =
Packit 577717
		fcntl( ( ( ia64_context_t * ) ctx )->fd, F_SETSIG,
Packit 577717
			   _ia64_vector.cmp_info.hardware_intr_sig );
Packit 577717
	if ( ret == -1 ) {
Packit 577717
		PAPIERROR( "fcntl(%d,F_SETSIG) errno %d",
Packit 577717
				   ( ( ia64_context_t * ) ctx )->fd, errno );
Packit 577717
		return ( PAPI_ESYS );
Packit 577717
	}
Packit 577717
Packit 577717
	/* set close-on-exec to ensure we will be getting the PFM_END_MSG, i.e.,
Packit 577717
	 * fd not visible to child. */
Packit 577717
Packit 577717
	ret = fcntl( ( ( ia64_context_t * ) ctx )->fd, F_SETFD, FD_CLOEXEC );
Packit 577717
	if ( ret == -1 ) {
Packit 577717
		PAPIERROR( "fcntl(%d,FD_CLOEXEC) errno %d",
Packit 577717
				   ( ( ia64_context_t * ) ctx )->fd, errno );
Packit 577717
		return ( PAPI_ESYS );
Packit 577717
	}
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
pfmw_create_context( hwd_context_t * thr_ctx )
Packit 577717
{
Packit 577717
	pfarg_context_t ctx;
Packit 577717
	memset( &ctx, 0, sizeof ( ctx ) );
Packit 577717
Packit 577717
	SUBDBG( "PFM_CREATE_CONTEXT on 0\n" );
Packit 577717
	if ( perfmonctl( 0, PFM_CREATE_CONTEXT, &ctx, 1 ) == -1 ) {
Packit 577717
		PAPIERROR( "perfmonctl(PFM_CREATE_CONTEXT) errno %d", errno );
Packit 577717
		return ( PAPI_ESYS );
Packit 577717
	}
Packit 577717
	( ( ia64_context_t * ) thr_ctx )->fd = ctx.ctx_fd;
Packit 577717
	( ( ia64_context_t * ) thr_ctx )->tid = mygettid(  );
Packit 577717
	SUBDBG( "PFM_CREATE_CONTEXT returns FD %d, TID %d\n",
Packit 577717
			( int ) ( ( ia64_context_t * ) thr_ctx )->fd,
Packit 577717
			( int ) ( ( ia64_context_t * ) thr_ctx )->tid );
Packit 577717
Packit 577717
	return ( pfmw_create_ctx_common( thr_ctx ) );
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
set_pmds_to_write( EventSetInfo_t * ESI, int index, unsigned long value )
Packit 577717
{
Packit 577717
	int *pos, count, i;
Packit 577717
	unsigned int hwcntr;
Packit 577717
	ia64_control_state_t *this_state =
Packit 577717
		( ia64_control_state_t * ) ESI->ctl_state;
Packit 577717
	pfmw_param_t *pevt = &( this_state->evt );
Packit 577717
Packit 577717
	pos = ESI->EventInfoArray[index].pos;
Packit 577717
	count = 0;
Packit 577717
	while ( pos[count] != -1 && count < MAX_COUNTERS ) {
Packit 577717
		hwcntr = pos[count] + PMU_FIRST_COUNTER;
Packit 577717
		for ( i = 0; i < MAX_COUNTERS; i++ ) {
Packit 577717
			if ( PFMW_PEVT_PFPPC_REG_NUM( pevt, i ) == hwcntr ) {
Packit 577717
				this_state->evt.pc[i].reg_smpl_pmds[0] = value;
Packit 577717
				break;
Packit 577717
			}
Packit 577717
		}
Packit 577717
		count++;
Packit 577717
	}
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
_pfm_decode_native_event( unsigned int EventCode, unsigned int *event,
Packit 577717
			  unsigned int *umask );
Packit 577717
Packit 577717
static  int
Packit 577717
pfmw_recreate_context( EventSetInfo_t * ESI, hwd_context_t * thr_ctx,
Packit 577717
		       void **smpl_vaddr, int EventIndex )
Packit 577717
{
Packit 577717
	pfm_default_smpl_ctx_arg_t ctx;
Packit 577717
	pfm_uuid_t buf_fmt_id = PFM_DEFAULT_SMPL_UUID;
Packit 577717
	int ctx_fd;
Packit 577717
	unsigned int native_index, EventCode;
Packit 577717
	int pos;
Packit 577717
	//hwd_context_t *thr_ctx = (hwd_context_t *) &ESI->master->context;
Packit 577717
#ifdef PFMLIB_MONTECITO_PMU
Packit 577717
	unsigned int umask;
Packit 577717
#endif
Packit 577717
Packit 577717
	pos = ESI->EventInfoArray[EventIndex].pos[0];
Packit 577717
	EventCode = ESI->EventInfoArray[EventIndex].event_code;
Packit 577717
#ifdef PFMLIB_MONTECITO_PMU
Packit 577717
	if ( _perfmon2_pfm_pmu_type == PFMLIB_MONTECITO_PMU ) {
Packit 577717
		if ( _pfm_decode_native_event
Packit 577717
			 ( ESI->NativeInfoArray[pos].ni_event, &native_index,
Packit 577717
			   &umask ) != PAPI_OK )
Packit 577717
			return ( PAPI_ENOEVNT );
Packit 577717
	} else
Packit 577717
#endif
Packit 577717
		native_index =
Packit 577717
			ESI->NativeInfoArray[pos].ni_event & PAPI_NATIVE_AND_MASK;
Packit 577717
Packit 577717
	memset( &ctx, 0, sizeof ( ctx ) );
Packit 577717
	/*
Packit 577717
	 * We initialize the format specific information.
Packit 577717
	 * The format is identified by its UUID which must be copied
Packit 577717
	 * into the ctx_buf_fmt_id field.
Packit 577717
	 */
Packit 577717
	memcpy( ctx.ctx_arg.ctx_smpl_buf_id, buf_fmt_id, sizeof ( pfm_uuid_t ) );
Packit 577717
	/*
Packit 577717
	 * the size of the buffer is indicated in bytes (not entries).
Packit 577717
	 * The kernel will record into the buffer up to a certain point.
Packit 577717
	 * No partial samples are ever recorded.
Packit 577717
	 */
Packit 577717
	ctx.buf_arg.buf_size = 4096;
Packit 577717
	/*
Packit 577717
	 * now create the context for self monitoring/per-task
Packit 577717
	 */
Packit 577717
	SUBDBG( "PFM_CREATE_CONTEXT on 0\n" );
Packit 577717
	if ( perfmonctl( 0, PFM_CREATE_CONTEXT, &ctx, 1 ) == -1 ) {
Packit 577717
		if ( errno == ENOSYS )
Packit 577717
			PAPIERROR
Packit 577717
				( "Your kernel does not have performance monitoring support" );
Packit 577717
		else
Packit 577717
			PAPIERROR( "perfmonctl(PFM_CREATE_CONTEXT) errno %d", errno );
Packit 577717
		return ( PAPI_ESYS );
Packit 577717
	}
Packit 577717
	/*
Packit 577717
	 * extract the file descriptor we will use to
Packit 577717
	 * identify this newly created context
Packit 577717
	 */
Packit 577717
	ctx_fd = ctx.ctx_arg.ctx_fd;
Packit 577717
	/* save the fd into the thread context struct */
Packit 577717
	( ( ia64_context_t * ) thr_ctx )->fd = ctx_fd;
Packit 577717
	( ( ia64_context_t * ) thr_ctx )->tid = mygettid(  );
Packit 577717
	SUBDBG( "PFM_CREATE_CONTEXT returns FD %d, TID %d\n",
Packit 577717
			( int ) ( ( ia64_context_t * ) thr_ctx )->fd,
Packit 577717
			( int ) ( ( ia64_context_t * ) thr_ctx )->tid );
Packit 577717
	/* indicate which PMD to include in the sample */
Packit 577717
/* DEAR and BTB events */
Packit 577717
	switch ( _perfmon2_pfm_pmu_type ) {
Packit 577717
	case PFMLIB_ITANIUM_PMU:
Packit 577717
		if ( pfm_ita_is_dear( native_index ) )
Packit 577717
			set_pmds_to_write( ESI, EventIndex, DEAR_REGS_MASK );
Packit 577717
		else if ( pfm_ita_is_btb( native_index )
Packit 577717
				  || EventCode == ( unsigned int ) PAPI_BR_INS )
Packit 577717
			set_pmds_to_write( ESI, EventIndex, BTB_REGS_MASK );
Packit 577717
		break;
Packit 577717
	case PFMLIB_ITANIUM2_PMU:
Packit 577717
		if ( pfm_ita2_is_dear( native_index ) )
Packit 577717
			set_pmds_to_write( ESI, EventIndex, DEAR_REGS_MASK );
Packit 577717
		else if ( pfm_ita2_is_btb( native_index )
Packit 577717
				  || EventCode == ( unsigned int ) PAPI_BR_INS )
Packit 577717
			set_pmds_to_write( ESI, EventIndex, BTB_REGS_MASK );
Packit 577717
		break;
Packit 577717
	case PFMLIB_MONTECITO_PMU:
Packit 577717
		if ( pfm_mont_is_dear( native_index ) )
Packit 577717
			set_pmds_to_write( ESI, EventIndex, MONT_DEAR_REGS_MASK );
Packit 577717
		else if ( pfm_mont_is_etb( native_index ) ||
Packit 577717
				  EventCode == ( unsigned int ) PAPI_BR_INS )
Packit 577717
			set_pmds_to_write( ESI, EventIndex, MONT_ETB_REGS_MASK );
Packit 577717
		break;
Packit 577717
	default:
Packit 577717
		PAPIERROR( "PMU type %d is not supported by this component",
Packit 577717
				   _perfmon2_pfm_pmu_type );
Packit 577717
		return ( PAPI_EBUG );
Packit 577717
	}
Packit 577717
Packit 577717
	*smpl_vaddr = ctx.ctx_arg.ctx_smpl_vaddr;
Packit 577717
Packit 577717
	return ( pfmw_create_ctx_common( thr_ctx ) );
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
pfmw_get_event_name( char *name, unsigned int idx )
Packit 577717
{
Packit 577717
	unsigned int total;
Packit 577717
Packit 577717
	pfm_get_num_events( &total );
Packit 577717
	if ( idx >= total )
Packit 577717
		return PAPI_ENOEVNT;
Packit 577717
	if ( pfm_get_event_name( idx, name, PAPI_MAX_STR_LEN ) == PFMLIB_SUCCESS )
Packit 577717
		return PAPI_OK;
Packit 577717
	else
Packit 577717
		return PAPI_ENOEVNT;
Packit 577717
}
Packit 577717
Packit 577717
static  void
Packit 577717
pfmw_get_event_description( unsigned int idx, char *dest, int len )
Packit 577717
{
Packit 577717
	char *descr;
Packit 577717
Packit 577717
	if ( pfm_get_event_description( idx, &descr ) == PFMLIB_SUCCESS ) {
Packit 577717
		strncpy( dest, descr, len );
Packit 577717
		free( descr );
Packit 577717
	} else
Packit 577717
		*dest = '\0';
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
pfmw_is_dear( unsigned int i )
Packit 577717
{
Packit 577717
	switch ( _perfmon2_pfm_pmu_type ) {
Packit 577717
	case PFMLIB_ITANIUM_PMU:
Packit 577717
		return ( pfm_ita_is_dear( i ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_ITANIUM2_PMU:
Packit 577717
		return ( pfm_ita2_is_dear( i ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_MONTECITO_PMU:
Packit 577717
		return ( pfm_mont_is_dear( i ) );
Packit 577717
		break;
Packit 577717
	default:
Packit 577717
		PAPIERROR( "PMU type %d is not supported by this component",
Packit 577717
				   _perfmon2_pfm_pmu_type );
Packit 577717
		return ( PAPI_EBUG );
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
pfmw_is_iear( unsigned int i )
Packit 577717
{
Packit 577717
	switch ( _perfmon2_pfm_pmu_type ) {
Packit 577717
	case PFMLIB_ITANIUM_PMU:
Packit 577717
		return ( pfm_ita_is_iear( i ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_ITANIUM2_PMU:
Packit 577717
		return ( pfm_ita2_is_iear( i ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_MONTECITO_PMU:
Packit 577717
		return ( pfm_mont_is_iear( i ) );
Packit 577717
		break;
Packit 577717
	default:
Packit 577717
		PAPIERROR( "PMU type %d is not supported by this component",
Packit 577717
				   _perfmon2_pfm_pmu_type );
Packit 577717
		return ( PAPI_EBUG );
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
pfmw_support_darr( unsigned int i )
Packit 577717
{
Packit 577717
	switch ( _perfmon2_pfm_pmu_type ) {
Packit 577717
	case PFMLIB_ITANIUM_PMU:
Packit 577717
		return ( pfm_ita_support_darr( i ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_ITANIUM2_PMU:
Packit 577717
		return ( pfm_ita2_support_darr( i ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_MONTECITO_PMU:
Packit 577717
		return ( pfm_mont_support_darr( i ) );
Packit 577717
		break;
Packit 577717
	default:
Packit 577717
		PAPIERROR( "PMU type %d is not supported by this component",
Packit 577717
				   _perfmon2_pfm_pmu_type );
Packit 577717
		return ( PAPI_EBUG );
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
pfmw_support_iarr( unsigned int i )
Packit 577717
{
Packit 577717
	switch ( _perfmon2_pfm_pmu_type ) {
Packit 577717
	case PFMLIB_ITANIUM_PMU:
Packit 577717
		return ( pfm_ita_support_iarr( i ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_ITANIUM2_PMU:
Packit 577717
		return ( pfm_ita2_support_iarr( i ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_MONTECITO_PMU:
Packit 577717
		return ( pfm_mont_support_iarr( i ) );
Packit 577717
		break;
Packit 577717
	default:
Packit 577717
		PAPIERROR( "PMU type %d is not supported by this component",
Packit 577717
				   _perfmon2_pfm_pmu_type );
Packit 577717
		return ( PAPI_EBUG );
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
pfmw_support_opcm( unsigned int i )
Packit 577717
{
Packit 577717
	switch ( _perfmon2_pfm_pmu_type ) {
Packit 577717
	case PFMLIB_ITANIUM_PMU:
Packit 577717
		return ( pfm_ita_support_opcm( i ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_ITANIUM2_PMU:
Packit 577717
		return ( pfm_ita2_support_opcm( i ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_MONTECITO_PMU:
Packit 577717
		return ( pfm_mont_support_opcm( i ) );
Packit 577717
		break;
Packit 577717
	default:
Packit 577717
		PAPIERROR( "PMU type %d is not supported by this component",
Packit 577717
				   _perfmon2_pfm_pmu_type );
Packit 577717
		return ( PAPI_EBUG );
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
static void
Packit 577717
check_ibrp_events( hwd_control_state_t * current_state )
Packit 577717
{
Packit 577717
	ia64_control_state_t *this_state = ( ia64_control_state_t * ) current_state;
Packit 577717
	pfmw_param_t *evt = &( this_state->evt );
Packit 577717
	unsigned long umasks_retired[4];
Packit 577717
	unsigned long umask;
Packit 577717
	unsigned int j, i, seen_retired, ibrp, idx;
Packit 577717
	int code;
Packit 577717
	int retired_code, incr;
Packit 577717
	pfmlib_ita2_output_param_t *ita2_output_param;
Packit 577717
	pfmlib_mont_output_param_t *mont_output_param;
Packit 577717
Packit 577717
#if defined(PFMLIB_ITANIUM2_PMU) || defined(PFMLIB_MONTECITO_PMU)
Packit 577717
char *retired_events[] = {
Packit 577717
	"IA64_TAGGED_INST_RETIRED_IBRP0_PMC8",
Packit 577717
	"IA64_TAGGED_INST_RETIRED_IBRP1_PMC9",
Packit 577717
	"IA64_TAGGED_INST_RETIRED_IBRP2_PMC8",
Packit 577717
	"IA64_TAGGED_INST_RETIRED_IBRP3_PMC9",
Packit 577717
	NULL
Packit 577717
};
Packit 577717
#endif
Packit 577717
Packit 577717
	switch ( _perfmon2_pfm_pmu_type ) {
Packit 577717
	case PFMLIB_ITANIUM2_PMU:
Packit 577717
		ita2_output_param =
Packit 577717
			&( this_state->ita_lib_param.ita2_param.ita2_output_param );
Packit 577717
		/*
Packit 577717
		 * in fine mode, it is enough to use the event
Packit 577717
		 * which only monitors the first debug register
Packit 577717
		 * pair. The two pairs making up the range
Packit 577717
		 * are guaranteed to be consecutive in rr_br[].
Packit 577717
		 */
Packit 577717
		incr = pfm_ita2_irange_is_fine( &evt->outp, ita2_output_param ) ? 4 : 2;
Packit 577717
Packit 577717
		for ( i = 0; retired_events[i]; i++ ) {
Packit 577717
			pfm_find_event( retired_events[i], &idx );
Packit 577717
			pfm_ita2_get_event_umask( idx, umasks_retired + i );
Packit 577717
		}
Packit 577717
Packit 577717
		pfm_get_event_code( idx, &retired_code );
Packit 577717
Packit 577717
		/*
Packit 577717
		 * print a warning message when the using IA64_TAGGED_INST_RETIRED_IBRP* which does
Packit 577717
		 * not completely cover the all the debug register pairs used to make up the range.
Packit 577717
		 * This could otherwise lead to misinterpretation of the results.
Packit 577717
		 */
Packit 577717
		for ( i = 0; i < ita2_output_param->pfp_ita2_irange.rr_nbr_used;
Packit 577717
			  i += incr ) {
Packit 577717
Packit 577717
			ibrp = ita2_output_param->pfp_ita2_irange.rr_br[i].reg_num >> 1;
Packit 577717
Packit 577717
			seen_retired = 0;
Packit 577717
			for ( j = 0; j < evt->inp.pfp_event_count; j++ ) {
Packit 577717
				pfm_get_event_code( evt->inp.pfp_events[j].event, &code );
Packit 577717
				if ( code != retired_code )
Packit 577717
					continue;
Packit 577717
				seen_retired = 1;
Packit 577717
				pfm_ita2_get_event_umask( evt->inp.pfp_events[j].event,
Packit 577717
										  &umask );
Packit 577717
				if ( umask == umasks_retired[ibrp] )
Packit 577717
					break;
Packit 577717
			}
Packit 577717
			if ( seen_retired && j == evt->inp.pfp_event_count )
Packit 577717
				printf
Packit 577717
					( "warning: code range uses IBR pair %d which is not monitored using %s\n",
Packit 577717
					  ibrp, retired_events[ibrp] );
Packit 577717
		}
Packit 577717
Packit 577717
		break;
Packit 577717
	case PFMLIB_MONTECITO_PMU:
Packit 577717
		mont_output_param =
Packit 577717
			&( this_state->ita_lib_param.mont_param.mont_output_param );
Packit 577717
		/*
Packit 577717
		 * in fine mode, it is enough to use the event
Packit 577717
		 * which only monitors the first debug register
Packit 577717
		 * pair. The two pairs making up the range
Packit 577717
		 * are guaranteed to be consecutive in rr_br[].
Packit 577717
		 */
Packit 577717
		incr = pfm_mont_irange_is_fine( &evt->outp, mont_output_param ) ? 4 : 2;
Packit 577717
Packit 577717
		for ( i = 0; retired_events[i]; i++ ) {
Packit 577717
			pfm_find_event( retired_events[i], &idx );
Packit 577717
			pfm_mont_get_event_umask( idx, umasks_retired + i );
Packit 577717
		}
Packit 577717
Packit 577717
		pfm_get_event_code( idx, &retired_code );
Packit 577717
Packit 577717
		/*
Packit 577717
		 * print a warning message when the using IA64_TAGGED_INST_RETIRED_IBRP* which does
Packit 577717
		 * not completely cover the all the debug register pairs used to make up the range.
Packit 577717
		 * This could otherwise lead to misinterpretation of the results.
Packit 577717
		 */
Packit 577717
		for ( i = 0; i < mont_output_param->pfp_mont_irange.rr_nbr_used;
Packit 577717
			  i += incr ) {
Packit 577717
Packit 577717
			ibrp = mont_output_param->pfp_mont_irange.rr_br[i].reg_num >> 1;
Packit 577717
Packit 577717
			seen_retired = 0;
Packit 577717
			for ( j = 0; j < evt->inp.pfp_event_count; j++ ) {
Packit 577717
				pfm_get_event_code( evt->inp.pfp_events[j].event, &code );
Packit 577717
				if ( code != retired_code )
Packit 577717
					continue;
Packit 577717
				seen_retired = 1;
Packit 577717
				pfm_mont_get_event_umask( evt->inp.pfp_events[j].event,
Packit 577717
										  &umask );
Packit 577717
				if ( umask == umasks_retired[ibrp] )
Packit 577717
					break;
Packit 577717
			}
Packit 577717
			if ( seen_retired && j == evt->inp.pfp_event_count )
Packit 577717
				printf
Packit 577717
					( "warning: code range uses IBR pair %d which is not monitored using %s\n",
Packit 577717
					  ibrp, retired_events[ibrp] );
Packit 577717
		}
Packit 577717
		break;
Packit 577717
	default:
Packit 577717
		PAPIERROR( "PMU type %d is not supported by this component",
Packit 577717
				   _perfmon2_pfm_pmu_type );
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
install_irange( hwd_context_t * pctx, hwd_control_state_t * current_state )
Packit 577717
{
Packit 577717
	ia64_control_state_t *this_state = ( ia64_control_state_t * ) current_state;
Packit 577717
	unsigned int i, used_dbr;
Packit 577717
	int r;
Packit 577717
	int pid = ( ( ia64_context_t * ) pctx )->fd;
Packit 577717
Packit 577717
	pfmlib_ita2_output_param_t *ita2_output_param;
Packit 577717
	pfarg_dbreg_t ita2_dbreg[PFMON_ITA2_MAX_IBRS];
Packit 577717
	pfmlib_mont_output_param_t *mont_output_param;
Packit 577717
	pfarg_dbreg_t mont_dbreg[PFMON_MONT_MAX_IBRS];
Packit 577717
Packit 577717
	memset( mont_dbreg, 0, sizeof ( mont_dbreg ) );
Packit 577717
	memset( ita2_dbreg, 0, sizeof ( ita2_dbreg ) );
Packit 577717
	check_ibrp_events( current_state );
Packit 577717
Packit 577717
	switch ( _perfmon2_pfm_pmu_type ) {
Packit 577717
	case PFMLIB_ITANIUM2_PMU:
Packit 577717
		ita2_output_param =
Packit 577717
			&( this_state->ita_lib_param.ita2_param.ita2_output_param );
Packit 577717
		used_dbr = ita2_output_param->pfp_ita2_irange.rr_nbr_used;
Packit 577717
Packit 577717
		for ( i = 0; i < used_dbr; i++ ) {
Packit 577717
			ita2_dbreg[i].dbreg_num =
Packit 577717
				ita2_output_param->pfp_ita2_irange.rr_br[i].reg_num;
Packit 577717
			ita2_dbreg[i].dbreg_value =
Packit 577717
				ita2_output_param->pfp_ita2_irange.rr_br[i].reg_value;
Packit 577717
		}
Packit 577717
Packit 577717
		r = perfmonctl( pid, PFM_WRITE_IBRS, ita2_dbreg,
Packit 577717
						ita2_output_param->pfp_ita2_irange.rr_nbr_used );
Packit 577717
		if ( r == -1 ) {
Packit 577717
			SUBDBG( "cannot install code range restriction: %s\n",
Packit 577717
					strerror( errno ) );
Packit 577717
			return ( PAPI_ESYS );
Packit 577717
		}
Packit 577717
		return ( PAPI_OK );
Packit 577717
		break;
Packit 577717
	case PFMLIB_MONTECITO_PMU:
Packit 577717
		mont_output_param =
Packit 577717
			&( this_state->ita_lib_param.mont_param.mont_output_param );
Packit 577717
Packit 577717
		used_dbr = mont_output_param->pfp_mont_irange.rr_nbr_used;
Packit 577717
Packit 577717
		for ( i = 0; i < used_dbr; i++ ) {
Packit 577717
			mont_dbreg[i].dbreg_num =
Packit 577717
				mont_output_param->pfp_mont_irange.rr_br[i].reg_num;
Packit 577717
			mont_dbreg[i].dbreg_value =
Packit 577717
				mont_output_param->pfp_mont_irange.rr_br[i].reg_value;
Packit 577717
		}
Packit 577717
Packit 577717
		r = perfmonctl( pid, PFM_WRITE_IBRS, mont_dbreg,
Packit 577717
						mont_output_param->pfp_mont_irange.rr_nbr_used );
Packit 577717
		if ( r == -1 ) {
Packit 577717
			SUBDBG( "cannot install code range restriction: %s\n",
Packit 577717
					strerror( errno ) );
Packit 577717
			return ( PAPI_ESYS );
Packit 577717
		}
Packit 577717
		return ( PAPI_OK );
Packit 577717
		break;
Packit 577717
	default:
Packit 577717
		PAPIERROR( "PMU type %d is not supported by this component",
Packit 577717
				   _perfmon2_pfm_pmu_type );
Packit 577717
		return PAPI_ENOIMPL;
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
install_drange( hwd_context_t * pctx, hwd_control_state_t * current_state )
Packit 577717
{
Packit 577717
	ia64_control_state_t *this_state = ( ia64_control_state_t * ) current_state;
Packit 577717
	unsigned int i, used_dbr;
Packit 577717
	int r;
Packit 577717
	int pid = ( ( ia64_context_t * ) pctx )->fd;
Packit 577717
Packit 577717
	pfmlib_ita2_output_param_t *ita2_output_param;
Packit 577717
	pfarg_dbreg_t ita2_dbreg[PFMON_ITA2_MAX_IBRS];
Packit 577717
	pfmlib_mont_output_param_t *mont_output_param;
Packit 577717
	pfarg_dbreg_t mont_dbreg[PFMON_MONT_MAX_IBRS];
Packit 577717
Packit 577717
	memset( mont_dbreg, 0, sizeof ( mont_dbreg ) );
Packit 577717
	memset( ita2_dbreg, 0, sizeof ( ita2_dbreg ) );
Packit 577717
Packit 577717
	switch ( _perfmon2_pfm_pmu_type ) {
Packit 577717
	case PFMLIB_ITANIUM2_PMU:
Packit 577717
		ita2_output_param =
Packit 577717
			&( this_state->ita_lib_param.ita2_param.ita2_output_param );
Packit 577717
		used_dbr = ita2_output_param->pfp_ita2_drange.rr_nbr_used;
Packit 577717
Packit 577717
		for ( i = 0; i < used_dbr; i++ ) {
Packit 577717
			ita2_dbreg[i].dbreg_num =
Packit 577717
				ita2_output_param->pfp_ita2_drange.rr_br[i].reg_num;
Packit 577717
			ita2_dbreg[i].dbreg_value =
Packit 577717
				ita2_output_param->pfp_ita2_drange.rr_br[i].reg_value;
Packit 577717
		}
Packit 577717
Packit 577717
		r = perfmonctl( pid, PFM_WRITE_DBRS, ita2_dbreg,
Packit 577717
						ita2_output_param->pfp_ita2_drange.rr_nbr_used );
Packit 577717
		if ( r == -1 ) {
Packit 577717
			SUBDBG( "cannot install data range restriction: %s\n",
Packit 577717
					strerror( errno ) );
Packit 577717
			return ( PAPI_ESYS );
Packit 577717
		}
Packit 577717
		return ( PAPI_OK );
Packit 577717
		break;
Packit 577717
	case PFMLIB_MONTECITO_PMU:
Packit 577717
		mont_output_param =
Packit 577717
			&( this_state->ita_lib_param.mont_param.mont_output_param );
Packit 577717
		used_dbr = mont_output_param->pfp_mont_drange.rr_nbr_used;
Packit 577717
Packit 577717
		for ( i = 0; i < used_dbr; i++ ) {
Packit 577717
			mont_dbreg[i].dbreg_num =
Packit 577717
				mont_output_param->pfp_mont_drange.rr_br[i].reg_num;
Packit 577717
			mont_dbreg[i].dbreg_value =
Packit 577717
				mont_output_param->pfp_mont_drange.rr_br[i].reg_value;
Packit 577717
		}
Packit 577717
Packit 577717
		r = perfmonctl( pid, PFM_WRITE_DBRS, mont_dbreg,
Packit 577717
						mont_output_param->pfp_mont_drange.rr_nbr_used );
Packit 577717
		if ( r == -1 ) {
Packit 577717
			SUBDBG( "cannot install data range restriction: %s\n",
Packit 577717
					strerror( errno ) );
Packit 577717
			return PAPI_ESYS;
Packit 577717
		}
Packit 577717
		return PAPI_OK;
Packit 577717
		break;
Packit 577717
	default:
Packit 577717
		PAPIERROR( "PMU type %d is not supported by this component",
Packit 577717
				   _perfmon2_pfm_pmu_type );
Packit 577717
		return PAPI_ENOIMPL;
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
/* The routines set_{d,i}range() provide places to install the data and / or
Packit 577717
   instruction address range restrictions for counting qualified events.
Packit 577717
   These routines must set up or clear the appropriate local static data structures.
Packit 577717
   The actual work of loading the hardware registers must be done in update_ctl_state().
Packit 577717
   Both drange and irange can be set on the same eventset.
Packit 577717
   If start=end=0, the feature is disabled. 
Packit 577717
*/
Packit 577717
static  int
Packit 577717
set_drange( hwd_context_t * ctx, hwd_control_state_t * current_state,
Packit 577717
			_papi_int_option_t * option )
Packit 577717
{
Packit 577717
	int ret = PAPI_OK;
Packit 577717
	ia64_control_state_t *this_state = ( ia64_control_state_t * ) current_state;
Packit 577717
	pfmw_param_t *evt = &( this_state->evt );
Packit 577717
	pfmlib_input_param_t *inp = &evt->inp;
Packit 577717
	pfmlib_ita2_input_param_t *ita2_inp =
Packit 577717
		&( this_state->ita_lib_param.ita2_param.ita2_input_param );
Packit 577717
	pfmlib_ita2_output_param_t *ita2_outp =
Packit 577717
		&( this_state->ita_lib_param.ita2_param.ita2_output_param );
Packit 577717
	pfmlib_mont_input_param_t *mont_inp =
Packit 577717
		&( this_state->ita_lib_param.mont_param.mont_input_param );
Packit 577717
	pfmlib_mont_output_param_t *mont_outp =
Packit 577717
		&( this_state->ita_lib_param.mont_param.mont_output_param );
Packit 577717
Packit 577717
	switch ( _perfmon2_pfm_pmu_type ) {
Packit 577717
	case PFMLIB_ITANIUM2_PMU:
Packit 577717
Packit 577717
		if ( ( unsigned long ) option->address_range.start ==
Packit 577717
			 ( unsigned long ) option->address_range.end ||
Packit 577717
			 ( ( unsigned long ) option->address_range.start == 0 &&
Packit 577717
			   ( unsigned long ) option->address_range.end == 0 ) )
Packit 577717
			return ( PAPI_EINVAL );
Packit 577717
		/*
Packit 577717
		 * set the privilege mode:
Packit 577717
		 *  PFM_PLM3 : user level only
Packit 577717
		 */
Packit 577717
		memset( &ita2_inp->pfp_ita2_drange, 0,
Packit 577717
				sizeof ( pfmlib_ita2_input_rr_t ) );
Packit 577717
		memset( ita2_outp, 0, sizeof ( pfmlib_ita2_output_param_t ) );
Packit 577717
		inp->pfp_dfl_plm = PFM_PLM3;
Packit 577717
		ita2_inp->pfp_ita2_drange.rr_used = 1;
Packit 577717
		ita2_inp->pfp_ita2_drange.rr_limits[0].rr_start =
Packit 577717
			( unsigned long ) option->address_range.start;
Packit 577717
		ita2_inp->pfp_ita2_drange.rr_limits[0].rr_end =
Packit 577717
			( unsigned long ) option->address_range.end;
Packit 577717
		SUBDBG
Packit 577717
			( "++++ before data range  : [%#016lx-%#016lx=%ld]: %d pair of debug registers used\n"
Packit 577717
			  "     start_offset:-%#lx end_offset:+%#lx\n",
Packit 577717
			  ita2_inp->pfp_ita2_drange.rr_limits[0].rr_start,
Packit 577717
			  ita2_inp->pfp_ita2_drange.rr_limits[0].rr_end,
Packit 577717
			  ita2_inp->pfp_ita2_drange.rr_limits[0].rr_end -
Packit 577717
			  ita2_inp->pfp_ita2_drange.rr_limits[0].rr_start,
Packit 577717
			  ita2_outp->pfp_ita2_drange.rr_nbr_used >> 1,
Packit 577717
			  ita2_outp->pfp_ita2_drange.rr_infos[0].rr_soff,
Packit 577717
			  ita2_outp->pfp_ita2_drange.rr_infos[0].rr_eoff );
Packit 577717
Packit 577717
		/*
Packit 577717
		 * let the library figure out the values for the PMCS
Packit 577717
		 */
Packit 577717
		if ( ( ret = pfmw_dispatch_events( evt ) ) != PFMLIB_SUCCESS ) {
Packit 577717
			SUBDBG( "cannot configure events: %s\n", pfm_strerror( ret ) );
Packit 577717
		}
Packit 577717
Packit 577717
		SUBDBG
Packit 577717
			( "++++ data range  : [%#016lx-%#016lx=%ld]: %d pair of debug registers used\n"
Packit 577717
			  "     start_offset:-%#lx end_offset:+%#lx\n",
Packit 577717
			  ita2_inp->pfp_ita2_drange.rr_limits[0].rr_start,
Packit 577717
			  ita2_inp->pfp_ita2_drange.rr_limits[0].rr_end,
Packit 577717
			  ita2_inp->pfp_ita2_drange.rr_limits[0].rr_end -
Packit 577717
			  ita2_inp->pfp_ita2_drange.rr_limits[0].rr_start,
Packit 577717
			  ita2_outp->pfp_ita2_drange.rr_nbr_used >> 1,
Packit 577717
			  ita2_outp->pfp_ita2_drange.rr_infos[0].rr_soff,
Packit 577717
			  ita2_outp->pfp_ita2_drange.rr_infos[0].rr_eoff );
Packit 577717
Packit 577717
/*   if(	ita2_inp->pfp_ita2_irange.rr_limits[0].rr_start!=0 || 	ita2_inp->pfp_ita2_irange.rr_limits[0].rr_end!=0 )
Packit 577717
   if((ret=install_irange(ctx, current_state)) ==PAPI_OK){
Packit 577717
	  option->address_range.start_off=ita2_outp->pfp_ita2_irange.rr_infos[0].rr_soff;
Packit 577717
	  option->address_range.end_off=ita2_outp->pfp_ita2_irange.rr_infos[0].rr_eoff;
Packit 577717
   }
Packit 577717
*/
Packit 577717
		if ( ( ret = install_drange( ctx, current_state ) ) == PAPI_OK ) {
Packit 577717
			option->address_range.start_off =
Packit 577717
				ita2_outp->pfp_ita2_drange.rr_infos[0].rr_soff;
Packit 577717
			option->address_range.end_off =
Packit 577717
				ita2_outp->pfp_ita2_drange.rr_infos[0].rr_eoff;
Packit 577717
		}
Packit 577717
		return ( ret );
Packit 577717
Packit 577717
		break;
Packit 577717
	case PFMLIB_MONTECITO_PMU:
Packit 577717
Packit 577717
		if ( ( unsigned long ) option->address_range.start ==
Packit 577717
			 ( unsigned long ) option->address_range.end ||
Packit 577717
			 ( ( unsigned long ) option->address_range.start == 0 &&
Packit 577717
			   ( unsigned long ) option->address_range.end == 0 ) )
Packit 577717
			return ( PAPI_EINVAL );
Packit 577717
		/*
Packit 577717
		 * set the privilege mode:
Packit 577717
		 *  PFM_PLM3 : user level only
Packit 577717
		 */
Packit 577717
		memset( &mont_inp->pfp_mont_drange, 0,
Packit 577717
				sizeof ( pfmlib_mont_input_rr_t ) );
Packit 577717
		memset( mont_outp, 0, sizeof ( pfmlib_mont_output_param_t ) );
Packit 577717
		inp->pfp_dfl_plm = PFM_PLM3;
Packit 577717
		mont_inp->pfp_mont_drange.rr_used = 1;
Packit 577717
		mont_inp->pfp_mont_drange.rr_limits[0].rr_start =
Packit 577717
			( unsigned long ) option->address_range.start;
Packit 577717
		mont_inp->pfp_mont_drange.rr_limits[0].rr_end =
Packit 577717
			( unsigned long ) option->address_range.end;
Packit 577717
		SUBDBG
Packit 577717
			( "++++ before data range  : [%#016lx-%#016lx=%ld]: %d pair of debug registers used\n"
Packit 577717
			  "     start_offset:-%#lx end_offset:+%#lx\n",
Packit 577717
			  mont_inp->pfp_mont_drange.rr_limits[0].rr_start,
Packit 577717
			  mont_inp->pfp_mont_drange.rr_limits[0].rr_end,
Packit 577717
			  mont_inp->pfp_mont_drange.rr_limits[0].rr_end -
Packit 577717
			  mont_inp->pfp_mont_drange.rr_limits[0].rr_start,
Packit 577717
			  mont_outp->pfp_mont_drange.rr_nbr_used >> 1,
Packit 577717
			  mont_outp->pfp_mont_drange.rr_infos[0].rr_soff,
Packit 577717
			  mont_outp->pfp_mont_drange.rr_infos[0].rr_eoff );
Packit 577717
		/*
Packit 577717
		 * let the library figure out the values for the PMCS
Packit 577717
		 */
Packit 577717
		if ( ( ret = pfmw_dispatch_events( evt ) ) != PFMLIB_SUCCESS ) {
Packit 577717
			SUBDBG( "cannot configure events: %s\n", pfm_strerror( ret ) );
Packit 577717
		}
Packit 577717
Packit 577717
		SUBDBG
Packit 577717
			( "++++ data range  : [%#016lx-%#016lx=%ld]: %d pair of debug registers used\n"
Packit 577717
			  "     start_offset:-%#lx end_offset:+%#lx\n",
Packit 577717
			  mont_inp->pfp_mont_drange.rr_limits[0].rr_start,
Packit 577717
			  mont_inp->pfp_mont_drange.rr_limits[0].rr_end,
Packit 577717
			  mont_inp->pfp_mont_drange.rr_limits[0].rr_end -
Packit 577717
			  mont_inp->pfp_mont_drange.rr_limits[0].rr_start,
Packit 577717
			  mont_outp->pfp_mont_drange.rr_nbr_used >> 1,
Packit 577717
			  mont_outp->pfp_mont_drange.rr_infos[0].rr_soff,
Packit 577717
			  mont_outp->pfp_mont_drange.rr_infos[0].rr_eoff );
Packit 577717
Packit 577717
/*   if(	ita2_inp->pfp_ita2_irange.rr_limits[0].rr_start!=0 || 	ita2_inp->pfp_ita2_irange.rr_limits[0].rr_end!=0 )
Packit 577717
   if((ret=install_irange(ctx, current_state)) ==PAPI_OK){
Packit 577717
	  option->address_range.start_off=ita2_outp->pfp_ita2_irange.rr_infos[0].rr_soff;
Packit 577717
	  option->address_range.end_off=ita2_outp->pfp_ita2_irange.rr_infos[0].rr_eoff;
Packit 577717
   }
Packit 577717
*/
Packit 577717
		if ( ( ret = install_drange( ctx, current_state ) ) == PAPI_OK ) {
Packit 577717
			option->address_range.start_off =
Packit 577717
				mont_outp->pfp_mont_drange.rr_infos[0].rr_soff;
Packit 577717
			option->address_range.end_off =
Packit 577717
				mont_outp->pfp_mont_drange.rr_infos[0].rr_eoff;
Packit 577717
		}
Packit 577717
		return ( ret );
Packit 577717
Packit 577717
		break;
Packit 577717
	default:
Packit 577717
		PAPIERROR( "PMU type %d is not supported by this component",
Packit 577717
				   _perfmon2_pfm_pmu_type );
Packit 577717
		return PAPI_ENOIMPL;
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
set_irange( hwd_context_t * ctx, hwd_control_state_t * current_state,
Packit 577717
			_papi_int_option_t * option )
Packit 577717
{
Packit 577717
	int ret = PAPI_OK;
Packit 577717
	ia64_control_state_t *this_state = ( ia64_control_state_t * ) current_state;
Packit 577717
	pfmw_param_t *evt = &( this_state->evt );
Packit 577717
	pfmlib_input_param_t *inp = &evt->inp;
Packit 577717
	pfmlib_ita2_input_param_t *ita2_inp =
Packit 577717
		&( this_state->ita_lib_param.ita2_param.ita2_input_param );
Packit 577717
	pfmlib_ita2_output_param_t *ita2_outp =
Packit 577717
		&( this_state->ita_lib_param.ita2_param.ita2_output_param );
Packit 577717
	pfmlib_mont_input_param_t *mont_inp =
Packit 577717
		&( this_state->ita_lib_param.mont_param.mont_input_param );
Packit 577717
	pfmlib_mont_output_param_t *mont_outp =
Packit 577717
		&( this_state->ita_lib_param.mont_param.mont_output_param );
Packit 577717
Packit 577717
	switch ( _perfmon2_pfm_pmu_type ) {
Packit 577717
	case PFMLIB_ITANIUM2_PMU:
Packit 577717
Packit 577717
		if ( ( unsigned long ) option->address_range.start ==
Packit 577717
			 ( unsigned long ) option->address_range.end ||
Packit 577717
			 ( ( unsigned long ) option->address_range.start == 0 &&
Packit 577717
			   ( unsigned long ) option->address_range.end == 0 ) )
Packit 577717
			return ( PAPI_EINVAL );
Packit 577717
		/*
Packit 577717
		 * set the privilege mode:
Packit 577717
		 *    PFM_PLM3 : user level only
Packit 577717
		 */
Packit 577717
		memset( &ita2_inp->pfp_ita2_irange, 0,
Packit 577717
				sizeof ( pfmlib_ita2_input_rr_t ) );
Packit 577717
		memset( ita2_outp, 0, sizeof ( pfmlib_ita2_output_param_t ) );
Packit 577717
		inp->pfp_dfl_plm = PFM_PLM3;
Packit 577717
		ita2_inp->pfp_ita2_irange.rr_used = 1;
Packit 577717
		ita2_inp->pfp_ita2_irange.rr_limits[0].rr_start =
Packit 577717
			( unsigned long ) option->address_range.start;
Packit 577717
		ita2_inp->pfp_ita2_irange.rr_limits[0].rr_end =
Packit 577717
			( unsigned long ) option->address_range.end;
Packit 577717
		SUBDBG
Packit 577717
			( "++++ before code range  : [%#016lx-%#016lx=%ld]: %d pair of debug registers used\n"
Packit 577717
			  "     start_offset:-%#lx end_offset:+%#lx\n",
Packit 577717
			  ita2_inp->pfp_ita2_irange.rr_limits[0].rr_start,
Packit 577717
			  ita2_inp->pfp_ita2_irange.rr_limits[0].rr_end,
Packit 577717
			  ita2_inp->pfp_ita2_irange.rr_limits[0].rr_end -
Packit 577717
			  ita2_inp->pfp_ita2_irange.rr_limits[0].rr_start,
Packit 577717
			  ita2_outp->pfp_ita2_irange.rr_nbr_used >> 1,
Packit 577717
			  ita2_outp->pfp_ita2_irange.rr_infos[0].rr_soff,
Packit 577717
			  ita2_outp->pfp_ita2_irange.rr_infos[0].rr_eoff );
Packit 577717
Packit 577717
		/*
Packit 577717
		 * let the library figure out the values for the PMCS
Packit 577717
		 */
Packit 577717
		if ( ( ret = pfmw_dispatch_events( evt ) ) != PFMLIB_SUCCESS ) {
Packit 577717
			SUBDBG( "cannot configure events: %s\n", pfm_strerror( ret ) );
Packit 577717
		}
Packit 577717
Packit 577717
		SUBDBG
Packit 577717
			( "++++ code range  : [%#016lx-%#016lx=%ld]: %d pair of debug registers used\n"
Packit 577717
			  "     start_offset:-%#lx end_offset:+%#lx\n",
Packit 577717
			  ita2_inp->pfp_ita2_irange.rr_limits[0].rr_start,
Packit 577717
			  ita2_inp->pfp_ita2_irange.rr_limits[0].rr_end,
Packit 577717
			  ita2_inp->pfp_ita2_irange.rr_limits[0].rr_end -
Packit 577717
			  ita2_inp->pfp_ita2_irange.rr_limits[0].rr_start,
Packit 577717
			  ita2_outp->pfp_ita2_irange.rr_nbr_used >> 1,
Packit 577717
			  ita2_outp->pfp_ita2_irange.rr_infos[0].rr_soff,
Packit 577717
			  ita2_outp->pfp_ita2_irange.rr_infos[0].rr_eoff );
Packit 577717
		if ( ( ret = install_irange( ctx, current_state ) ) == PAPI_OK ) {
Packit 577717
			option->address_range.start_off =
Packit 577717
				ita2_outp->pfp_ita2_irange.rr_infos[0].rr_soff;
Packit 577717
			option->address_range.end_off =
Packit 577717
				ita2_outp->pfp_ita2_irange.rr_infos[0].rr_eoff;
Packit 577717
		}
Packit 577717
Packit 577717
		break;
Packit 577717
	case PFMLIB_MONTECITO_PMU:
Packit 577717
Packit 577717
		if ( ( unsigned long ) option->address_range.start ==
Packit 577717
			 ( unsigned long ) option->address_range.end ||
Packit 577717
			 ( ( unsigned long ) option->address_range.start == 0 &&
Packit 577717
			   ( unsigned long ) option->address_range.end == 0 ) )
Packit 577717
			return ( PAPI_EINVAL );
Packit 577717
		/*
Packit 577717
		 * set the privilege mode:
Packit 577717
		 *  PFM_PLM3 : user level only
Packit 577717
		 */
Packit 577717
		memset( &mont_inp->pfp_mont_irange, 0,
Packit 577717
				sizeof ( pfmlib_mont_input_rr_t ) );
Packit 577717
		memset( mont_outp, 0, sizeof ( pfmlib_mont_output_param_t ) );
Packit 577717
		inp->pfp_dfl_plm = PFM_PLM3;
Packit 577717
		mont_inp->pfp_mont_irange.rr_used = 1;
Packit 577717
		mont_inp->pfp_mont_irange.rr_limits[0].rr_start =
Packit 577717
			( unsigned long ) option->address_range.start;
Packit 577717
		mont_inp->pfp_mont_irange.rr_limits[0].rr_end =
Packit 577717
			( unsigned long ) option->address_range.end;
Packit 577717
		SUBDBG
Packit 577717
			( "++++ before code range  : [%#016lx-%#016lx=%ld]: %d pair of debug registers used\n"
Packit 577717
			  "     start_offset:-%#lx end_offset:+%#lx\n",
Packit 577717
			  mont_inp->pfp_mont_irange.rr_limits[0].rr_start,
Packit 577717
			  mont_inp->pfp_mont_irange.rr_limits[0].rr_end,
Packit 577717
			  mont_inp->pfp_mont_irange.rr_limits[0].rr_end -
Packit 577717
			  mont_inp->pfp_mont_irange.rr_limits[0].rr_start,
Packit 577717
			  mont_outp->pfp_mont_irange.rr_nbr_used >> 1,
Packit 577717
			  mont_outp->pfp_mont_irange.rr_infos[0].rr_soff,
Packit 577717
			  mont_outp->pfp_mont_irange.rr_infos[0].rr_eoff );
Packit 577717
Packit 577717
		/*
Packit 577717
		 * let the library figure out the values for the PMCS
Packit 577717
		 */
Packit 577717
		if ( ( ret = pfmw_dispatch_events( evt ) ) != PFMLIB_SUCCESS ) {
Packit 577717
			SUBDBG( "cannot configure events: %s\n", pfm_strerror( ret ) );
Packit 577717
		}
Packit 577717
Packit 577717
		SUBDBG
Packit 577717
			( "++++ code range  : [%#016lx-%#016lx=%ld]: %d pair of debug registers used\n"
Packit 577717
			  "     start_offset:-%#lx end_offset:+%#lx\n",
Packit 577717
			  mont_inp->pfp_mont_irange.rr_limits[0].rr_start,
Packit 577717
			  mont_inp->pfp_mont_irange.rr_limits[0].rr_end,
Packit 577717
			  mont_inp->pfp_mont_irange.rr_limits[0].rr_end -
Packit 577717
			  mont_inp->pfp_mont_irange.rr_limits[0].rr_start,
Packit 577717
			  mont_outp->pfp_mont_irange.rr_nbr_used >> 1,
Packit 577717
			  mont_outp->pfp_mont_irange.rr_infos[0].rr_soff,
Packit 577717
			  mont_outp->pfp_mont_irange.rr_infos[0].rr_eoff );
Packit 577717
		if ( ( ret = install_irange( ctx, current_state ) ) == PAPI_OK ) {
Packit 577717
			option->address_range.start_off =
Packit 577717
				mont_outp->pfp_mont_irange.rr_infos[0].rr_soff;
Packit 577717
			option->address_range.end_off =
Packit 577717
				mont_outp->pfp_mont_irange.rr_infos[0].rr_eoff;
Packit 577717
		}
Packit 577717
Packit 577717
		break;
Packit 577717
	default:
Packit 577717
		PAPIERROR( "PMU type %d is not supported by this component",
Packit 577717
				   _perfmon2_pfm_pmu_type );
Packit 577717
		return PAPI_ENOIMPL;
Packit 577717
	}
Packit 577717
Packit 577717
	return ret;
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
pfmw_get_num_counters( int *num )
Packit 577717
{
Packit 577717
	unsigned int tmp;
Packit 577717
	if ( pfm_get_num_counters( &tmp ) != PFMLIB_SUCCESS )
Packit 577717
		return ( PAPI_ESYS );
Packit 577717
	*num = tmp;
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
pfmw_get_num_events( int *num )
Packit 577717
{
Packit 577717
	unsigned int tmp;
Packit 577717
	if ( pfm_get_num_events( &tmp ) != PFMLIB_SUCCESS )
Packit 577717
		return ( PAPI_ESYS );
Packit 577717
	*num = tmp;
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/* Globals declared extern elsewhere */
Packit 577717
Packit 577717
hwi_search_t *preset_search_map;
Packit 577717
extern papi_vector_t _ia64_vector;
Packit 577717
Packit 577717
unsigned int PAPI_NATIVE_EVENT_AND_MASK = 0x000003ff;
Packit 577717
unsigned int PAPI_NATIVE_EVENT_SHIFT = 0;
Packit 577717
unsigned int PAPI_NATIVE_UMASK_AND_MASK = 0x03fffc00;
Packit 577717
unsigned int PAPI_NATIVE_UMASK_MAX = 16;
Packit 577717
unsigned int PAPI_NATIVE_UMASK_SHIFT = 10;
Packit 577717
Packit 577717
/* Static locals */
Packit 577717
Packit 577717
int _perfmon2_pfm_pmu_type = -1;
Packit 577717
Packit 577717
/*
Packit 577717
static papi_svector_t _linux_ia64_table[] = {
Packit 577717
 {(void (*)())_papi_hwd_update_shlib_info, VEC_PAPI_HWD_UPDATE_SHLIB_INFO},
Packit 577717
 {(void (*)())_papi_hwd_init, VEC_PAPI_HWD_INIT},
Packit 577717
 {(void (*)())_papi_hwd_init_control_state, VEC_PAPI_HWD_INIT_CONTROL_STATE},
Packit 577717
 {(void (*)())_papi_hwd_dispatch_timer, VEC_PAPI_HWD_DISPATCH_TIMER},
Packit 577717
 {(void (*)())_papi_hwd_ctl, VEC_PAPI_HWD_CTL},
Packit 577717
 {(void (*)())_papi_hwd_get_real_usec, VEC_PAPI_HWD_GET_REAL_USEC},
Packit 577717
 {(void (*)())_papi_hwd_get_real_cycles, VEC_PAPI_HWD_GET_REAL_CYCLES},
Packit 577717
 {(void (*)())_papi_hwd_get_virt_cycles, VEC_PAPI_HWD_GET_VIRT_CYCLES},
Packit 577717
 {(void (*)())_papi_hwd_get_virt_usec, VEC_PAPI_HWD_GET_VIRT_USEC},
Packit 577717
 {(void (*)())_papi_hwd_update_control_state,VEC_PAPI_HWD_UPDATE_CONTROL_STATE}, 
Packit 577717
 {(void (*)())_papi_hwd_start, VEC_PAPI_HWD_START },
Packit 577717
 {(void (*)())_papi_hwd_stop, VEC_PAPI_HWD_STOP },
Packit 577717
 {(void (*)())_papi_hwd_read, VEC_PAPI_HWD_READ },
Packit 577717
 {(void (*)())_papi_hwd_shutdown, VEC_PAPI_HWD_SHUTDOWN },
Packit 577717
 {(void (*)())_papi_hwd_reset, VEC_PAPI_HWD_RESET},
Packit 577717
 {(void (*)())_papi_hwd_set_profile, VEC_PAPI_HWD_SET_PROFILE},
Packit 577717
 {(void (*)())_papi_hwd_stop_profiling, VEC_PAPI_HWD_STOP_PROFILING},
Packit 577717
 {(void (*)())_papi_hwd_get_dmem_info, VEC_PAPI_HWD_GET_DMEM_INFO},
Packit 577717
 {(void (*)())_papi_hwd_set_overflow, VEC_PAPI_HWD_SET_OVERFLOW},
Packit 577717
 {(void (*)())_papi_hwd_ntv_enum_events, VEC_PAPI_HWD_NTV_ENUM_EVENTS},
Packit 577717
 {(void (*)())_papi_hwd_ntv_code_to_name, VEC_PAPI_HWD_NTV_CODE_TO_NAME},
Packit 577717
 {(void (*)())_papi_hwd_ntv_code_to_descr, VEC_PAPI_HWD_NTV_CODE_TO_DESCR},
Packit 577717
 {NULL, VEC_PAPI_END}
Packit 577717
};
Packit 577717
*/
Packit 577717
Packit 577717
static itanium_preset_search_t ia1_preset_search_map[] = {
Packit 577717
	{PAPI_L1_TCM, DERIVED_ADD,
Packit 577717
	 {"L1D_READ_MISSES_RETIRED", "L2_INST_DEMAND_READS"}, {0}},
Packit 577717
	{PAPI_L1_ICM, 0, {"L2_INST_DEMAND_READS"}, {0}},
Packit 577717
	{PAPI_L1_DCM, 0, {"L1D_READ_MISSES_RETIRED"}, {0}},
Packit 577717
	{PAPI_L2_TCM, 0, {"L2_MISSES"}, {0}},
Packit 577717
	{PAPI_L2_DCM, DERIVED_SUB, {"L2_MISSES", "L3_READS_INST_READS_ALL"}, {0}},
Packit 577717
	{PAPI_L2_ICM, 0, {"L3_READS_INST_READS_ALL"}, {0}},
Packit 577717
	{PAPI_L3_TCM, 0, {"L3_MISSES"}, {0}},
Packit 577717
	{PAPI_L3_ICM, 0, {"L3_READS_INST_READS_MISS"}, {0}},
Packit 577717
	{PAPI_L3_DCM, DERIVED_ADD,
Packit 577717
	 {"L3_READS_DATA_READS_MISS", "L3_WRITES_DATA_WRITES_MISS"}, {0}},
Packit 577717
	{PAPI_L3_LDM, 0, {"L3_READS_DATA_READS_MISS"}, {0}},
Packit 577717
	{PAPI_L3_STM, 0, {"L3_WRITES_DATA_WRITES_MISS"}, {0}},
Packit 577717
	{PAPI_L1_LDM, 0, {"L1D_READ_MISSES_RETIRED"}, {0}},
Packit 577717
	{PAPI_L2_LDM, 0, {"L3_READS_DATA_READS_ALL"}, {0}},
Packit 577717
	{PAPI_L2_STM, 0, {"L3_WRITES_ALL_WRITES_ALL"}, {0}},
Packit 577717
	{PAPI_L3_DCH, DERIVED_ADD,
Packit 577717
	 {"L3_READS_DATA_READS_HIT", "L3_WRITES_DATA_WRITES_HIT"}, {0}},
Packit 577717
	{PAPI_L1_DCH, DERIVED_SUB, {"L1D_READS_RETIRED", "L1D_READ_MISSES_RETIRED"},
Packit 577717
	 {0}},
Packit 577717
	{PAPI_L1_DCA, 0, {"L1D_READS_RETIRED"}, {0}},
Packit 577717
	{PAPI_L2_DCA, 0, {"L2_DATA_REFERENCES_ALL"}, {0}},
Packit 577717
	{PAPI_L3_DCA, DERIVED_ADD,
Packit 577717
	 {"L3_READS_DATA_READS_ALL", "L3_WRITES_DATA_WRITES_ALL"}, {0}},
Packit 577717
	{PAPI_L2_DCR, 0, {"L2_DATA_REFERENCES_READS"}, {0}},
Packit 577717
	{PAPI_L3_DCR, 0, {"L3_READS_DATA_READS_ALL"}, {0}},
Packit 577717
	{PAPI_L2_DCW, 0, {"L2_DATA_REFERENCES_WRITES"}, {0}},
Packit 577717
	{PAPI_L3_DCW, 0, {"L3_WRITES_DATA_WRITES_ALL"}, {0}},
Packit 577717
	{PAPI_L3_ICH, 0, {"L3_READS_INST_READS_HIT"}, {0}},
Packit 577717
	{PAPI_L1_ICR, DERIVED_ADD, {"L1I_PREFETCH_READS", "L1I_DEMAND_READS"}, {0}},
Packit 577717
	{PAPI_L2_ICR, DERIVED_ADD,
Packit 577717
	 {"L2_INST_DEMAND_READS", "L2_INST_PREFETCH_READS"}, {0}},
Packit 577717
	{PAPI_L3_ICR, 0, {"L3_READS_INST_READS_ALL"}, {0}},
Packit 577717
	{PAPI_TLB_DM, 0, {"DTLB_MISSES"}, {0}},
Packit 577717
	{PAPI_TLB_IM, 0, {"ITLB_MISSES_FETCH"}, {0}},
Packit 577717
	{PAPI_MEM_SCY, 0, {"MEMORY_CYCLE"}, {0}},
Packit 577717
	{PAPI_STL_ICY, 0, {"UNSTALLED_BACKEND_CYCLE"}, {0}},
Packit 577717
	{PAPI_BR_INS, 0, {"BRANCH_EVENT"}, {0}},
Packit 577717
	{PAPI_BR_PRC, 0, {"BRANCH_PREDICTOR_ALL_CORRECT_PREDICTIONS"}, {0}},
Packit 577717
	{PAPI_BR_MSP, DERIVED_ADD,
Packit 577717
	 {"BRANCH_PREDICTOR_ALL_WRONG_PATH", "BRANCH_PREDICTOR_ALL_WRONG_TARGET"},
Packit 577717
	 {0}},
Packit 577717
	{PAPI_TOT_CYC, 0, {"CPU_CYCLES"}, {0}},
Packit 577717
	{PAPI_FP_OPS, DERIVED_ADD, {"FP_OPS_RETIRED_HI", "FP_OPS_RETIRED_LO"}, {0}},
Packit 577717
	{PAPI_TOT_INS, 0, {"IA64_INST_RETIRED"}, {0}},
Packit 577717
	{PAPI_LD_INS, 0, {"LOADS_RETIRED"}, {0}},
Packit 577717
	{PAPI_SR_INS, 0, {"STORES_RETIRED"}, {0}},
Packit 577717
	{PAPI_LST_INS, DERIVED_ADD, {"LOADS_RETIRED", "STORES_RETIRED"}, {0}},
Packit 577717
	{0, 0, {0}, {0}}
Packit 577717
};
Packit 577717
Packit 577717
static itanium_preset_search_t ia2_preset_search_map[] = {
Packit 577717
	{PAPI_CA_SNP, 0, {"BUS_SNOOPS_SELF"}, {0}},
Packit 577717
	{PAPI_CA_INV, DERIVED_ADD,
Packit 577717
	 {"BUS_MEM_READ_BRIL_SELF", "BUS_MEM_READ_BIL_SELF"}, {0}},
Packit 577717
	{PAPI_TLB_TL, DERIVED_ADD, {"ITLB_MISSES_FETCH_L2ITLB", "L2DTLB_MISSES"},
Packit 577717
	 {0}},
Packit 577717
	{PAPI_STL_ICY, 0, {"DISP_STALLED"}, {0}},
Packit 577717
	{PAPI_STL_CCY, 0, {"BACK_END_BUBBLE_ALL"}, {0}},
Packit 577717
	{PAPI_TOT_IIS, 0, {"INST_DISPERSED"}, {0}},
Packit 577717
	{PAPI_RES_STL, 0, {"BE_EXE_BUBBLE_ALL"}, {0}},
Packit 577717
	{PAPI_FP_STAL, 0, {"BE_EXE_BUBBLE_FRALL"}, {0}},
Packit 577717
	{PAPI_L2_TCR, DERIVED_ADD,
Packit 577717
	 {"L2_DATA_REFERENCES_L2_DATA_READS", "L2_INST_DEMAND_READS",
Packit 577717
	  "L2_INST_PREFETCHES"}, {0}},
Packit 577717
	{PAPI_L1_TCM, DERIVED_ADD, {"L2_INST_DEMAND_READS", "L1D_READ_MISSES_ALL"},
Packit 577717
	 {0}},
Packit 577717
	{PAPI_L1_ICM, 0, {"L2_INST_DEMAND_READS"}, {0}},
Packit 577717
	{PAPI_L1_DCM, 0, {"L1D_READ_MISSES_ALL"}, {0}},
Packit 577717
	{PAPI_L2_TCM, 0, {"L2_MISSES"}, {0}},
Packit 577717
	{PAPI_L2_DCM, DERIVED_SUB, {"L2_MISSES", "L3_READS_INST_FETCH_ALL"}, {0}},
Packit 577717
	{PAPI_L2_ICM, 0, {"L3_READS_INST_FETCH_ALL"}, {0}},
Packit 577717
	{PAPI_L3_TCM, 0, {"L3_MISSES"}, {0}},
Packit 577717
	{PAPI_L3_ICM, 0, {"L3_READS_INST_FETCH_MISS"}, {0}},
Packit 577717
	{PAPI_L3_DCM, DERIVED_ADD,
Packit 577717
	 {"L3_READS_DATA_READ_MISS", "L3_WRITES_DATA_WRITE_MISS"}, {0}},
Packit 577717
	{PAPI_L3_LDM, 0, {"L3_READS_ALL_MISS"}, {0}},
Packit 577717
	{PAPI_L3_STM, 0, {"L3_WRITES_DATA_WRITE_MISS"}, {0}},
Packit 577717
	{PAPI_L1_LDM, DERIVED_ADD, {"L1D_READ_MISSES_ALL", "L2_INST_DEMAND_READS"},
Packit 577717
	 {0}},
Packit 577717
	{PAPI_L2_LDM, 0, {"L3_READS_ALL_ALL"}, {0}},
Packit 577717
	{PAPI_L2_STM, 0, {"L3_WRITES_ALL_ALL"}, {0}},
Packit 577717
	{PAPI_L1_DCH, DERIVED_SUB, {"L1D_READS_SET1", "L1D_READ_MISSES_ALL"}, {0}},
Packit 577717
	{PAPI_L2_DCH, DERIVED_SUB, {"L2_DATA_REFERENCES_L2_ALL", "L2_MISSES"}, {0}},
Packit 577717
	{PAPI_L3_DCH, DERIVED_ADD,
Packit 577717
	 {"L3_READS_DATA_READ_HIT", "L3_WRITES_DATA_WRITE_HIT"}, {0}},
Packit 577717
	{PAPI_L1_DCA, 0, {"L1D_READS_SET1"}, {0}},
Packit 577717
	{PAPI_L2_DCA, 0, {"L2_DATA_REFERENCES_L2_ALL"}, {0}},
Packit 577717
	{PAPI_L3_DCA, DERIVED_ADD,
Packit 577717
	 {"L3_READS_DATA_READ_ALL", "L3_WRITES_DATA_WRITE_ALL"}, {0}},
Packit 577717
	{PAPI_L1_DCR, 0, {"L1D_READS_SET1"}, {0}},
Packit 577717
	{PAPI_L2_DCR, 0, {"L2_DATA_REFERENCES_L2_DATA_READS"}, {0}},
Packit 577717
	{PAPI_L3_DCR, 0, {"L3_READS_DATA_READ_ALL"}, {0}},
Packit 577717
	{PAPI_L2_DCW, 0, {"L2_DATA_REFERENCES_L2_DATA_WRITES"}, {0}},
Packit 577717
	{PAPI_L3_DCW, 0, {"L3_WRITES_DATA_WRITE_ALL"}, {0}},
Packit 577717
	{PAPI_L3_ICH, 0, {"L3_READS_DINST_FETCH_HIT"}, {0}},
Packit 577717
	{PAPI_L1_ICR, DERIVED_ADD, {"L1I_PREFETCHES", "L1I_READS"}, {0}},
Packit 577717
	{PAPI_L2_ICR, DERIVED_ADD, {"L2_INST_DEMAND_READS", "L2_INST_PREFETCHES"},
Packit 577717
	 {0}},
Packit 577717
	{PAPI_L3_ICR, 0, {"L3_READS_INST_FETCH_ALL"}, {0}},
Packit 577717
	{PAPI_L1_ICA, DERIVED_ADD, {"L1I_PREFETCHES", "L1I_READS"}, {0}},
Packit 577717
	{PAPI_L2_TCH, DERIVED_SUB, {"L2_REFERENCES", "L2_MISSES"}, {0}},
Packit 577717
	{PAPI_L3_TCH, DERIVED_SUB, {"L3_REFERENCES", "L3_MISSES"}, {0}},
Packit 577717
	{PAPI_L2_TCA, 0, {"L2_REFERENCES"}, {0}},
Packit 577717
	{PAPI_L3_TCA, 0, {"L3_REFERENCES"}, {0}},
Packit 577717
	{PAPI_L3_TCR, 0, {"L3_READS_ALL_ALL"}, {0}},
Packit 577717
	{PAPI_L3_TCW, 0, {"L3_WRITES_ALL_ALL"}, {0}},
Packit 577717
	{PAPI_TLB_DM, 0, {"L2DTLB_MISSES"}, {0}},
Packit 577717
	{PAPI_TLB_IM, 0, {"ITLB_MISSES_FETCH_L2ITLB"}, {0}},
Packit 577717
	{PAPI_BR_INS, 0, {"BRANCH_EVENT"}, {0}},
Packit 577717
	{PAPI_BR_PRC, 0, {"BR_MISPRED_DETAIL_ALL_CORRECT_PRED"}, {0}},
Packit 577717
	{PAPI_BR_MSP, DERIVED_ADD,
Packit 577717
	 {"BR_MISPRED_DETAIL_ALL_WRONG_PATH", "BR_MISPRED_DETAIL_ALL_WRONG_TARGET"},
Packit 577717
	 {0}},
Packit 577717
	{PAPI_TOT_CYC, 0, {"CPU_CYCLES"}, {0}},
Packit 577717
	{PAPI_FP_OPS, 0, {"FP_OPS_RETIRED"}, {0}},
Packit 577717
	{PAPI_TOT_INS, DERIVED_ADD, {"IA64_INST_RETIRED", "IA32_INST_RETIRED"},
Packit 577717
	 {0}},
Packit 577717
	{PAPI_LD_INS, 0, {"LOADS_RETIRED"}, {0}},
Packit 577717
	{PAPI_SR_INS, 0, {"STORES_RETIRED"}, {0}},
Packit 577717
	{PAPI_L2_ICA, 0, {"L2_INST_DEMAND_READS"}, {0}},
Packit 577717
	{PAPI_L3_ICA, 0, {"L3_READS_INST_FETCH_ALL"}, {0}},
Packit 577717
	{PAPI_L1_TCR, DERIVED_ADD, {"L1D_READS_SET0", "L1I_READS"}, {0}},
Packit 577717
	{PAPI_L1_TCA, DERIVED_ADD, {"L1D_READS_SET0", "L1I_READS"}, {0}},
Packit 577717
	{PAPI_L2_TCW, 0, {"L2_DATA_REFERENCES_L2_DATA_WRITES"}, {0}},
Packit 577717
	{0, 0, {0}, {0}}
Packit 577717
};
Packit 577717
Packit 577717
static itanium_preset_search_t ia3_preset_search_map[] = {
Packit 577717
/* not sure */
Packit 577717
	{PAPI_CA_SNP, 0, {"BUS_SNOOP_STALL_CYCLES_ANY"}, {0}},
Packit 577717
	{PAPI_CA_INV, DERIVED_ADD,
Packit 577717
	 {"BUS_MEM_READ_BRIL_SELF", "BUS_MEM_READ_BIL_SELF"}, {0}},
Packit 577717
/* should be OK */
Packit 577717
	{PAPI_TLB_TL, DERIVED_ADD, {"ITLB_MISSES_FETCH_L2ITLB", "L2DTLB_MISSES"},
Packit 577717
	 {0}},
Packit 577717
	{PAPI_STL_ICY, 0, {"DISP_STALLED"}, {0}},
Packit 577717
	{PAPI_STL_CCY, 0, {"BACK_END_BUBBLE_ALL"}, {0}},
Packit 577717
	{PAPI_TOT_IIS, 0, {"INST_DISPERSED"}, {0}},
Packit 577717
	{PAPI_RES_STL, 0, {"BE_EXE_BUBBLE_ALL"}, {0}},
Packit 577717
	{PAPI_FP_STAL, 0, {"BE_EXE_BUBBLE_FRALL"}, {0}},
Packit 577717
/* should be OK */
Packit 577717
	{PAPI_L2_TCR, DERIVED_ADD,
Packit 577717
	 {"L2D_REFERENCES_READS", "L2I_READS_ALL_DMND", "L2I_READS_ALL_PFTCH"},
Packit 577717
	 {0}},
Packit 577717
/* what is the correct name here: L2I_READS_ALL_DMND or L2I_DEMANDS_READ ?
Packit 577717
 * do not have papi_native_avail at this time, going to use L2I_READS_ALL_DMND always
Packit 577717
 * just replace on demand
Packit 577717
 */
Packit 577717
	{PAPI_L1_TCM, DERIVED_ADD, {"L2I_READS_ALL_DMND", "L1D_READ_MISSES_ALL"},
Packit 577717
	 {0}},
Packit 577717
	{PAPI_L1_ICM, 0, {"L2I_READS_ALL_DMND"}, {0}},
Packit 577717
	{PAPI_L1_DCM, 0, {"L1D_READ_MISSES_ALL"}, {0}},
Packit 577717
	{PAPI_L2_TCM, 0, {"L2I_READS_MISS_ALL", "L2D_MISSES"}, {0}},
Packit 577717
	{PAPI_L2_DCM, DERIVED_SUB, {"L2D_MISSES"}, {0}},
Packit 577717
	{PAPI_L2_ICM, 0, {"L2I_READS_MISS_ALL"}, {0}},
Packit 577717
	{PAPI_L3_TCM, 0, {"L3_MISSES"}, {0}},
Packit 577717
	{PAPI_L3_ICM, 0, {"L3_READS_INST_FETCH_MISS:M:E:S:I"}, {0}},
Packit 577717
	{PAPI_L3_DCM, DERIVED_ADD,
Packit 577717
	 {"L3_READS_DATA_READ_MISS:M:E:S:I", "L3_WRITES_DATA_WRITE_MISS:M:E:S:I"},
Packit 577717
	 {0}},
Packit 577717
	{PAPI_L3_LDM, 0, {"L3_READS_ALL_MISS:M:E:S:I"}, {0}},
Packit 577717
	{PAPI_L3_STM, 0, {"L3_WRITES_DATA_WRITE_MISS:M:E:S:I"}, {0}},
Packit 577717
/* why L2_INST_DEMAND_READS has been added here for the Itanium II ?
Packit 577717
 * OLD:  {PAPI_L1_LDM, DERIVED_ADD, {"L1D_READ_MISSES_ALL", "L2_INST_DEMAND_READS", 0, 0}}
Packit 577717
 */
Packit 577717
	{PAPI_L1_LDM, 0, {"L1D_READ_MISSES_ALL"}, {0}},
Packit 577717
	{PAPI_L2_LDM, 0, {"L3_READS_ALL_ALL:M:E:S:I"}, {0}},
Packit 577717
	{PAPI_L2_STM, 0, {"L3_WRITES_ALL_ALL:M:E:S:I"}, {0}},
Packit 577717
	{PAPI_L1_DCH, DERIVED_SUB, {"L1D_READS_SET1", "L1D_READ_MISSES_ALL"}, {0}},
Packit 577717
	{PAPI_L2_DCH, DERIVED_SUB, {"L2D_REFERENCES_ALL", "L2D_MISSES"}, {0}},
Packit 577717
	{PAPI_L3_DCH, DERIVED_ADD,
Packit 577717
	 {"L3_READS_DATA_READ_HIT:M:E:S:I", "L3_WRITES_DATA_WRITE_HIT:M:E:S:I"},
Packit 577717
	 {0}},
Packit 577717
	{PAPI_L1_DCA, 0, {"L1D_READS_SET1"}, {0}},
Packit 577717
	{PAPI_L2_DCA, 0, {"L2D_REFERENCES_ALL"}, {0}},
Packit 577717
	{PAPI_L3_DCA, 0, {"L3_REFERENCES"}, {0}},
Packit 577717
	{PAPI_L1_DCR, 0, {"L1D_READS_SET1"}, {0}},
Packit 577717
	{PAPI_L2_DCR, 0, {"L2D_REFERENCES_READS"}, {0}},
Packit 577717
	{PAPI_L3_DCR, 0, {"L3_READS_DATA_READ_ALL:M:E:S:I"}, {0}},
Packit 577717
	{PAPI_L2_DCW, 0, {"L2D_REFERENCES_WRITES"}, {0}},
Packit 577717
	{PAPI_L3_DCW, 0, {"L3_WRITES_DATA_WRITE_ALL:M:E:S:I"}, {0}},
Packit 577717
	{PAPI_L3_ICH, 0, {"L3_READS_DINST_FETCH_HIT:M:E:S:I"}, {0}},
Packit 577717
	{PAPI_L1_ICR, DERIVED_ADD, {"L1I_PREFETCHES", "L1I_READS"}, {0}},
Packit 577717
	{PAPI_L2_ICR, DERIVED_ADD, {"L2I_READS_ALL_DMND", "L2I_PREFETCHES"}, {0}},
Packit 577717
	{PAPI_L3_ICR, 0, {"L3_READS_INST_FETCH_ALL:M:E:S:I"}, {0}},
Packit 577717
	{PAPI_L1_ICA, DERIVED_ADD, {"L1I_PREFETCHES", "L1I_READS"}, {0}},
Packit 577717
	{PAPI_L2_TCH, DERIVED_SUB, {"L2I_READS_HIT_ALL", "L2D_INSERT_HITS"}, {0}},
Packit 577717
	{PAPI_L3_TCH, DERIVED_SUB, {"L3_REFERENCES", "L3_MISSES"}, {0}},
Packit 577717
	{PAPI_L2_TCA, DERIVED_ADD, {"L2I_READS_ALL_ALL", "L2D_REFERENCES_ALL"},
Packit 577717
	 {0}},
Packit 577717
	{PAPI_L3_TCA, 0, {"L3_REFERENCES"}, {0}},
Packit 577717
	{PAPI_L3_TCR, 0, {"L3_READS_ALL_ALL:M:E:S:I"}, {0}},
Packit 577717
	{PAPI_L3_TCW, 0, {"L3_WRITES_ALL_ALL:M:E:S:I"}, {0}},
Packit 577717
	{PAPI_TLB_DM, 0, {"L2DTLB_MISSES"}, {0}},
Packit 577717
	{PAPI_TLB_IM, 0, {"ITLB_MISSES_FETCH_L2ITLB"}, {0}},
Packit 577717
	{PAPI_BR_INS, 0, {"BRANCH_EVENT"}, {0}},
Packit 577717
	{PAPI_BR_PRC, 0, {"BR_MISPRED_DETAIL_ALL_CORRECT_PRED"}, {0}},
Packit 577717
	{PAPI_BR_MSP, DERIVED_ADD,
Packit 577717
	 {"BR_MISPRED_DETAIL_ALL_WRONG_PATH", "BR_MISPRED_DETAIL_ALL_WRONG_TARGET"},
Packit 577717
	 {0}},
Packit 577717
	{PAPI_TOT_CYC, 0, {"CPU_OP_CYCLES_ALL"}, {0}},
Packit 577717
	{PAPI_FP_OPS, 0, {"FP_OPS_RETIRED"}, {0}},
Packit 577717
//   {PAPI_TOT_INS, DERIVED_ADD, {"IA64_INST_RETIRED", "IA32_INST_RETIRED"}, {0}},
Packit 577717
	{PAPI_TOT_INS, 0, {"IA64_INST_RETIRED"}, {0}},
Packit 577717
	{PAPI_LD_INS, 0, {"LOADS_RETIRED"}, {0}},
Packit 577717
	{PAPI_SR_INS, 0, {"STORES_RETIRED"}, {0}},
Packit 577717
	{PAPI_L2_ICA, 0, {"L2I_DEMAND_READS"}, {0}},
Packit 577717
	{PAPI_L3_ICA, 0, {"L3_READS_INST_FETCH_ALL:M:E:S:I"}, {0}},
Packit 577717
	{PAPI_L1_TCR, 0, {"L2I_READS_ALL_ALL"}, {0}},
Packit 577717
/* Why are TCA READS+READS_SET0? I used the same as PAPI_L1_TCR, because its an write through cache
Packit 577717
 * OLD: {PAPI_L1_TCA, DERIVED_ADD, {"L1D_READS_SET0", "L1I_READS"}, {0}}, 
Packit 577717
 */
Packit 577717
	{PAPI_L1_TCA, DERIVED_ADD,
Packit 577717
	 {"L1I_PREFETCHES", "L1I_READS", "L1D_READS_SET0"}, {0}},
Packit 577717
	{PAPI_L2_TCW, 0, {"L2D_REFERENCES_WRITES"}, {0}},
Packit 577717
	{0, 0, {0}, {0}}
Packit 577717
};
Packit 577717
Packit 577717
/* This component should never malloc anything. All allocation should be
Packit 577717
   done by the high level API. */
Packit 577717
Packit 577717
Packit 577717
/*****************************************************************************
Packit 577717
 * Code to support unit masks; only needed by Montecito and above            *
Packit 577717
 *****************************************************************************/
Packit 577717
static  int _ia64_modify_event( unsigned int event, int modifier );
Packit 577717
Packit 577717
/* Break a PAPI native event code into its composite event code and pfm mask bits */
Packit 577717
static  int
Packit 577717
_pfm_decode_native_event( unsigned int EventCode, unsigned int *event,
Packit 577717
						  unsigned int *umask )
Packit 577717
{
Packit 577717
	unsigned int tevent, major, minor;
Packit 577717
Packit 577717
	tevent = EventCode & PAPI_NATIVE_AND_MASK;
Packit 577717
	major = ( tevent & PAPI_NATIVE_EVENT_AND_MASK ) >> PAPI_NATIVE_EVENT_SHIFT;
Packit 577717
	if ( major >= ( unsigned int ) _ia64_vector.cmp_info.num_native_events )
Packit 577717
		return ( PAPI_ENOEVNT );
Packit 577717
Packit 577717
	minor = ( tevent & PAPI_NATIVE_UMASK_AND_MASK ) >> PAPI_NATIVE_UMASK_SHIFT;
Packit 577717
	*event = major;
Packit 577717
	*umask = minor;
Packit 577717
	SUBDBG( "EventCode %#08x is event %d, umask %#x\n", EventCode, major,
Packit 577717
			minor );
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
/* This routine is used to step through all possible combinations of umask
Packit 577717
    values. It assumes that mask contains a valid combination of array indices
Packit 577717
    for this event. */
Packit 577717
static  int
Packit 577717
encode_native_event_raw( unsigned int event, unsigned int mask )
Packit 577717
{
Packit 577717
	unsigned int tmp = event << PAPI_NATIVE_EVENT_SHIFT;
Packit 577717
	SUBDBG( "Old native index was %#08x with %#08x mask\n", tmp, mask );
Packit 577717
	tmp = tmp | ( mask << PAPI_NATIVE_UMASK_SHIFT );
Packit 577717
	SUBDBG( "New encoding is %#08x\n", tmp | PAPI_NATIVE_MASK );
Packit 577717
	return ( tmp | PAPI_NATIVE_MASK );
Packit 577717
}
Packit 577717
Packit 577717
/* convert a collection of pfm mask bits into an array of pfm mask indices */
Packit 577717
static  int
Packit 577717
prepare_umask( unsigned int foo, unsigned int *values )
Packit 577717
{
Packit 577717
	unsigned int tmp = foo, i, j = 0;
Packit 577717
Packit 577717
	SUBDBG( "umask %#x\n", tmp );
Packit 577717
	if ( foo == 0 )
Packit 577717
		return 0;
Packit 577717
	while ( ( i = ffs( tmp ) ) ) {
Packit 577717
		tmp = tmp ^ ( 1 << ( i - 1 ) );
Packit 577717
		values[j] = i - 1;
Packit 577717
		SUBDBG( "umask %d is %d\n", j, values[j] );
Packit 577717
		j++;
Packit 577717
	}
Packit 577717
	return ( j );
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_papi_pfm_ntv_enum_events( unsigned int *EventCode, int modifier )
Packit 577717
{
Packit 577717
	unsigned int event, umask, num_masks;
Packit 577717
	int ret;
Packit 577717
Packit 577717
	if ( modifier == PAPI_ENUM_FIRST ) {
Packit 577717
		*EventCode = PAPI_NATIVE_MASK;	/* assumes first native event is always 0x4000000 */
Packit 577717
		return ( PAPI_OK );
Packit 577717
	}
Packit 577717
Packit 577717
	if ( _pfm_decode_native_event( *EventCode, &event, &umask ) != PAPI_OK )
Packit 577717
		return ( PAPI_ENOEVNT );
Packit 577717
Packit 577717
	ret = pfm_get_num_event_masks( event, &num_masks );
Packit 577717
	SUBDBG( "pfm_get_num_event_masks: event=%d  num_masks=%d\n", event,
Packit 577717
			num_masks );
Packit 577717
	if ( ret != PFMLIB_SUCCESS ) {
Packit 577717
		PAPIERROR( "pfm_get_num_event_masks(%d,%p): %s", event, &num_masks,
Packit 577717
				   pfm_strerror( ret ) );
Packit 577717
		return ( PAPI_ENOEVNT );
Packit 577717
	}
Packit 577717
	if ( num_masks > PAPI_NATIVE_UMASK_MAX )
Packit 577717
		num_masks = PAPI_NATIVE_UMASK_MAX;
Packit 577717
	SUBDBG( "This is umask %d of %d\n", umask, num_masks );
Packit 577717
Packit 577717
	if ( modifier == PAPI_ENUM_EVENTS ) {
Packit 577717
		if ( event < ( unsigned int ) _ia64_vector.cmp_info.num_native_events - 1 ) {
Packit 577717
			*EventCode = encode_native_event_raw( event + 1, 0 );
Packit 577717
			return ( PAPI_OK );
Packit 577717
		}
Packit 577717
		return ( PAPI_ENOEVNT );
Packit 577717
	} else if ( modifier == PAPI_NTV_ENUM_UMASK_COMBOS ) {
Packit 577717
		if ( umask + 1 < ( unsigned ) ( 1 << num_masks ) ) {
Packit 577717
			*EventCode = encode_native_event_raw( event, umask + 1 );
Packit 577717
			return ( PAPI_OK );
Packit 577717
		}
Packit 577717
		return ( PAPI_ENOEVNT );
Packit 577717
	} else if ( modifier == PAPI_NTV_ENUM_UMASKS ) {
Packit 577717
		int thisbit = ffs( umask );
Packit 577717
Packit 577717
		SUBDBG( "First bit is %d in %08x\b\n", thisbit - 1, umask );
Packit 577717
		thisbit = 1 << thisbit;
Packit 577717
Packit 577717
		if ( thisbit & ( ( 1 << num_masks ) - 1 ) ) {
Packit 577717
			*EventCode = encode_native_event_raw( event, thisbit );
Packit 577717
			return ( PAPI_OK );
Packit 577717
		}
Packit 577717
		return ( PAPI_ENOEVNT );
Packit 577717
	} else {
Packit 577717
		while ( event++ <
Packit 577717
				( unsigned int ) _ia64_vector.cmp_info.num_native_events - 1 ) {
Packit 577717
			*EventCode = encode_native_event_raw( event + 1, 0 );
Packit 577717
			if ( _ia64_modify_event( event + 1, modifier ) )
Packit 577717
				return ( PAPI_OK );
Packit 577717
		}
Packit 577717
		return ( PAPI_ENOEVNT );
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
static int
Packit 577717
_papi_pfm_ntv_name_to_code( const char *name, unsigned int *event_code )
Packit 577717
{
Packit 577717
	pfmlib_event_t event;
Packit 577717
	unsigned int i, mask = 0;
Packit 577717
	int ret;
Packit 577717
Packit 577717
	SUBDBG( "pfm_find_full_event(%s,%p)\n", name, &event );
Packit 577717
	ret = pfm_find_full_event( name, &event );
Packit 577717
	if ( ret == PFMLIB_SUCCESS ) {
Packit 577717
		/* we can only capture PAPI_NATIVE_UMASK_MAX or fewer masks */
Packit 577717
		if ( event.num_masks > PAPI_NATIVE_UMASK_MAX ) {
Packit 577717
			SUBDBG( "num_masks (%d) > max masks (%d)\n", event.num_masks,
Packit 577717
					PAPI_NATIVE_UMASK_MAX );
Packit 577717
			return ( PAPI_ENOEVNT );
Packit 577717
		} else {
Packit 577717
			/* no mask index can exceed PAPI_NATIVE_UMASK_MAX */
Packit 577717
			for ( i = 0; i < event.num_masks; i++ ) {
Packit 577717
				if ( event.unit_masks[i] > PAPI_NATIVE_UMASK_MAX ) {
Packit 577717
					SUBDBG( "mask index (%d) > max masks (%d)\n",
Packit 577717
							event.unit_masks[i], PAPI_NATIVE_UMASK_MAX );
Packit 577717
					return ( PAPI_ENOEVNT );
Packit 577717
				}
Packit 577717
				mask |= 1 << event.unit_masks[i];
Packit 577717
			}
Packit 577717
			*event_code = encode_native_event_raw( event.event, mask );
Packit 577717
			SUBDBG( "event_code: %#x  event: %d  num_masks: %d\n", *event_code,
Packit 577717
					event.event, event.num_masks );
Packit 577717
			return ( PAPI_OK );
Packit 577717
		}
Packit 577717
	} else if ( ret == PFMLIB_ERR_UMASK ) {
Packit 577717
		ret = pfm_find_event( name, &event.event );
Packit 577717
		if ( ret == PFMLIB_SUCCESS ) {
Packit 577717
			*event_code = encode_native_event_raw( event.event, 0 );
Packit 577717
			return ( PAPI_OK );
Packit 577717
		}
Packit 577717
	}
Packit 577717
	return ( PAPI_ENOEVNT );
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_papi_pfm_ntv_code_to_name( unsigned int EventCode, char *ntv_name, int len )
Packit 577717
{
Packit 577717
	int ret;
Packit 577717
	unsigned int event, umask;
Packit 577717
	pfmlib_event_t gete;
Packit 577717
Packit 577717
	memset( &gete, 0, sizeof ( gete ) );
Packit 577717
Packit 577717
	if ( _pfm_decode_native_event( EventCode, &event, &umask ) != PAPI_OK )
Packit 577717
		return ( PAPI_ENOEVNT );
Packit 577717
Packit 577717
	gete.event = event;
Packit 577717
	gete.num_masks = prepare_umask( umask, gete.unit_masks );
Packit 577717
	if ( gete.num_masks == 0 )
Packit 577717
		ret = pfm_get_event_name( gete.event, ntv_name, len );
Packit 577717
	else
Packit 577717
		ret = pfm_get_full_event_name( &gete, ntv_name, len );
Packit 577717
	if ( ret != PFMLIB_SUCCESS ) {
Packit 577717
		char tmp[PAPI_2MAX_STR_LEN];
Packit 577717
		pfm_get_event_name( gete.event, tmp, sizeof ( tmp ) );
Packit 577717
		PAPIERROR
Packit 577717
			( "pfm_get_full_event_name(%p(event %d,%s,%d masks),%p,%d): %d -- %s",
Packit 577717
			  &gete, gete.event, tmp, gete.num_masks, ntv_name, len, ret,
Packit 577717
			  pfm_strerror( ret ) );
Packit 577717
		if ( ret == PFMLIB_ERR_FULL )
Packit 577717
			return PAPI_EBUF;
Packit 577717
		return PAPI_ECMP;
Packit 577717
	}
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_papi_pfm_ntv_code_to_descr( unsigned int EventCode, char *ntv_descr, int len )
Packit 577717
{
Packit 577717
	unsigned int event, umask;
Packit 577717
	char *eventd, **maskd, *tmp;
Packit 577717
	int i, ret, total_len = 0;
Packit 577717
	pfmlib_event_t gete;
Packit 577717
Packit 577717
	memset( &gete, 0, sizeof ( gete ) );
Packit 577717
Packit 577717
	if ( _pfm_decode_native_event( EventCode, &event, &umask ) != PAPI_OK )
Packit 577717
		return ( PAPI_ENOEVNT );
Packit 577717
Packit 577717
	ret = pfm_get_event_description( event, &eventd );
Packit 577717
	if ( ret != PFMLIB_SUCCESS ) {
Packit 577717
		PAPIERROR( "pfm_get_event_description(%d,%p): %s",
Packit 577717
				   event, &eventd, pfm_strerror( ret ) );
Packit 577717
		return ( PAPI_ENOEVNT );
Packit 577717
	}
Packit 577717
Packit 577717
	if ( ( gete.num_masks = prepare_umask( umask, gete.unit_masks ) ) ) {
Packit 577717
		maskd = ( char ** ) malloc( gete.num_masks * sizeof ( char * ) );
Packit 577717
		if ( maskd == NULL ) {
Packit 577717
			free( eventd );
Packit 577717
			return ( PAPI_ENOMEM );
Packit 577717
		}
Packit 577717
		for ( i = 0; i < ( int ) gete.num_masks; i++ ) {
Packit 577717
			ret =
Packit 577717
				pfm_get_event_mask_description( event, gete.unit_masks[i],
Packit 577717
												&maskd[i] );
Packit 577717
			if ( ret != PFMLIB_SUCCESS ) {
Packit 577717
				PAPIERROR( "pfm_get_event_mask_description(%d,%d,%p): %s",
Packit 577717
						   event, umask, &maskd, pfm_strerror( ret ) );
Packit 577717
				free( eventd );
Packit 577717
				for ( ; i >= 0; i-- )
Packit 577717
					free( maskd[i] );
Packit 577717
				free( maskd );
Packit 577717
				return ( PAPI_EINVAL );
Packit 577717
			}
Packit 577717
			total_len += strlen( maskd[i] );
Packit 577717
		}
Packit 577717
		tmp =
Packit 577717
			( char * ) malloc( strlen( eventd ) + strlen( ", masks:" ) +
Packit 577717
							   total_len + gete.num_masks + 1 );
Packit 577717
		if ( tmp == NULL ) {
Packit 577717
			for ( i = gete.num_masks - 1; i >= 0; i-- )
Packit 577717
				free( maskd[i] );
Packit 577717
			free( maskd );
Packit 577717
			free( eventd );
Packit 577717
		}
Packit 577717
		tmp[0] = '\0';
Packit 577717
		strcat( tmp, eventd );
Packit 577717
		strcat( tmp, ", masks:" );
Packit 577717
		for ( i = 0; i < ( int ) gete.num_masks; i++ ) {
Packit 577717
			if ( i != 0 )
Packit 577717
				strcat( tmp, "," );
Packit 577717
			strcat( tmp, maskd[i] );
Packit 577717
			free( maskd[i] );
Packit 577717
		}
Packit 577717
		free( maskd );
Packit 577717
	} else {
Packit 577717
		tmp = ( char * ) malloc( strlen( eventd ) + 1 );
Packit 577717
		if ( tmp == NULL ) {
Packit 577717
			free( eventd );
Packit 577717
			return ( PAPI_ENOMEM );
Packit 577717
		}
Packit 577717
		tmp[0] = '\0';
Packit 577717
		strcat( tmp, eventd );
Packit 577717
		free( eventd );
Packit 577717
	}
Packit 577717
	strncpy( ntv_descr, tmp, len );
Packit 577717
	if ( strlen( tmp ) > ( unsigned int ) len - 1 )
Packit 577717
		ret = PAPI_EBUF;
Packit 577717
	else
Packit 577717
		ret = PAPI_OK;
Packit 577717
	free( tmp );
Packit 577717
	return ( ret );
Packit 577717
}
Packit 577717
Packit 577717
/*****************************************************************************
Packit 577717
 *****************************************************************************/
Packit 577717
Packit 577717
/* The values defined in this file may be X86-specific (2 general 
Packit 577717
   purpose counters, 1 special purpose counter, etc.*/
Packit 577717
Packit 577717
/* PAPI stuff */
Packit 577717
Packit 577717
/* Low level functions, should not handle errors, just return codes. */
Packit 577717
Packit 577717
/* I want to keep the old way to define the preset search map.
Packit 577717
   In Itanium2, there are more than 400 native events, if I use the
Packit 577717
   index directly, it will be difficult for people to debug, so I
Packit 577717
   still keep the old way to define preset search table, but 
Packit 577717
   I add this function to generate the preset search map in papi3 
Packit 577717
*/
Packit 577717
int
Packit 577717
generate_preset_search_map( hwi_search_t ** maploc,
Packit 577717
							itanium_preset_search_t * oldmap, int num_cnt )
Packit 577717
{
Packit 577717
	( void ) num_cnt;		 /*unused */
Packit 577717
	int pnum, i = 0, cnt;
Packit 577717
	char **findme;
Packit 577717
	hwi_search_t *psmap;
Packit 577717
Packit 577717
	/* Count up the presets */
Packit 577717
	while ( oldmap[i].preset )
Packit 577717
		i++;
Packit 577717
	/* Add null entry */
Packit 577717
	i++;
Packit 577717
Packit 577717
	psmap = ( hwi_search_t * ) papi_malloc( i * sizeof ( hwi_search_t ) );
Packit 577717
	if ( psmap == NULL )
Packit 577717
		return ( PAPI_ENOMEM );
Packit 577717
	memset( psmap, 0x0, i * sizeof ( hwi_search_t ) );
Packit 577717
Packit 577717
	pnum = 0;				 /* preset event counter */
Packit 577717
	for ( i = 0; i <= PAPI_MAX_PRESET_EVENTS; i++ ) {
Packit 577717
		if ( oldmap[i].preset == 0 )
Packit 577717
			break;
Packit 577717
		pnum++;
Packit 577717
		psmap[i].event_code = oldmap[i].preset;
Packit 577717
		psmap[i].data.derived = oldmap[i].derived;
Packit 577717
		strcpy( psmap[i].data.operation, oldmap[i].operation );
Packit 577717
		findme = oldmap[i].findme;
Packit 577717
		cnt = 0;
Packit 577717
		while ( *findme != NULL ) {
Packit 577717
			if ( cnt == MAX_COUNTER_TERMS ) {
Packit 577717
				PAPIERROR( "Count (%d) == MAX_COUNTER_TERMS (%d)\n", cnt,
Packit 577717
						   MAX_COUNTER_TERMS );
Packit 577717
				papi_free( psmap );
Packit 577717
				return ( PAPI_EBUG );
Packit 577717
			}
Packit 577717
			if ( _perfmon2_pfm_pmu_type == PFMLIB_MONTECITO_PMU ) {
Packit 577717
				if ( _papi_pfm_ntv_name_to_code
Packit 577717
					 ( *findme,
Packit 577717
					   ( unsigned int * ) &psmap[i].data.native[cnt] ) !=
Packit 577717
					 PAPI_OK ) {
Packit 577717
					PAPIERROR( "_papi_pfm_ntv_name_to_code(%s) failed\n",
Packit 577717
							   *findme );
Packit 577717
					papi_free( psmap );
Packit 577717
					return ( PAPI_EBUG );
Packit 577717
				} else
Packit 577717
					psmap[i].data.native[cnt] ^= PAPI_NATIVE_MASK;
Packit 577717
			} else {
Packit 577717
				if ( pfm_find_event_byname
Packit 577717
					 ( *findme,
Packit 577717
					   ( unsigned int * ) &psmap[i].data.native[cnt] ) !=
Packit 577717
					 PFMLIB_SUCCESS ) {
Packit 577717
					PAPIERROR( "pfm_find_event_byname(%s) failed\n", *findme );
Packit 577717
					papi_free( psmap );
Packit 577717
					return ( PAPI_EBUG );
Packit 577717
				} else
Packit 577717
					psmap[i].data.native[cnt] ^= PAPI_NATIVE_MASK;
Packit 577717
			}
Packit 577717
Packit 577717
			findme++;
Packit 577717
			cnt++;
Packit 577717
		}
Packit 577717
		psmap[i].data.native[cnt] = PAPI_NULL;
Packit 577717
	}
Packit 577717
Packit 577717
	*maploc = psmap;
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
static  char *
Packit 577717
search_cpu_info( FILE * f, char *search_str, char *line )
Packit 577717
{
Packit 577717
	/* This code courtesy of our friends in Germany. Thanks Rudolph Berrendorf! */
Packit 577717
	/* See the PCL home page for the German version of PAPI. */
Packit 577717
Packit 577717
	char *s;
Packit 577717
Packit 577717
	while ( fgets( line, 256, f ) != NULL ) {
Packit 577717
		if ( strstr( line, search_str ) != NULL ) {
Packit 577717
			/* ignore all characters in line up to : */
Packit 577717
			for ( s = line; *s && ( *s != ':' ); ++s );
Packit 577717
			if ( *s )
Packit 577717
				return ( s );
Packit 577717
		}
Packit 577717
	}
Packit 577717
	return ( NULL );
Packit 577717
Packit 577717
	/* End stolen code */
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_ita_set_domain( hwd_control_state_t * this_state, int domain )
Packit 577717
{
Packit 577717
	int mode = 0, did = 0, i;
Packit 577717
	pfmw_param_t *evt = &( ( ia64_control_state_t * ) this_state )->evt;
Packit 577717
Packit 577717
	if ( domain & PAPI_DOM_USER ) {
Packit 577717
		did = 1;
Packit 577717
		mode |= PFM_PLM3;
Packit 577717
	}
Packit 577717
Packit 577717
	if ( domain & PAPI_DOM_KERNEL ) {
Packit 577717
		did = 1;
Packit 577717
		mode |= PFM_PLM0;
Packit 577717
	}
Packit 577717
Packit 577717
	if ( !did )
Packit 577717
		return ( PAPI_EINVAL );
Packit 577717
Packit 577717
	PFMW_PEVT_DFLPLM( evt ) = mode;
Packit 577717
Packit 577717
	/* Bug fix in case we don't call pfmw_dispatch_events after this code */
Packit 577717
	/* Who did this? This sucks, we should always call it here -PJM */
Packit 577717
Packit 577717
	for ( i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++ ) {
Packit 577717
		if ( PFMW_PEVT_PFPPC_REG_NUM( evt, i ) ) {
Packit 577717
			pfm_ita_pmc_reg_t value;
Packit 577717
			SUBDBG( "slot %d, register %lud active, config value %#lx\n",
Packit 577717
					i, ( unsigned long ) ( PFMW_PEVT_PFPPC_REG_NUM( evt, i ) ),
Packit 577717
					PFMW_PEVT_PFPPC_REG_VAL( evt, i ) );
Packit 577717
Packit 577717
			PFMW_ARCH_REG_PMCVAL( value ) = PFMW_PEVT_PFPPC_REG_VAL( evt, i );
Packit 577717
			value.pmc_ita_count_reg.pmc_plm = mode;
Packit 577717
			PFMW_PEVT_PFPPC_REG_VAL( evt, i ) = PFMW_ARCH_REG_PMCVAL( value );
Packit 577717
Packit 577717
			SUBDBG( "new config value %#lx\n",
Packit 577717
					PFMW_PEVT_PFPPC_REG_VAL( evt, i ) );
Packit 577717
		}
Packit 577717
	}
Packit 577717
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_ita2_set_domain( hwd_control_state_t * this_state, int domain )
Packit 577717
{
Packit 577717
	int mode = 0, did = 0, i;
Packit 577717
	pfmw_param_t *evt = &this_state->evt;
Packit 577717
Packit 577717
	if ( domain & PAPI_DOM_USER ) {
Packit 577717
		did = 1;
Packit 577717
		mode |= PFM_PLM3;
Packit 577717
	}
Packit 577717
Packit 577717
	if ( domain & PAPI_DOM_KERNEL ) {
Packit 577717
		did = 1;
Packit 577717
		mode |= PFM_PLM0;
Packit 577717
	}
Packit 577717
Packit 577717
	if ( !did )
Packit 577717
		return ( PAPI_EINVAL );
Packit 577717
Packit 577717
	PFMW_PEVT_DFLPLM( evt ) = mode;
Packit 577717
Packit 577717
	/* Bug fix in case we don't call pfmw_dispatch_events after this code */
Packit 577717
	/* Who did this? This sucks, we should always call it here -PJM */
Packit 577717
Packit 577717
	for ( i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++ ) {
Packit 577717
		if ( PFMW_PEVT_PFPPC_REG_NUM( evt, i ) ) {
Packit 577717
			pfm_ita2_pmc_reg_t value;
Packit 577717
			SUBDBG( "slot %d, register %lud active, config value %#lx\n",
Packit 577717
					i, ( unsigned long ) ( PFMW_PEVT_PFPPC_REG_NUM( evt, i ) ),
Packit 577717
					PFMW_PEVT_PFPPC_REG_VAL( evt, i ) );
Packit 577717
Packit 577717
			PFMW_ARCH_REG_PMCVAL( value ) = PFMW_PEVT_PFPPC_REG_VAL( evt, i );
Packit 577717
			value.pmc_ita2_counter_reg.pmc_plm = mode;
Packit 577717
			PFMW_PEVT_PFPPC_REG_VAL( evt, i ) = PFMW_ARCH_REG_PMCVAL( value );
Packit 577717
Packit 577717
			SUBDBG( "new config value %#lx\n",
Packit 577717
					PFMW_PEVT_PFPPC_REG_VAL( evt, i ) );
Packit 577717
		}
Packit 577717
	}
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_mont_set_domain( hwd_control_state_t * this_state, int domain )
Packit 577717
{
Packit 577717
	int mode = 0, did = 0, i;
Packit 577717
	pfmw_param_t *evt = &( ( ia64_control_state_t * ) this_state )->evt;
Packit 577717
Packit 577717
	if ( domain & PAPI_DOM_USER ) {
Packit 577717
		did = 1;
Packit 577717
		mode |= PFM_PLM3;
Packit 577717
	}
Packit 577717
Packit 577717
	if ( domain & PAPI_DOM_KERNEL ) {
Packit 577717
		did = 1;
Packit 577717
		mode |= PFM_PLM0;
Packit 577717
	}
Packit 577717
Packit 577717
	if ( !did )
Packit 577717
		return ( PAPI_EINVAL );
Packit 577717
Packit 577717
	PFMW_PEVT_DFLPLM( evt ) = mode;
Packit 577717
Packit 577717
	/* Bug fix in case we don't call pfmw_dispatch_events after this code */
Packit 577717
	/* Who did this? This sucks, we should always call it here -PJM */
Packit 577717
Packit 577717
	for ( i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++ ) {
Packit 577717
		if ( PFMW_PEVT_PFPPC_REG_NUM( evt, i ) ) {
Packit 577717
			pfm_mont_pmc_reg_t value;
Packit 577717
			SUBDBG( "slot %d, register %lud active, config value %#lx\n",
Packit 577717
					i, ( unsigned long ) ( PFMW_PEVT_PFPPC_REG_NUM( evt, i ) ),
Packit 577717
					PFMW_PEVT_PFPPC_REG_VAL( evt, i ) );
Packit 577717
Packit 577717
			PFMW_ARCH_REG_PMCVAL( value ) = PFMW_PEVT_PFPPC_REG_VAL( evt, i );
Packit 577717
			value.pmc_mont_counter_reg.pmc_plm = mode;
Packit 577717
			PFMW_PEVT_PFPPC_REG_VAL( evt, i ) = PFMW_ARCH_REG_PMCVAL( value );
Packit 577717
Packit 577717
			SUBDBG( "new config value %#lx\n",
Packit 577717
					PFMW_PEVT_PFPPC_REG_VAL( evt, i ) );
Packit 577717
		}
Packit 577717
	}
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_set_domain( hwd_control_state_t * this_state, int domain )
Packit 577717
{
Packit 577717
	switch ( _perfmon2_pfm_pmu_type ) {
Packit 577717
	case PFMLIB_ITANIUM_PMU:
Packit 577717
		return ( _ia64_ita_set_domain( this_state, domain ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_ITANIUM2_PMU:
Packit 577717
		return ( _ia64_ita2_set_domain( this_state, domain ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_MONTECITO_PMU:
Packit 577717
		return ( _ia64_mont_set_domain( this_state, domain ) );
Packit 577717
		break;
Packit 577717
	default:
Packit 577717
		PAPIERROR( "PMU type %d is not supported by this component",
Packit 577717
				   _perfmon2_pfm_pmu_type );
Packit 577717
		return ( PAPI_EBUG );
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
set_granularity( hwd_control_state_t * this_state, int domain )
Packit 577717
{
Packit 577717
	( void ) this_state;	 /*unused */
Packit 577717
	switch ( domain ) {
Packit 577717
	case PAPI_GRN_PROCG:
Packit 577717
	case PAPI_GRN_SYS:
Packit 577717
	case PAPI_GRN_SYS_CPU:
Packit 577717
	case PAPI_GRN_PROC:
Packit 577717
		return PAPI_ECMP;
Packit 577717
	case PAPI_GRN_THR:
Packit 577717
		break;
Packit 577717
	default:
Packit 577717
		return PAPI_EINVAL;
Packit 577717
	}
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_ita_read( hwd_context_t * ctx, hwd_control_state_t * machdep,
Packit 577717
				long long **events, int flags )
Packit 577717
{
Packit 577717
	( void ) flags;			 /*unused */
Packit 577717
	unsigned int i;
Packit 577717
	pfarg_reg_t readem[_ia64_vector.cmp_info.num_cntrs];
Packit 577717
Packit 577717
	pfmw_stop( ( ia64_context_t * ) ctx );
Packit 577717
	memset( readem, 0x0, sizeof readem );
Packit 577717
Packit 577717
/* read the 4 counters, the high level function will process the 
Packit 577717
   mapping for papi event to hardware counter 
Packit 577717
*/
Packit 577717
	for ( i = 0; i < ( unsigned int ) _ia64_vector.cmp_info.num_cntrs; i++ ) {
Packit 577717
		readem[i].reg_num = PMU_FIRST_COUNTER + i;
Packit 577717
	}
Packit 577717
Packit 577717
	if ( pfmw_perfmonctl
Packit 577717
		 ( ( ( ia64_context_t * ) ctx )->tid, ( ( ia64_context_t * ) ctx )->fd,
Packit 577717
		   PFM_READ_PMDS, readem, _ia64_vector.cmp_info.num_cntrs ) == -1 ) {
Packit 577717
		SUBDBG( "perfmonctl error READ_PMDS errno %d\n", errno );
Packit 577717
		pfmw_start( ( ia64_context_t * ) ctx );
Packit 577717
		return PAPI_ESYS;
Packit 577717
	}
Packit 577717
Packit 577717
	for ( i = 0; i < ( unsigned int ) _ia64_vector.cmp_info.num_cntrs; i++ ) {
Packit 577717
		( ( ia64_control_state_t * ) machdep )->counters[i] =
Packit 577717
			readem[i].reg_value;
Packit 577717
		SUBDBG( "read counters is %ld\n", readem[i].reg_value );
Packit 577717
	}
Packit 577717
Packit 577717
	pfmw_param_t *pevt = &( ( ( ia64_control_state_t * ) machdep )->evt );
Packit 577717
	pfm_ita_pmc_reg_t flop_hack;
Packit 577717
	/* special case, We need to scale FP_OPS_HI */
Packit 577717
	for ( i = 0; i < PFMW_PEVT_EVTCOUNT( pevt ); i++ ) {
Packit 577717
		PFMW_ARCH_REG_PMCVAL( flop_hack ) = PFMW_PEVT_PFPPC_REG_VAL( pevt, i );
Packit 577717
		if ( flop_hack.pmc_ita_count_reg.pmc_es == 0xa )
Packit 577717
			( ( ia64_control_state_t * ) machdep )->counters[i] *= 4;
Packit 577717
	}
Packit 577717
Packit 577717
	*events = ( ( ia64_control_state_t * ) machdep )->counters;
Packit 577717
	pfmw_start( ( ia64_context_t * ) ctx );
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
int
Packit 577717
_ia64_ita23_read( hwd_context_t * ctx, hwd_control_state_t * machdep,
Packit 577717
				  long long **events, int flags )
Packit 577717
{
Packit 577717
	( void ) flags;			 /*unused */
Packit 577717
	int i;
Packit 577717
	pfarg_reg_t readem[_ia64_vector.cmp_info.num_cntrs];
Packit 577717
Packit 577717
	pfmw_stop( ( ia64_context_t * ) ctx );
Packit 577717
	memset( readem, 0x0, sizeof readem );
Packit 577717
Packit 577717
/* read the 4 counters, the high level function will process the 
Packit 577717
   mapping for papi event to hardware counter 
Packit 577717
*/
Packit 577717
	for ( i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++ ) {
Packit 577717
		readem[i].reg_num = PMU_FIRST_COUNTER + i;
Packit 577717
	}
Packit 577717
Packit 577717
	if ( pfmw_perfmonctl
Packit 577717
		 ( ( ( ia64_context_t * ) ctx )->tid, ( ( ia64_context_t * ) ctx )->fd,
Packit 577717
		   PFM_READ_PMDS, readem, _ia64_vector.cmp_info.num_cntrs ) == -1 ) {
Packit 577717
		SUBDBG( "perfmonctl error READ_PMDS errno %d\n", errno );
Packit 577717
		pfmw_start( ( ia64_context_t * ) ctx );
Packit 577717
		return PAPI_ESYS;
Packit 577717
	}
Packit 577717
Packit 577717
	for ( i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++ ) {
Packit 577717
		( ( ia64_control_state_t * ) machdep )->counters[i] =
Packit 577717
			readem[i].reg_value;
Packit 577717
		SUBDBG( "read counters is %ld\n", readem[i].reg_value );
Packit 577717
	}
Packit 577717
Packit 577717
	*events = ( ( ia64_control_state_t * ) machdep )->counters;
Packit 577717
	pfmw_start( ( ia64_context_t * ) ctx );
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_read( hwd_context_t * ctx, hwd_control_state_t * machdep,
Packit 577717
			long long **events, int flags )
Packit 577717
{
Packit 577717
	switch ( _perfmon2_pfm_pmu_type ) {
Packit 577717
	case PFMLIB_ITANIUM_PMU:
Packit 577717
		return ( _ia64_ita_read( ctx, machdep, events, flags ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_ITANIUM2_PMU:
Packit 577717
		return ( _ia64_ita23_read( ctx, machdep, events, flags ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_MONTECITO_PMU:
Packit 577717
		return ( _ia64_ita23_read( ctx, machdep, events, flags ) );
Packit 577717
		break;
Packit 577717
	default:
Packit 577717
		PAPIERROR( "PMU type %d is not supported by this component",
Packit 577717
				   _perfmon2_pfm_pmu_type );
Packit 577717
		return ( PAPI_EBUG );
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
/* This function should tell your kernel extension that your children
Packit 577717
   inherit performance register information and propagate the values up
Packit 577717
   upon child exit and parent wait. */
Packit 577717
Packit 577717
static  int
Packit 577717
set_inherit( int arg )
Packit 577717
{
Packit 577717
	( void ) arg;			 /*unused */
Packit 577717
	return PAPI_ECMP;
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
set_default_domain( hwd_control_state_t * this_state, int domain )
Packit 577717
{
Packit 577717
	return ( _ia64_set_domain( this_state, domain ) );
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
set_default_granularity( hwd_control_state_t * this_state, int granularity )
Packit 577717
{
Packit 577717
	return ( set_granularity( this_state, granularity ) );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
Packit 577717
Packit 577717
int
Packit 577717
_ia64_init_component( int cidx )
Packit 577717
{
Packit 577717
	( void ) cidx;			 /*unused */
Packit 577717
	int i, retval, type;
Packit 577717
	unsigned int version;
Packit 577717
	pfmlib_options_t pfmlib_options;
Packit 577717
	itanium_preset_search_t *ia_preset_search_map = NULL;
Packit 577717
Packit 577717
	/* Always initialize globals dynamically to handle forks properly. */
Packit 577717
Packit 577717
	preset_search_map = NULL;
Packit 577717
Packit 577717
	/* Opened once for all threads. */
Packit 577717
	if ( pfm_initialize(  ) != PFMLIB_SUCCESS )
Packit 577717
		return ( PAPI_ESYS );
Packit 577717
Packit 577717
	if ( pfm_get_version( &version ) != PFMLIB_SUCCESS )
Packit 577717
		return PAPI_ECMP;
Packit 577717
Packit 577717
	if ( PFM_VERSION_MAJOR( version ) != PFM_VERSION_MAJOR( PFMLIB_VERSION ) ) {
Packit 577717
		PAPIERROR( "Version mismatch of libpfm: compiled %#x vs. installed %#x",
Packit 577717
				   PFM_VERSION_MAJOR( PFMLIB_VERSION ),
Packit 577717
				   PFM_VERSION_MAJOR( version ) );
Packit 577717
		return PAPI_ECMP;
Packit 577717
	}
Packit 577717
Packit 577717
	memset( &pfmlib_options, 0, sizeof ( pfmlib_options ) );
Packit 577717
#ifdef DEBUG
Packit 577717
	if ( ISLEVEL( DEBUG_SUBSTRATE ) ) {
Packit 577717
		pfmlib_options.pfm_debug = 1;
Packit 577717
		pfmlib_options.pfm_verbose = 1;
Packit 577717
	}
Packit 577717
#endif
Packit 577717
Packit 577717
	if ( pfm_set_options( &pfmlib_options ) )
Packit 577717
		return ( PAPI_ESYS );
Packit 577717
Packit 577717
	if ( pfm_get_pmu_type( &type ) != PFMLIB_SUCCESS )
Packit 577717
		return ( PAPI_ESYS );
Packit 577717
Packit 577717
	_perfmon2_pfm_pmu_type = type;
Packit 577717
Packit 577717
	/* Setup presets */
Packit 577717
Packit 577717
	switch ( type ) {
Packit 577717
	case PFMLIB_ITANIUM_PMU:
Packit 577717
		ia_preset_search_map = ia1_preset_search_map;
Packit 577717
		break;
Packit 577717
	case PFMLIB_ITANIUM2_PMU:
Packit 577717
		ia_preset_search_map = ia2_preset_search_map;
Packit 577717
		break;
Packit 577717
	case PFMLIB_MONTECITO_PMU:
Packit 577717
		ia_preset_search_map = ia3_preset_search_map;
Packit 577717
		break;
Packit 577717
	default:
Packit 577717
		PAPIERROR( "PMU type %d is not supported by this component", type );
Packit 577717
		return ( PAPI_EBUG );
Packit 577717
	}
Packit 577717
Packit 577717
	int ncnt, nnev;
Packit 577717
Packit 577717
	retval = pfmw_get_num_events( &nnev );
Packit 577717
	if ( retval != PAPI_OK )
Packit 577717
		return ( retval );
Packit 577717
Packit 577717
	retval = pfmw_get_num_counters( &ncnt );
Packit 577717
	if ( retval != PAPI_OK )
Packit 577717
		return ( retval );
Packit 577717
Packit 577717
	sprintf( _ia64_vector.cmp_info.support_version, 
Packit 577717
		 "%08x", PFMLIB_VERSION );
Packit 577717
	sprintf( _ia64_vector.cmp_info.kernel_version, 
Packit 577717
		 "%08x", 2 << 16 );	/* 2.0 */
Packit 577717
Packit 577717
	_ia64_vector.cmp_info.num_native_events = nnev;
Packit 577717
	_ia64_vector.cmp_info.num_cntrs = ncnt;
Packit 577717
	_ia64_vector.cmp_info.num_mpx_cntrs = ncnt;
Packit 577717
Packit 577717
	_ia64_vector.cmp_info.clock_ticks = sysconf( _SC_CLK_TCK );
Packit 577717
	/* Put the signal handler in use to consume PFM_END_MSG's */
Packit 577717
	_papi_hwi_start_signal( _ia64_vector.cmp_info.hardware_intr_sig, 1,
Packit 577717
							_ia64_vector.cmp_info.CmpIdx );
Packit 577717
Packit 577717
	retval = mmtimer_setup();
Packit 577717
	if ( retval )
Packit 577717
		return ( retval );
Packit 577717
Packit 577717
	retval =
Packit 577717
		generate_preset_search_map( &preset_search_map, ia_preset_search_map,
Packit 577717
									_ia64_vector.cmp_info.num_cntrs );
Packit 577717
	if ( retval )
Packit 577717
		return ( retval );
Packit 577717
Packit 577717
	retval = _papi_hwi_setup_all_presets( preset_search_map, NULL );
Packit 577717
	if ( retval )
Packit 577717
		return ( retval );
Packit 577717
Packit 577717
	/* get_memory_info has a CPU model argument that is not used,
Packit 577717
	 * faking it here with hw_info.model which is not set by this
Packit 577717
	 * component 
Packit 577717
	 */
Packit 577717
	retval = _linux_get_memory_info( &_papi_hwi_system_info.hw_info,
Packit 577717
				     _papi_hwi_system_info.hw_info.model );
Packit 577717
	if ( retval )
Packit 577717
		return ( retval );
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_init( hwd_context_t * zero )
Packit 577717
{
Packit 577717
#if defined(USE_PROC_PTTIMER)
Packit 577717
	{
Packit 577717
		char buf[LINE_MAX];
Packit 577717
		int fd;
Packit 577717
		sprintf( buf, "/proc/%d/task/%d/stat", getpid(  ), mygettid(  ) );
Packit 577717
		fd = open( buf, O_RDONLY );
Packit 577717
		if ( fd == -1 ) {
Packit 577717
			PAPIERROR( "open(%s)", buf );
Packit 577717
			return ( PAPI_ESYS );
Packit 577717
		}
Packit 577717
		zero->stat_fd = fd;
Packit 577717
	}
Packit 577717
#endif
Packit 577717
	return ( pfmw_create_context( zero ) );
Packit 577717
}
Packit 577717
Packit 577717
/* reset the hardware counters */
Packit 577717
int
Packit 577717
_ia64_reset( hwd_context_t * ctx, hwd_control_state_t * machdep )
Packit 577717
{
Packit 577717
	pfmw_param_t *pevt = &( machdep->evt );
Packit 577717
	pfarg_reg_t writeem[MAX_COUNTERS];
Packit 577717
	int i;
Packit 577717
Packit 577717
	pfmw_stop( ctx );
Packit 577717
	memset( writeem, 0, sizeof writeem );
Packit 577717
	for ( i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++ ) {
Packit 577717
		/* Writing doesn't matter, we're just zeroing the counter. */
Packit 577717
		writeem[i].reg_num = PMU_FIRST_COUNTER + i;
Packit 577717
		if ( PFMW_PEVT_PFPPC_REG_FLG( pevt, i ) & PFM_REGFL_OVFL_NOTIFY )
Packit 577717
			writeem[i].reg_value = machdep->pd[i].reg_long_reset;
Packit 577717
	}
Packit 577717
	if ( pfmw_perfmonctl
Packit 577717
		 ( ctx->tid, ctx->fd, PFM_WRITE_PMDS, writeem,
Packit 577717
		   _ia64_vector.cmp_info.num_cntrs ) == -1 ) {
Packit 577717
		PAPIERROR( "perfmonctl(PFM_WRITE_PMDS) errno %d", errno );
Packit 577717
		return PAPI_ESYS;
Packit 577717
	}
Packit 577717
	pfmw_start( ctx );
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_start( hwd_context_t * ctx, hwd_control_state_t * current_state )
Packit 577717
{
Packit 577717
	int i;
Packit 577717
	pfmw_param_t *pevt = &( current_state->evt );
Packit 577717
Packit 577717
	pfmw_stop( ctx );
Packit 577717
Packit 577717
/* write PMCS */
Packit 577717
	if ( pfmw_perfmonctl( ctx->tid, ctx->fd, PFM_WRITE_PMCS,
Packit 577717
						  PFMW_PEVT_PFPPC( pevt ),
Packit 577717
						  PFMW_PEVT_PFPPC_COUNT( pevt ) ) == -1 ) {
Packit 577717
		PAPIERROR( "perfmonctl(PFM_WRITE_PMCS) errno %d", errno );
Packit 577717
		return ( PAPI_ESYS );
Packit 577717
	}
Packit 577717
	if ( pfmw_perfmonctl
Packit 577717
		 ( ctx->tid, ctx->fd, PFM_WRITE_PMDS, PFMW_PEVT_PFPPD( pevt ),
Packit 577717
		   PFMW_PEVT_EVTCOUNT( pevt ) ) == -1 ) {
Packit 577717
		PAPIERROR( "perfmonctl(PFM_WRITE_PMDS) errno %d", errno );
Packit 577717
		return ( PAPI_ESYS );
Packit 577717
	}
Packit 577717
Packit 577717
/* set the initial value of the hardware counter , if PAPI_overflow or
Packit 577717
  PAPI_profil are called, then the initial value is the threshold
Packit 577717
*/
Packit 577717
	for ( i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++ )
Packit 577717
		current_state->pd[i].reg_num = PMU_FIRST_COUNTER + i;
Packit 577717
Packit 577717
	if ( pfmw_perfmonctl( ctx->tid, ctx->fd,
Packit 577717
						  PFM_WRITE_PMDS, current_state->pd,
Packit 577717
						  _ia64_vector.cmp_info.num_cntrs ) == -1 ) {
Packit 577717
		PAPIERROR( "perfmonctl(WRITE_PMDS) errno %d", errno );
Packit 577717
		return ( PAPI_ESYS );
Packit 577717
	}
Packit 577717
Packit 577717
	pfmw_start( ctx );
Packit 577717
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_stop( hwd_context_t * ctx, hwd_control_state_t * zero )
Packit 577717
{
Packit 577717
	( void ) zero;			 /*unused */
Packit 577717
	pfmw_stop( ctx );
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
round_requested_ns( int ns )
Packit 577717
{
Packit 577717
	if ( ns < _papi_os_info.itimer_res_ns ) {
Packit 577717
		return _papi_os_info.itimer_res_ns;
Packit 577717
	} else {
Packit 577717
		int leftover_ns = ns % _papi_os_info.itimer_res_ns;
Packit 577717
		return ns + leftover_ns;
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_ctl( hwd_context_t * zero, int code, _papi_int_option_t * option )
Packit 577717
{
Packit 577717
	int ret;
Packit 577717
	switch ( code ) {
Packit 577717
	case PAPI_DEFDOM:
Packit 577717
		return ( set_default_domain( option->domain.ESI->ctl_state,
Packit 577717
									 option->domain.domain ) );
Packit 577717
	case PAPI_DOMAIN:
Packit 577717
		return ( _ia64_set_domain
Packit 577717
				 ( option->domain.ESI->ctl_state, option->domain.domain ) );
Packit 577717
	case PAPI_DEFGRN:
Packit 577717
		return ( set_default_granularity
Packit 577717
				 ( option->granularity.ESI->ctl_state,
Packit 577717
				   option->granularity.granularity ) );
Packit 577717
	case PAPI_GRANUL:
Packit 577717
		return ( set_granularity( option->granularity.ESI->ctl_state,
Packit 577717
								  option->granularity.granularity ) );
Packit 577717
#if 0
Packit 577717
	case PAPI_INHERIT:
Packit 577717
		return ( set_inherit( option->inherit.inherit ) );
Packit 577717
#endif
Packit 577717
	case PAPI_DATA_ADDRESS:
Packit 577717
		ret =
Packit 577717
			set_default_domain( option->address_range.ESI->ctl_state,
Packit 577717
								option->address_range.domain );
Packit 577717
		if ( ret != PAPI_OK )
Packit 577717
			return ( ret );
Packit 577717
		set_drange( zero, option->address_range.ESI->ctl_state, option );
Packit 577717
		return ( PAPI_OK );
Packit 577717
	case PAPI_INSTR_ADDRESS:
Packit 577717
		ret =
Packit 577717
			set_default_domain( option->address_range.ESI->ctl_state,
Packit 577717
								option->address_range.domain );
Packit 577717
		if ( ret != PAPI_OK )
Packit 577717
			return ( ret );
Packit 577717
		set_irange( zero, option->address_range.ESI->ctl_state, option );
Packit 577717
		return ( PAPI_OK );
Packit 577717
	case PAPI_DEF_ITIMER:{
Packit 577717
		/* flags are currently ignored, eventually the flags will be able
Packit 577717
		   to specify whether or not we use POSIX itimers (clock_gettimer) */
Packit 577717
		if ( ( option->itimer.itimer_num == ITIMER_REAL ) &&
Packit 577717
			 ( option->itimer.itimer_sig != SIGALRM ) )
Packit 577717
			return PAPI_EINVAL;
Packit 577717
		if ( ( option->itimer.itimer_num == ITIMER_VIRTUAL ) &&
Packit 577717
			 ( option->itimer.itimer_sig != SIGVTALRM ) )
Packit 577717
			return PAPI_EINVAL;
Packit 577717
		if ( ( option->itimer.itimer_num == ITIMER_PROF ) &&
Packit 577717
			 ( option->itimer.itimer_sig != SIGPROF ) )
Packit 577717
			return PAPI_EINVAL;
Packit 577717
		if ( option->itimer.ns > 0 )
Packit 577717
			option->itimer.ns = round_requested_ns( option->itimer.ns );
Packit 577717
		/* At this point, we assume the user knows what he or
Packit 577717
		   she is doing, they maybe doing something arch specific */
Packit 577717
		return PAPI_OK;
Packit 577717
	}
Packit 577717
	case PAPI_DEF_MPX_NS:{
Packit 577717
		option->multiplex.ns = round_requested_ns( option->multiplex.ns );
Packit 577717
		return ( PAPI_OK );
Packit 577717
	}
Packit 577717
	case PAPI_DEF_ITIMER_NS:{
Packit 577717
		option->itimer.ns = round_requested_ns( option->itimer.ns );
Packit 577717
		return ( PAPI_OK );
Packit 577717
	}
Packit 577717
	default:
Packit 577717
		return ( PAPI_EINVAL );
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_shutdown( hwd_context_t * ctx )
Packit 577717
{
Packit 577717
#if defined(USE_PROC_PTTIMER)
Packit 577717
	close( ctx->stat_fd );
Packit 577717
#endif
Packit 577717
Packit 577717
	return ( pfmw_destroy_context( ctx ) );
Packit 577717
}
Packit 577717
Packit 577717
static int
Packit 577717
ia64_ita_process_profile_buffer( ThreadInfo_t * thread, EventSetInfo_t * ESI )
Packit 577717
{
Packit 577717
	( void ) thread;		 /*unused */
Packit 577717
	pfmw_smpl_hdr_t *hdr;
Packit 577717
	pfmw_smpl_entry_t *ent;
Packit 577717
	unsigned long buf_pos;
Packit 577717
	unsigned long entry_size;
Packit 577717
	int ret, reg_num, count, pos;
Packit 577717
	unsigned int i, EventCode = 0, eventindex, native_index = 0;
Packit 577717
	ia64_control_state_t *this_state;
Packit 577717
	pfm_ita_pmd_reg_t *reg;
Packit 577717
	unsigned long overflow_vector, pc;
Packit 577717
Packit 577717
Packit 577717
	if ( ( ESI->state & PAPI_PROFILING ) == 0 )
Packit 577717
		return ( PAPI_EBUG );
Packit 577717
Packit 577717
	this_state = ( ia64_control_state_t * ) ( ESI->ctl_state );
Packit 577717
	hdr = ( pfmw_smpl_hdr_t * ) this_state->smpl_vaddr;
Packit 577717
Packit 577717
	entry_size = sizeof ( pfmw_smpl_entry_t );
Packit 577717
Packit 577717
	/*
Packit 577717
	 * walk through all the entries recorded in the buffer
Packit 577717
	 */
Packit 577717
	buf_pos = ( unsigned long ) ( hdr + 1 );
Packit 577717
	for ( i = 0; i < hdr->hdr_count; i++ ) {
Packit 577717
		ret = 0;
Packit 577717
		ent = ( pfmw_smpl_entry_t * ) buf_pos;
Packit 577717
		/* PFM30 only one PMD overflows in each sample */
Packit 577717
		overflow_vector = 1 << ent->ovfl_pmd;
Packit 577717
Packit 577717
		SUBDBG( "Entry %d PID:%d CPU:%d ovfl_vector:%#lx IIP:%#016lx\n",
Packit 577717
				i, ent->pid, ent->cpu, overflow_vector, ent->ip );
Packit 577717
Packit 577717
		while ( overflow_vector ) {
Packit 577717
			reg_num = ffs( overflow_vector ) - 1;
Packit 577717
			/* find the event code */
Packit 577717
			for ( count = 0; count < ESI->profile.event_counter; count++ ) {
Packit 577717
				eventindex = ESI->profile.EventIndex[count];
Packit 577717
				pos = ESI->EventInfoArray[eventindex].pos[0];
Packit 577717
				if ( pos + PMU_FIRST_COUNTER == reg_num ) {
Packit 577717
					EventCode = ESI->profile.EventCode[count];
Packit 577717
					native_index =
Packit 577717
						ESI->NativeInfoArray[pos].
Packit 577717
						ni_event & PAPI_NATIVE_AND_MASK;
Packit 577717
					break;
Packit 577717
				}
Packit 577717
			}
Packit 577717
			/* something is wrong */
Packit 577717
			if ( count == ESI->profile.event_counter ) {
Packit 577717
				PAPIERROR
Packit 577717
					( "wrong count: %d vs. ESI->profile.event_counter %d\n",
Packit 577717
					  count, ESI->profile.event_counter );
Packit 577717
				return ( PAPI_EBUG );
Packit 577717
			}
Packit 577717
Packit 577717
			/* print entry header */
Packit 577717
			pc = ent->ip;
Packit 577717
			if ( pfm_ita_is_dear( native_index ) ) {
Packit 577717
				reg = ( pfm_ita_pmd_reg_t * ) ( ent + 1 );
Packit 577717
				reg++;
Packit 577717
				reg++;
Packit 577717
				pc = ( reg->pmd17_ita_reg.dear_iaddr << 4 ) | ( reg->
Packit 577717
																pmd17_ita_reg.
Packit 577717
																dear_slot );
Packit 577717
				/* adjust pointer position */
Packit 577717
				buf_pos += ( hweight64( DEAR_REGS_MASK ) << 3 );
Packit 577717
			}
Packit 577717
Packit 577717
			_papi_hwi_dispatch_profile( ESI, ( caddr_t ) pc, ( long long ) 0,
Packit 577717
										count );
Packit 577717
			overflow_vector ^= ( unsigned long ) 1 << reg_num;
Packit 577717
		}
Packit 577717
		/*  move to next entry */
Packit 577717
		buf_pos += entry_size;
Packit 577717
	}						 /* end of if */
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
static int
Packit 577717
ia64_ita2_process_profile_buffer( ThreadInfo_t * thread, EventSetInfo_t * ESI )
Packit 577717
{
Packit 577717
	( void ) thread;		 /*unused */
Packit 577717
	pfmw_smpl_hdr_t *hdr;
Packit 577717
	pfmw_smpl_entry_t *ent;
Packit 577717
	unsigned long buf_pos;
Packit 577717
	unsigned long entry_size;
Packit 577717
	int ret, reg_num, count, pos;
Packit 577717
	unsigned int i, EventCode = 0, eventindex, native_index = 0;
Packit 577717
	ia64_control_state_t *this_state;
Packit 577717
	pfm_ita2_pmd_reg_t *reg;
Packit 577717
	unsigned long overflow_vector, pc;
Packit 577717
Packit 577717
Packit 577717
	if ( ( ESI->state & PAPI_PROFILING ) == 0 )
Packit 577717
		return ( PAPI_EBUG );
Packit 577717
Packit 577717
	this_state = ( ia64_control_state_t * ) ( ESI->ctl_state );
Packit 577717
	hdr = ( pfmw_smpl_hdr_t * ) ( this_state->smpl_vaddr );
Packit 577717
Packit 577717
	entry_size = sizeof ( pfmw_smpl_entry_t );
Packit 577717
Packit 577717
	/*
Packit 577717
	 * walk through all the entries recorded in the buffer
Packit 577717
	 */
Packit 577717
	buf_pos = ( unsigned long ) ( hdr + 1 );
Packit 577717
	for ( i = 0; i < hdr->hdr_count; i++ ) {
Packit 577717
		ret = 0;
Packit 577717
		ent = ( pfmw_smpl_entry_t * ) buf_pos;
Packit 577717
		/* PFM30 only one PMD overflows in each sample */
Packit 577717
		overflow_vector = 1 << ent->ovfl_pmd;
Packit 577717
Packit 577717
		SUBDBG( "Entry %d PID:%d CPU:%d ovfl_vector:%#lx IIP:%#016lx\n",
Packit 577717
				i, ent->pid, ent->cpu, overflow_vector, ent->ip );
Packit 577717
Packit 577717
		while ( overflow_vector ) {
Packit 577717
			reg_num = ffs( overflow_vector ) - 1;
Packit 577717
			/* find the event code */
Packit 577717
			for ( count = 0; count < ESI->profile.event_counter; count++ ) {
Packit 577717
				eventindex = ESI->profile.EventIndex[count];
Packit 577717
				pos = ESI->EventInfoArray[eventindex].pos[0];
Packit 577717
				if ( pos + PMU_FIRST_COUNTER == reg_num ) {
Packit 577717
					EventCode = ESI->profile.EventCode[count];
Packit 577717
					native_index =
Packit 577717
						ESI->NativeInfoArray[pos].
Packit 577717
						ni_event & PAPI_NATIVE_AND_MASK;
Packit 577717
					break;
Packit 577717
				}
Packit 577717
			}
Packit 577717
			/* something is wrong */
Packit 577717
			if ( count == ESI->profile.event_counter ) {
Packit 577717
				PAPIERROR
Packit 577717
					( "wrong count: %d vs. ESI->profile.event_counter %d\n",
Packit 577717
					  count, ESI->profile.event_counter );
Packit 577717
				return ( PAPI_EBUG );
Packit 577717
			}
Packit 577717
Packit 577717
			/* print entry header */
Packit 577717
			pc = ent->ip;
Packit 577717
			if ( pfm_ita2_is_dear( native_index ) ) {
Packit 577717
				reg = ( pfm_ita2_pmd_reg_t * ) ( ent + 1 );
Packit 577717
				reg++;
Packit 577717
				reg++;
Packit 577717
				pc = ( ( reg->pmd17_ita2_reg.dear_iaddr +
Packit 577717
						 reg->pmd17_ita2_reg.dear_bn ) << 4 )
Packit 577717
					| reg->pmd17_ita2_reg.dear_slot;
Packit 577717
Packit 577717
				/* adjust pointer position */
Packit 577717
				buf_pos += ( hweight64( DEAR_REGS_MASK ) << 3 );
Packit 577717
			}
Packit 577717
Packit 577717
			_papi_hwi_dispatch_profile( ESI, ( caddr_t ) pc, ( long long ) 0,
Packit 577717
										count );
Packit 577717
			overflow_vector ^= ( unsigned long ) 1 << reg_num;
Packit 577717
		}
Packit 577717
		/*  move to next entry */
Packit 577717
		buf_pos += entry_size;
Packit 577717
	}						 /* end of if */
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
static int
Packit 577717
ia64_mont_process_profile_buffer( ThreadInfo_t * thread, EventSetInfo_t * ESI )
Packit 577717
{
Packit 577717
	( void ) thread;		 /*unused */
Packit 577717
	pfmw_smpl_hdr_t *hdr;
Packit 577717
	pfmw_smpl_entry_t *ent;
Packit 577717
	unsigned long buf_pos;
Packit 577717
	unsigned long entry_size;
Packit 577717
	int ret, reg_num, count, pos;
Packit 577717
	unsigned int i, EventCode = 0, eventindex, native_index = 0;
Packit 577717
	ia64_control_state_t *this_state;
Packit 577717
	pfm_mont_pmd_reg_t *reg;
Packit 577717
	unsigned long overflow_vector, pc;
Packit 577717
	unsigned int umask;
Packit 577717
Packit 577717
Packit 577717
	if ( ( ESI->state & PAPI_PROFILING ) == 0 )
Packit 577717
		return ( PAPI_EBUG );
Packit 577717
Packit 577717
	this_state = ( ia64_control_state_t * ) ESI->ctl_state;
Packit 577717
	hdr = ( pfmw_smpl_hdr_t * ) this_state->smpl_vaddr;
Packit 577717
Packit 577717
	entry_size = sizeof ( pfmw_smpl_entry_t );
Packit 577717
Packit 577717
	/*
Packit 577717
	 * walk through all the entries recorded in the buffer
Packit 577717
	 */
Packit 577717
	buf_pos = ( unsigned long ) ( hdr + 1 );
Packit 577717
	for ( i = 0; i < hdr->hdr_count; i++ ) {
Packit 577717
		ret = 0;
Packit 577717
		ent = ( pfmw_smpl_entry_t * ) buf_pos;
Packit 577717
		/* PFM30 only one PMD overflows in each sample */
Packit 577717
		overflow_vector = 1 << ent->ovfl_pmd;
Packit 577717
Packit 577717
		SUBDBG( "Entry %d PID:%d CPU:%d ovfl_vector:%#lx IIP:%#016lx\n",
Packit 577717
				i, ent->pid, ent->cpu, overflow_vector, ent->ip );
Packit 577717
Packit 577717
		while ( overflow_vector ) {
Packit 577717
			reg_num = ffs( overflow_vector ) - 1;
Packit 577717
			/* find the event code */
Packit 577717
			for ( count = 0; count < ESI->profile.event_counter; count++ ) {
Packit 577717
				eventindex = ESI->profile.EventIndex[count];
Packit 577717
				pos = ESI->EventInfoArray[eventindex].pos[0];
Packit 577717
				if ( pos + PMU_FIRST_COUNTER == reg_num ) {
Packit 577717
					EventCode = ESI->profile.EventCode[count];
Packit 577717
					if ( _pfm_decode_native_event
Packit 577717
						 ( ESI->NativeInfoArray[pos].ni_event, &native_index,
Packit 577717
						   &umask ) != PAPI_OK )
Packit 577717
						return ( PAPI_ENOEVNT );
Packit 577717
					break;
Packit 577717
				}
Packit 577717
			}
Packit 577717
			/* something is wrong */
Packit 577717
			if ( count == ESI->profile.event_counter ) {
Packit 577717
				PAPIERROR
Packit 577717
					( "wrong count: %d vs. ESI->profile.event_counter %d\n",
Packit 577717
					  count, ESI->profile.event_counter );
Packit 577717
				return ( PAPI_EBUG );
Packit 577717
			}
Packit 577717
Packit 577717
			/* print entry header */
Packit 577717
			pc = ent->ip;
Packit 577717
			if ( pfm_mont_is_dear( native_index ) ) {
Packit 577717
				reg = ( pfm_mont_pmd_reg_t * ) ( ent + 1 );
Packit 577717
				reg++;
Packit 577717
				reg++;
Packit 577717
				pc = ( ( reg->pmd36_mont_reg.dear_iaddr +
Packit 577717
						 reg->pmd36_mont_reg.dear_bn ) << 4 )
Packit 577717
					| reg->pmd36_mont_reg.dear_slot;
Packit 577717
				/* adjust pointer position */
Packit 577717
				buf_pos += ( hweight64( DEAR_REGS_MASK ) << 3 );
Packit 577717
			}
Packit 577717
Packit 577717
			_papi_hwi_dispatch_profile( ESI, ( caddr_t ) pc, ( long long ) 0,
Packit 577717
										count );
Packit 577717
			overflow_vector ^= ( unsigned long ) 1 << reg_num;
Packit 577717
		}
Packit 577717
		/*  move to next entry */
Packit 577717
		buf_pos += entry_size;
Packit 577717
	}						 /* end of if */
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
static int
Packit 577717
ia64_process_profile_buffer( ThreadInfo_t * thread, EventSetInfo_t * ESI )
Packit 577717
{
Packit 577717
	switch ( _perfmon2_pfm_pmu_type ) {
Packit 577717
	case PFMLIB_ITANIUM_PMU:
Packit 577717
		return ( ia64_ita_process_profile_buffer( thread, ESI ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_ITANIUM2_PMU:
Packit 577717
		return ( ia64_ita2_process_profile_buffer( thread, ESI ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_MONTECITO_PMU:
Packit 577717
		return ( ia64_mont_process_profile_buffer( thread, ESI ) );
Packit 577717
		break;
Packit 577717
	default:
Packit 577717
		PAPIERROR( "PMU type %d is not supported by this component",
Packit 577717
				   _perfmon2_pfm_pmu_type );
Packit 577717
		return ( PAPI_EBUG );
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
static  void
Packit 577717
ia64_dispatch_sigprof( int n, hwd_siginfo_t * info, hwd_ucontext_t *sc )
Packit 577717
{
Packit 577717
	( void ) n;				 /*unused */
Packit 577717
	_papi_hwi_context_t ctx;
Packit 577717
	ThreadInfo_t *thread = _papi_hwi_lookup_thread( 0 );
Packit 577717
	caddr_t address;
Packit 577717
	int cidx = _ia64_vector.cmp_info.CmpIdx;
Packit 577717
Packit 577717
#if defined(DEBUG)
Packit 577717
	if ( thread == NULL ) {
Packit 577717
		PAPIERROR( "thread == NULL in _papi_hwd_dispatch_timer!" );
Packit 577717
		return;
Packit 577717
	}
Packit 577717
#endif
Packit 577717
Packit 577717
	ctx.si = info;
Packit 577717
	ctx.ucontext = sc;
Packit 577717
	address = GET_OVERFLOW_ADDRESS( ( ctx ) );
Packit 577717
Packit 577717
	if ( ( thread == NULL ) || ( thread->running_eventset[cidx] == NULL ) ) {
Packit 577717
		SUBDBG( "%p, %p\n", thread, thread->running_eventset[cidx] );
Packit 577717
		return;
Packit 577717
	}
Packit 577717
Packit 577717
	if ( thread->running_eventset[cidx]->overflow.
Packit 577717
		 flags & PAPI_OVERFLOW_FORCE_SW ) {
Packit 577717
		_papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address, NULL, 0,
Packit 577717
											0, &thread, cidx );
Packit 577717
		return;
Packit 577717
	}
Packit 577717
Packit 577717
	pfm_msg_t msg;
Packit 577717
	int ret, fd;
Packit 577717
	fd = info->si_fd;
Packit 577717
  retry:
Packit 577717
	ret = read( fd, &msg, sizeof ( msg ) );
Packit 577717
	if ( ret == -1 ) {
Packit 577717
		if ( errno == EINTR ) {
Packit 577717
			SUBDBG( "read(%d) interrupted, retrying\n", fd );
Packit 577717
			goto retry;
Packit 577717
		} else {
Packit 577717
			PAPIERROR( "read(%d): errno %d", fd, errno );
Packit 577717
		}
Packit 577717
	} else if ( ret != sizeof ( msg ) ) {
Packit 577717
		PAPIERROR( "read(%d): short %d vs. %d bytes", fd, ret, sizeof ( msg ) );
Packit 577717
		ret = -1;
Packit 577717
	}
Packit 577717
#if defined(HAVE_PFM_MSG_TYPE)
Packit 577717
	if ( msg.type == PFM_MSG_END ) {
Packit 577717
		SUBDBG( "PFM_MSG_END\n" );
Packit 577717
		return;
Packit 577717
	}
Packit 577717
	if ( msg.type != PFM_MSG_OVFL ) {
Packit 577717
		PAPIERROR( "unexpected msg type %d", msg.type );
Packit 577717
		return;
Packit 577717
	}
Packit 577717
#else
Packit 577717
	if ( msg.pfm_gen_msg.msg_type == PFM_MSG_END ) {
Packit 577717
		SUBDBG( "PFM_MSG_END\n" );
Packit 577717
		return;
Packit 577717
	}
Packit 577717
	if ( msg.pfm_gen_msg.msg_type != PFM_MSG_OVFL ) {
Packit 577717
		PAPIERROR( "unexpected msg type %d", msg.pfm_gen_msg.msg_type );
Packit 577717
		return;
Packit 577717
	}
Packit 577717
#endif
Packit 577717
	if ( ret != -1 ) {
Packit 577717
		if ( ( thread->running_eventset[cidx]->state & PAPI_PROFILING ) &&
Packit 577717
			 !( thread->running_eventset[cidx]->profile.
Packit 577717
				flags & PAPI_PROFIL_FORCE_SW ) )
Packit 577717
			ia64_process_profile_buffer( thread,
Packit 577717
										 thread->running_eventset[cidx] );
Packit 577717
		else
Packit 577717
			_papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address,
Packit 577717
												NULL,
Packit 577717
												msg.pfm_ovfl_msg.
Packit 577717
												msg_ovfl_pmds[0] >>
Packit 577717
												PMU_FIRST_COUNTER, 0,
Packit 577717
												&thread, cidx );
Packit 577717
	}
Packit 577717
	if ( pfmw_perfmonctl( 0, fd, PFM_RESTART, 0, 0 ) == -1 ) {
Packit 577717
		PAPIERROR( "perfmonctl(PFM_RESTART) errno %d, %s", errno,
Packit 577717
				   strerror( errno ) );
Packit 577717
		return;
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
void
Packit 577717
_ia64_dispatch_timer( int signal, hwd_siginfo_t * info, void *context )
Packit 577717
{
Packit 577717
	ia64_dispatch_sigprof( signal, info, context );
Packit 577717
}
Packit 577717
Packit 577717
static int
Packit 577717
set_notify( EventSetInfo_t * ESI, int index, int value )
Packit 577717
{
Packit 577717
	int *pos, count, i;
Packit 577717
	unsigned int hwcntr;
Packit 577717
	pfmw_param_t *pevt =
Packit 577717
		&( ( ( ia64_control_state_t * ) ESI->ctl_state )->evt );
Packit 577717
Packit 577717
	pos = ESI->EventInfoArray[index].pos;
Packit 577717
	count = 0;
Packit 577717
	while ( pos[count] != -1 && count < _ia64_vector.cmp_info.num_cntrs ) {
Packit 577717
		hwcntr = pos[count] + PMU_FIRST_COUNTER;
Packit 577717
		for ( i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++ ) {
Packit 577717
			if ( PFMW_PEVT_PFPPC_REG_NUM( pevt, i ) == hwcntr ) {
Packit 577717
				SUBDBG( "Found hw counter %d in %d, flags %d\n", hwcntr, i,
Packit 577717
						value );
Packit 577717
				PFMW_PEVT_PFPPC_REG_FLG( pevt, i ) = value;
Packit 577717
/*
Packit 577717
         #ifdef PFM30
Packit 577717
            if (value)
Packit 577717
               pevt->pc[i].reg_reset_pmds[0] = 1UL << pevt->pc[i].reg_num;
Packit 577717
            else 
Packit 577717
               pevt->pc[i].reg_reset_pmds[0] = 0;
Packit 577717
         #endif
Packit 577717
*/
Packit 577717
				break;
Packit 577717
			}
Packit 577717
		}
Packit 577717
		count++;
Packit 577717
	}
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_stop_profiling( ThreadInfo_t * thread, EventSetInfo_t * ESI )
Packit 577717
{
Packit 577717
	int cidx = _ia64_vector.cmp_info.CmpIdx;
Packit 577717
Packit 577717
	pfmw_stop( thread->context[cidx] );
Packit 577717
	return ( ia64_process_profile_buffer( thread, ESI ) );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
int
Packit 577717
_ia64_set_profile( EventSetInfo_t * ESI, int EventIndex, int threshold )
Packit 577717
{
Packit 577717
	int cidx = _ia64_vector.cmp_info.CmpIdx;
Packit 577717
	hwd_control_state_t *this_state = ESI->ctl_state;
Packit 577717
	hwd_context_t *ctx = ESI->master->context[cidx];
Packit 577717
	int ret;
Packit 577717
Packit 577717
	ret = _ia64_vector.set_overflow( ESI, EventIndex, threshold );
Packit 577717
	if ( ret != PAPI_OK )
Packit 577717
		return ret;
Packit 577717
	ret = pfmw_destroy_context( ctx );
Packit 577717
	if ( ret != PAPI_OK )
Packit 577717
		return ret;
Packit 577717
	if ( threshold == 0 )
Packit 577717
		ret = pfmw_create_context( ctx );
Packit 577717
	else
Packit 577717
		ret =
Packit 577717
			pfmw_recreate_context( ESI, ctx, &this_state->smpl_vaddr,
Packit 577717
								   EventIndex );
Packit 577717
Packit 577717
//#warning "This should be handled in the high level layers"
Packit 577717
	ESI->state ^= PAPI_OVERFLOWING;
Packit 577717
	ESI->overflow.flags ^= PAPI_OVERFLOW_HARDWARE;
Packit 577717
Packit 577717
	return ( ret );
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_set_overflow( EventSetInfo_t * ESI, int EventIndex, int threshold )
Packit 577717
{
Packit 577717
	hwd_control_state_t *this_state = ESI->ctl_state;
Packit 577717
	int j, retval = PAPI_OK, *pos;
Packit 577717
	int cidx = _ia64_vector.cmp_info.CmpIdx;
Packit 577717
Packit 577717
	pos = ESI->EventInfoArray[EventIndex].pos;
Packit 577717
	j = pos[0];
Packit 577717
	SUBDBG( "Hardware counter %d used in overflow, threshold %d\n", j,
Packit 577717
			threshold );
Packit 577717
Packit 577717
	if ( threshold == 0 ) {
Packit 577717
		/* Remove the signal handler */
Packit 577717
Packit 577717
		retval = _papi_hwi_stop_signal( _ia64_vector.cmp_info.hardware_intr_sig );
Packit 577717
		if ( retval != PAPI_OK )
Packit 577717
			return ( retval );
Packit 577717
Packit 577717
		/* Remove the overflow notifier on the proper event. */
Packit 577717
Packit 577717
		set_notify( ESI, EventIndex, 0 );
Packit 577717
Packit 577717
		this_state->pd[j].reg_value = 0;
Packit 577717
		this_state->pd[j].reg_long_reset = 0;
Packit 577717
		this_state->pd[j].reg_short_reset = 0;
Packit 577717
	} else {
Packit 577717
		retval =
Packit 577717
			_papi_hwi_start_signal( _ia64_vector.cmp_info.hardware_intr_sig, 1,
Packit 577717
									cidx );
Packit 577717
		if ( retval != PAPI_OK )
Packit 577717
			return ( retval );
Packit 577717
Packit 577717
		/* Set the overflow notifier on the proper event. Remember that selector */
Packit 577717
Packit 577717
		set_notify( ESI, EventIndex, PFM_REGFL_OVFL_NOTIFY );
Packit 577717
Packit 577717
		this_state->pd[j].reg_value =
Packit 577717
			( ~0UL ) - ( unsigned long ) threshold + 1;
Packit 577717
		this_state->pd[j].reg_short_reset =
Packit 577717
			( ~0UL ) - ( unsigned long ) threshold + 1;
Packit 577717
		this_state->pd[j].reg_long_reset =
Packit 577717
			( ~0UL ) - ( unsigned long ) threshold + 1;
Packit 577717
Packit 577717
	}
Packit 577717
	return ( retval );
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_ntv_code_to_name( unsigned int EventCode, char *ntv_name, int len )
Packit 577717
{
Packit 577717
	if ( _perfmon2_pfm_pmu_type == PFMLIB_MONTECITO_PMU )
Packit 577717
		return ( _papi_pfm_ntv_code_to_name( EventCode, ntv_name, len ) );
Packit 577717
	else {
Packit 577717
		char name[PAPI_MAX_STR_LEN];
Packit 577717
		int ret = 0;
Packit 577717
Packit 577717
		pfmw_get_event_name( name, EventCode ^ PAPI_NATIVE_MASK );
Packit 577717
Packit 577717
		if ( ret != PAPI_OK )
Packit 577717
			return ( PAPI_ENOEVNT );
Packit 577717
Packit 577717
		strncpy( ntv_name, name, len );
Packit 577717
		return ( PAPI_OK );
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_ntv_code_to_descr( unsigned int EventCode, char *ntv_descr, int len )
Packit 577717
{
Packit 577717
	if ( _perfmon2_pfm_pmu_type == PFMLIB_MONTECITO_PMU )
Packit 577717
		return ( _papi_pfm_ntv_code_to_descr( EventCode, ntv_descr, len ) );
Packit 577717
	else {
Packit 577717
#if defined(HAVE_PFM_GET_EVENT_DESCRIPTION)
Packit 577717
		pfmw_get_event_description( EventCode ^ PAPI_NATIVE_MASK, ntv_descr,
Packit 577717
									len );
Packit 577717
		return ( PAPI_OK );
Packit 577717
#else
Packit 577717
		return ( _ia64_ntv_code_to_name( EventCode, ntv_descr, len ) );
Packit 577717
#endif
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
static  int
Packit 577717
_ia64_modify_event( unsigned int event, int modifier )
Packit 577717
{
Packit 577717
	switch ( modifier ) {
Packit 577717
	case PAPI_NTV_ENUM_IARR:
Packit 577717
		return ( pfmw_support_iarr( event ) );
Packit 577717
	case PAPI_NTV_ENUM_DARR:
Packit 577717
		return ( pfmw_support_darr( event ) );
Packit 577717
	case PAPI_NTV_ENUM_OPCM:
Packit 577717
		return ( pfmw_support_opcm( event ) );
Packit 577717
	case PAPI_NTV_ENUM_DEAR:
Packit 577717
		return ( pfmw_is_dear( event ) );
Packit 577717
	case PAPI_NTV_ENUM_IEAR:
Packit 577717
		return ( pfmw_is_iear( event ) );
Packit 577717
	default:
Packit 577717
		return ( 1 );
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_ntv_enum_events( unsigned int *EventCode, int modifier )
Packit 577717
{
Packit 577717
	if ( _perfmon2_pfm_pmu_type == PFMLIB_MONTECITO_PMU )
Packit 577717
		return ( _papi_pfm_ntv_enum_events( EventCode, modifier ) );
Packit 577717
	else {
Packit 577717
		int index = *EventCode & PAPI_NATIVE_AND_MASK;
Packit 577717
Packit 577717
		if ( modifier == PAPI_ENUM_FIRST ) {
Packit 577717
			*EventCode = PAPI_NATIVE_MASK;
Packit 577717
			return ( PAPI_OK );
Packit 577717
		}
Packit 577717
Packit 577717
		while ( index++ < _ia64_vector.cmp_info.num_native_events - 1 ) {
Packit 577717
			*EventCode += 1;
Packit 577717
			if ( _ia64_modify_event
Packit 577717
				 ( ( *EventCode ^ PAPI_NATIVE_MASK ), modifier ) )
Packit 577717
				return ( PAPI_OK );
Packit 577717
		}
Packit 577717
		return ( PAPI_ENOEVNT );
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_ita_init_control_state( hwd_control_state_t * this_state )
Packit 577717
{
Packit 577717
	pfmw_param_t *evt;
Packit 577717
	pfmw_ita1_param_t *param;
Packit 577717
	ia64_control_state_t *ptr;
Packit 577717
Packit 577717
	ptr = ( ia64_control_state_t * ) this_state;
Packit 577717
	evt = &( ptr->evt );
Packit 577717
Packit 577717
	param = &( ptr->ita_lib_param.ita_param );
Packit 577717
	memset( evt, 0, sizeof ( pfmw_param_t ) );
Packit 577717
	memset( param, 0, sizeof ( pfmw_ita1_param_t ) );
Packit 577717
Packit 577717
	_ia64_ita_set_domain( this_state, _ia64_vector.cmp_info.default_domain );
Packit 577717
/* set library parameter pointer */
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_ita2_init_control_state( hwd_control_state_t * this_state )
Packit 577717
{
Packit 577717
	pfmw_param_t *evt;
Packit 577717
	pfmw_ita2_param_t *param;
Packit 577717
	ia64_control_state_t *ptr;
Packit 577717
Packit 577717
	ptr = ( ia64_control_state_t * ) this_state;
Packit 577717
	evt = &( ptr->evt );
Packit 577717
Packit 577717
	param = &( ptr->ita_lib_param.ita2_param );
Packit 577717
	memset( evt, 0, sizeof ( pfmw_param_t ) );
Packit 577717
	memset( param, 0, sizeof ( pfmw_ita2_param_t ) );
Packit 577717
Packit 577717
	_ia64_ita2_set_domain( this_state, _ia64_vector.cmp_info.default_domain );
Packit 577717
/* set library parameter pointer */
Packit 577717
	evt->mod_inp = &( param->ita2_input_param );
Packit 577717
	evt->mod_outp = &( param->ita2_output_param );
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_mont_init_control_state( hwd_control_state_t * this_state )
Packit 577717
{
Packit 577717
	pfmw_param_t *evt;
Packit 577717
	pfmw_mont_param_t *param;
Packit 577717
	ia64_control_state_t *ptr;
Packit 577717
Packit 577717
	ptr = ( ia64_control_state_t * ) this_state;
Packit 577717
	evt = &( ptr->evt );
Packit 577717
Packit 577717
	param = &( ptr->ita_lib_param.mont_param );
Packit 577717
	memset( evt, 0, sizeof ( pfmw_param_t ) );
Packit 577717
	memset( param, 0, sizeof ( pfmw_mont_param_t ) );
Packit 577717
Packit 577717
	_ia64_mont_set_domain( this_state, _ia64_vector.cmp_info.default_domain );
Packit 577717
/* set library parameter pointer */
Packit 577717
	evt->mod_inp = &( param->mont_input_param );
Packit 577717
	evt->mod_outp = &( param->mont_output_param );
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_init_control_state( hwd_control_state_t * this_state )
Packit 577717
{
Packit 577717
	switch ( _perfmon2_pfm_pmu_type ) {
Packit 577717
	case PFMLIB_ITANIUM_PMU:
Packit 577717
		return ( _ia64_ita_init_control_state( this_state ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_ITANIUM2_PMU:
Packit 577717
		return ( _ia64_ita2_init_control_state( this_state ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_MONTECITO_PMU:
Packit 577717
		return ( _ia64_mont_init_control_state( this_state ) );
Packit 577717
		break;
Packit 577717
	default:
Packit 577717
		PAPIERROR( "PMU type %d is not supported by this component",
Packit 577717
				   _perfmon2_pfm_pmu_type );
Packit 577717
		return ( PAPI_EBUG );
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
void
Packit 577717
_ia64_remove_native( hwd_control_state_t * this_state,
Packit 577717
					 NativeInfo_t * nativeInfo )
Packit 577717
{
Packit 577717
	( void ) this_state;	 /*unused */
Packit 577717
	( void ) nativeInfo;	 /*unused */
Packit 577717
	return;
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_mont_update_control_state( hwd_control_state_t * this_state,
Packit 577717
								 NativeInfo_t * native, int count,
Packit 577717
								 hwd_context_t * zero )
Packit 577717
{
Packit 577717
	( void ) zero;			 /*unused */
Packit 577717
	int org_cnt;
Packit 577717
	pfmw_param_t *evt = &this_state->evt;
Packit 577717
	pfmw_param_t copy_evt;
Packit 577717
	unsigned int i, j, event, umask, EventCode;
Packit 577717
	pfmlib_event_t gete;
Packit 577717
	char name[128];
Packit 577717
Packit 577717
	if ( count == 0 ) {
Packit 577717
		for ( i = 0; i < ( unsigned int ) _ia64_vector.cmp_info.num_cntrs; i++ )
Packit 577717
			PFMW_PEVT_EVENT( evt, i ) = 0;
Packit 577717
		PFMW_PEVT_EVTCOUNT( evt ) = 0;
Packit 577717
		memset( PFMW_PEVT_PFPPC( evt ), 0, sizeof ( PFMW_PEVT_PFPPC( evt ) ) );
Packit 577717
		memset( &evt->inp.pfp_unavail_pmcs, 0, sizeof ( pfmlib_regmask_t ) );
Packit 577717
		return ( PAPI_OK );
Packit 577717
	}
Packit 577717
Packit 577717
/* save the old data */
Packit 577717
	org_cnt = PFMW_PEVT_EVTCOUNT( evt );
Packit 577717
Packit 577717
	memcpy( &copy_evt, evt, sizeof ( pfmw_param_t ) );
Packit 577717
Packit 577717
	for ( i = 0; i < ( unsigned int ) _ia64_vector.cmp_info.num_cntrs; i++ )
Packit 577717
		PFMW_PEVT_EVENT( evt, i ) = 0;
Packit 577717
	PFMW_PEVT_EVTCOUNT( evt ) = 0;
Packit 577717
	memset( PFMW_PEVT_PFPPC( evt ), 0, sizeof ( PFMW_PEVT_PFPPC( evt ) ) );
Packit 577717
	memset( &evt->inp.pfp_unavail_pmcs, 0, sizeof ( pfmlib_regmask_t ) );
Packit 577717
Packit 577717
	SUBDBG( " original count is %d\n", org_cnt );
Packit 577717
Packit 577717
/* add new native events to the evt structure */
Packit 577717
	for ( i = 0; i < ( unsigned int ) count; i++ ) {
Packit 577717
		memset( &gete, 0, sizeof ( gete ) );
Packit 577717
		EventCode = native[i].ni_event;
Packit 577717
		_papi_pfm_ntv_code_to_name( EventCode, name, 128 );
Packit 577717
		if ( _pfm_decode_native_event( EventCode, &event, &umask ) != PAPI_OK )
Packit 577717
			return ( PAPI_ENOEVNT );
Packit 577717
Packit 577717
		SUBDBG( " evtcode=%#x evtindex=%d name: %s\n", EventCode, event,
Packit 577717
				name );
Packit 577717
Packit 577717
		PFMW_PEVT_EVENT( evt, i ) = event;
Packit 577717
		evt->inp.pfp_events[i].num_masks = 0;
Packit 577717
		gete.event = event;
Packit 577717
		gete.num_masks = prepare_umask( umask, gete.unit_masks );
Packit 577717
		if ( gete.num_masks ) {
Packit 577717
			evt->inp.pfp_events[i].num_masks = gete.num_masks;
Packit 577717
			for ( j = 0; j < gete.num_masks; j++ )
Packit 577717
				evt->inp.pfp_events[i].unit_masks[j] = gete.unit_masks[j];
Packit 577717
		}
Packit 577717
	}
Packit 577717
	PFMW_PEVT_EVTCOUNT( evt ) = count;
Packit 577717
	/* Recalcuate the pfmlib_param_t structure, may also signal conflict */
Packit 577717
	if ( pfmw_dispatch_events( evt ) ) {
Packit 577717
		SUBDBG( "pfmw_dispatch_events fail\n" );
Packit 577717
		/* recover the old data */
Packit 577717
		PFMW_PEVT_EVTCOUNT( evt ) = org_cnt;
Packit 577717
		/*for (i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++)
Packit 577717
		   PFMW_PEVT_EVENT(evt,i) = events[i];
Packit 577717
		 */
Packit 577717
		memcpy( evt, &copy_evt, sizeof ( pfmw_param_t ) );
Packit 577717
		return ( PAPI_ECNFLCT );
Packit 577717
	}
Packit 577717
	SUBDBG( "event_count=%d\n", PFMW_PEVT_EVTCOUNT( evt ) );
Packit 577717
Packit 577717
	for ( i = 0; i < PFMW_PEVT_EVTCOUNT( evt ); i++ ) {
Packit 577717
		native[i].ni_position = PFMW_PEVT_PFPPC_REG_NUM( evt, i )
Packit 577717
			- PMU_FIRST_COUNTER;
Packit 577717
		SUBDBG( "event_code is %d, reg_num is %d\n",
Packit 577717
				native[i].ni_event & PAPI_NATIVE_AND_MASK,
Packit 577717
				native[i].ni_position );
Packit 577717
	}
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_ita_update_control_state( hwd_control_state_t * this_state,
Packit 577717
								NativeInfo_t * native, int count,
Packit 577717
								hwd_context_t * zero )
Packit 577717
{
Packit 577717
	( void ) zero;			 /*unused */
Packit 577717
	int index, org_cnt;
Packit 577717
	unsigned int i;
Packit 577717
	pfmw_param_t *evt = &this_state->evt;
Packit 577717
	pfmw_param_t copy_evt;
Packit 577717
Packit 577717
	if ( count == 0 ) {
Packit 577717
		for ( i = 0; i < ( unsigned int ) _ia64_vector.cmp_info.num_cntrs; i++ )
Packit 577717
			PFMW_PEVT_EVENT( evt, i ) = 0;
Packit 577717
		PFMW_PEVT_EVTCOUNT( evt ) = 0;
Packit 577717
		memset( PFMW_PEVT_PFPPC( evt ), 0, sizeof ( PFMW_PEVT_PFPPC( evt ) ) );
Packit 577717
		memset( &evt->inp.pfp_unavail_pmcs, 0, sizeof ( pfmlib_regmask_t ) );
Packit 577717
		return ( PAPI_OK );
Packit 577717
	}
Packit 577717
Packit 577717
/* save the old data */
Packit 577717
	org_cnt = PFMW_PEVT_EVTCOUNT( evt );
Packit 577717
Packit 577717
	memcpy( &copy_evt, evt, sizeof ( pfmw_param_t ) );
Packit 577717
	for ( i = 0; i < ( unsigned int ) _ia64_vector.cmp_info.num_cntrs; i++ )
Packit 577717
		PFMW_PEVT_EVENT( evt, i ) = 0;
Packit 577717
	PFMW_PEVT_EVTCOUNT( evt ) = 0;
Packit 577717
	memset( PFMW_PEVT_PFPPC( evt ), 0, sizeof ( PFMW_PEVT_PFPPC( evt ) ) );
Packit 577717
	memset( &evt->inp.pfp_unavail_pmcs, 0, sizeof ( pfmlib_regmask_t ) );
Packit 577717
Packit 577717
	SUBDBG( " original count is %d\n", org_cnt );
Packit 577717
Packit 577717
/* add new native events to the evt structure */
Packit 577717
	for ( i = 0; i < ( unsigned int ) count; i++ ) {
Packit 577717
		index = native[i].ni_event & PAPI_NATIVE_AND_MASK;
Packit 577717
		PFMW_PEVT_EVENT( evt, i ) = index;
Packit 577717
	}
Packit 577717
	PFMW_PEVT_EVTCOUNT( evt ) = count;
Packit 577717
	/* Recalcuate the pfmlib_param_t structure, may also signal conflict */
Packit 577717
	if ( pfmw_dispatch_events( evt ) ) {
Packit 577717
		SUBDBG( "pfmw_dispatch_events fail\n" );
Packit 577717
		/* recover the old data */
Packit 577717
		PFMW_PEVT_EVTCOUNT( evt ) = org_cnt;
Packit 577717
		/*for (i = 0; i < _ia64_vector.cmp_info.num_cntrs; i++)
Packit 577717
		   PFMW_PEVT_EVENT(evt,i) = events[i];
Packit 577717
		 */
Packit 577717
		memcpy( evt, &copy_evt, sizeof ( pfmw_param_t ) );
Packit 577717
		return ( PAPI_ECNFLCT );
Packit 577717
	}
Packit 577717
	SUBDBG( "event_count=%d\n", PFMW_PEVT_EVTCOUNT( evt ) );
Packit 577717
Packit 577717
	for ( i = 0; i < PFMW_PEVT_EVTCOUNT( evt ); i++ ) {
Packit 577717
		native[i].ni_position = PFMW_PEVT_PFPPC_REG_NUM( evt, i )
Packit 577717
			- PMU_FIRST_COUNTER;
Packit 577717
		SUBDBG( "event_code is %d, reg_num is %d\n",
Packit 577717
				native[i].ni_event & PAPI_NATIVE_AND_MASK,
Packit 577717
				native[i].ni_position );
Packit 577717
	}
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_ia64_update_control_state( hwd_control_state_t * this_state,
Packit 577717
							NativeInfo_t * native, int count,
Packit 577717
							hwd_context_t * zero )
Packit 577717
{
Packit 577717
	switch ( _perfmon2_pfm_pmu_type ) {
Packit 577717
	case PFMLIB_ITANIUM_PMU:
Packit 577717
		return ( _ia64_ita_update_control_state
Packit 577717
				 ( this_state, native, count, zero ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_ITANIUM2_PMU:
Packit 577717
		return ( _ia64_ita_update_control_state
Packit 577717
				 ( this_state, native, count, zero ) );
Packit 577717
		break;
Packit 577717
	case PFMLIB_MONTECITO_PMU:
Packit 577717
		return ( _ia64_mont_update_control_state
Packit 577717
				 ( this_state, native, count, zero ) );
Packit 577717
		break;
Packit 577717
	default:
Packit 577717
		PAPIERROR( "PMU type %d is not supported by this component",
Packit 577717
				   _perfmon2_pfm_pmu_type );
Packit 577717
		return ( PAPI_EBUG );
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
papi_vector_t _ia64_vector = {
Packit 577717
   .cmp_info = {
Packit 577717
      .name = "perfmon-ia64.c",
Packit 577717
      .version = "5.0",
Packit 577717
Packit 577717
      /* default component information (unspecified values initialized to 0) */
Packit 577717
      .default_domain = PAPI_DOM_USER,
Packit 577717
      .available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL,
Packit 577717
      .default_granularity = PAPI_GRN_THR,
Packit 577717
      .available_granularities = PAPI_GRN_THR,
Packit 577717
      .hardware_intr_sig = PAPI_INT_SIGNAL,
Packit 577717
      .hardware_intr = 1,
Packit 577717
      /* component specific cmp_info initializations */
Packit 577717
      .fast_real_timer = 1,
Packit 577717
      .fast_virtual_timer = 0,
Packit 577717
      .attach = 0,
Packit 577717
      .attach_must_ptrace = 0,
Packit 577717
      .kernel_profile = 1,
Packit 577717
      .cntr_umasks = 1;	
Packit 577717
  },
Packit 577717
Packit 577717
	/* sizes of framework-opaque component-private structures */
Packit 577717
	.size = {
Packit 577717
			 .context = sizeof ( ia64_context_t ),
Packit 577717
			 .control_state = sizeof ( ia64_control_state_t ),
Packit 577717
			 .reg_value = sizeof ( ia64_register_t ),
Packit 577717
			 .reg_alloc = sizeof ( ia64_reg_alloc_t ),
Packit 577717
			 }
Packit 577717
	,
Packit 577717
Packit 577717
	/* function pointers in this component */
Packit 577717
	.init_control_state = _ia64_init_control_state,
Packit 577717
	.start = _ia64_start,
Packit 577717
	.stop = _ia64_stop,
Packit 577717
	.read = _ia64_read,
Packit 577717
	.shutdown_thread = _ia64_shutdown,
Packit 577717
	.ctl = _ia64_ctl,
Packit 577717
	.update_control_state = _ia64_update_control_state,
Packit 577717
	.set_domain = _ia64_set_domain,
Packit 577717
	.reset = _ia64_reset,
Packit 577717
	.set_overflow = _ia64_set_overflow,
Packit 577717
	.set_profile = _ia64_set_profile,
Packit 577717
	.stop_profiling = _ia64_stop_profiling,
Packit 577717
	.init_component = _ia64_init_component,
Packit 577717
	.dispatch_timer = _ia64_dispatch_timer,
Packit 577717
	.init_thread = _ia64_init,
Packit 577717
Packit 577717
	.ntv_enum_events = _ia64_ntv_enum_events,
Packit 577717
	.ntv_code_to_name = _ia64_ntv_code_to_name,
Packit 577717
	.ntv_code_to_descr = _ia64_ntv_code_to_descr,
Packit 577717
Packit 577717
};