Blame src/solaris-niagara2.c

Packit Service a1973e
/*******************************************************************************
Packit Service a1973e
 * >>>>>> "Development of a PAPI Backend for the Sun Niagara 2 Processor" <<<<<<
Packit Service a1973e
 * -----------------------------------------------------------------------------
Packit Service a1973e
 *
Packit Service a1973e
 * Fabian Gorsler <fabian.gorsler@smail.inf.h-bonn-rhein-sieg.de>
Packit Service a1973e
 *
Packit Service a1973e
 *       Hochschule Bonn-Rhein-Sieg, Sankt Augustin, Germany
Packit Service a1973e
 *       University of Applied Sciences
Packit Service a1973e
 *
Packit Service a1973e
 * -----------------------------------------------------------------------------
Packit Service a1973e
 *
Packit Service a1973e
 * File:   solaris-niagara2.c
Packit Service a1973e
 * Author: fg215045
Packit Service a1973e
 * 
Packit Service a1973e
 * Description: This source file is the implementation of a PAPI 
Packit Service a1973e
 * component for the Sun Niagara 2 processor (aka UltraSPARC T2) 
Packit Service a1973e
 * running on Solaris 10 with libcpc 2. 
Packit Service a1973e
 * The machine for implementing this component was courtesy of RWTH 
Packit Service a1973e
 * Aachen University, Germany. Thanks to the HPC-Team at RWTH! 
Packit Service a1973e
 *
Packit Service a1973e
 * Conventions used:
Packit Service a1973e
 *  - __cpc_*: Functions, variables, etc. related to libcpc handling
Packit Service a1973e
 *  - __sol_*: Functions, variables, etc. related to Solaris handling
Packit Service a1973e
 *  - __int_*: Functions, variables, etc. related to extensions of libcpc
Packit Service a1973e
 *  - _niagara*: Functions, variables, etc. needed by PAPI hardware dependent
Packit Service a1973e
 *                 layer, i.e. the component itself
Packit Service a1973e
 *
Packit Service a1973e
 * 
Packit Service a1973e
 *      ***** Feel free to convert this header to the PAPI default *****
Packit Service a1973e
 *
Packit Service a1973e
 * -----------------------------------------------------------------------------
Packit Service a1973e
 * Created on April 23, 2009, 7:31 PM
Packit Service a1973e
 ******************************************************************************/
Packit Service a1973e
Packit Service a1973e
#include "papi.h"
Packit Service a1973e
#include "papi_internal.h"
Packit Service a1973e
#include "papi_vector.h"
Packit Service a1973e
#include "solaris-niagara2.h"
Packit Service a1973e
#include "papi_memory.h"
Packit Service a1973e
Packit Service a1973e
#include <libcpc.h>
Packit Service a1973e
#include <procfs.h>
Packit Service a1973e
#include <sys/types.h>
Packit Service a1973e
#include <sys/stat.h>
Packit Service a1973e
#include <fcntl.h>
Packit Service a1973e
#include <unistd.h>
Packit Service a1973e
#include <stdio.h>
Packit Service a1973e
#include <stdlib.h>
Packit Service a1973e
#include <strings.h>
Packit Service a1973e
#include <sys/lwp.h>
Packit Service a1973e
#include <limits.h>
Packit Service a1973e
#include <sys/processor.h>
Packit Service a1973e
#include <sys/types.h>
Packit Service a1973e
#include <sys/time.h>
Packit Service a1973e
#include <stdarg.h>
Packit Service a1973e
#include <libgen.h>
Packit Service a1973e
#include <ucontext.h>
Packit Service a1973e
#include <sys/regset.h>
Packit Service a1973e
#include <sys/utsname.h>
Packit Service a1973e
Packit Service a1973e
#include "solaris-common.h"
Packit Service a1973e
#include "solaris-memory.h"
Packit Service a1973e
Packit Service a1973e
#define hwd_control_state_t _niagara2_control_state_t
Packit Service a1973e
#define hwd_context_t       _niagara2_context_t
Packit Service a1973e
#define hwd_register_t      _niagara2_register_t
Packit Service a1973e
Packit Service a1973e
extern caddr_t _start, _end, _etext, _edata;
Packit Service a1973e
extern papi_vector_t _niagara2_vector;
Packit Service a1973e
Packit Service a1973e
/* Synthetic events */
Packit Service a1973e
int __int_setup_synthetic_event( int, hwd_control_state_t *, void * );
Packit Service a1973e
uint64_t __int_get_synthetic_event( int, hwd_control_state_t *, void * );
Packit Service a1973e
void __int_walk_synthetic_events_action_count( void );
Packit Service a1973e
void __int_walk_synthetic_events_action_store( void );
Packit Service a1973e
Packit Service a1973e
/* Simple error handlers for convenience */
Packit Service a1973e
#define __CHECK_ERR_DFLT(retval) \
Packit Service a1973e
    if(retval != 0){ SUBDBG("RETVAL: %d\n", retval); return PAPI_ECMP;}
Packit Service a1973e
Packit Service a1973e
#define __CHECK_ERR_NULL(retval) \
Packit Service a1973e
    if(retval == NULL){ SUBDBG("RETVAL: NULL\n"); return PAPI_ECMP;}
Packit Service a1973e
Packit Service a1973e
#define __CHECK_ERR_PAPI(retval) \
Packit Service a1973e
    if(retval != PAPI_OK){ SUBDBG("RETVAL: %d\n", retval); return PAPI_ECMP;}
Packit Service a1973e
Packit Service a1973e
#define __CHECK_ERR_INVA(retval) \
Packit Service a1973e
    if(retval != 0){ SUBDBG("RETVAL: %d\n", retval); return PAPI_EINVAL;}
Packit Service a1973e
Packit Service a1973e
#define __CHECK_ERR_NEGV(retval) \
Packit Service a1973e
    if(retval < 0){ SUBDBG("RETVAL: %d\n", retval); return PAPI_ECMP;}
Packit Service a1973e
Packit Service a1973e
// PAPI defined variables
Packit Service a1973e
extern papi_mdi_t _papi_hwi_system_info;
Packit Service a1973e
Packit Service a1973e
// The instance of libcpc
Packit Service a1973e
static cpc_t *cpc = NULL;
Packit Service a1973e
Packit Service a1973e
typedef struct __t2_store
Packit Service a1973e
{
Packit Service a1973e
	// Number of counters for a processing unit
Packit Service a1973e
	int npic;
Packit Service a1973e
	int *pic_ntv_count;
Packit Service a1973e
	int syn_evt_count;
Packit Service a1973e
} __t2_store_t;
Packit Service a1973e
Packit Service a1973e
static __t2_store_t __t2_store;
Packit Service a1973e
static char **__t2_ntv_events;
Packit Service a1973e
Packit Service a1973e
// Variables copied from the old component
Packit Service a1973e
static int pid;
Packit Service a1973e
Packit Service a1973e
// Data types for utility functions
Packit Service a1973e
Packit Service a1973e
typedef struct __sol_processor_information
Packit Service a1973e
{
Packit Service a1973e
	int total;
Packit Service a1973e
	int clock;
Packit Service a1973e
} __sol_processor_information_t;
Packit Service a1973e
Packit Service a1973e
typedef struct __t2_pst_table
Packit Service a1973e
{
Packit Service a1973e
	int papi_pst;
Packit Service a1973e
	char *ntv_event[MAX_COUNTERS];
Packit Service a1973e
	int ntv_ctrs;
Packit Service a1973e
	int ntv_opcode;
Packit Service a1973e
} __t2_pst_table_t;
Packit Service a1973e
Packit Service a1973e
#define SYNTHETIC_EVENTS_SUPPORTED  1
Packit Service a1973e
Packit Service a1973e
/* This table structure holds all preset events */
Packit Service a1973e
static __t2_pst_table_t __t2_table[] = {
Packit Service a1973e
	/* Presets defined by generic_events(3CPC) */
Packit Service a1973e
	{PAPI_L1_DCM,
Packit Service a1973e
	 {"DC_miss", NULL}, 1, NOT_DERIVED},
Packit Service a1973e
	{PAPI_L1_ICM,
Packit Service a1973e
	 {"IC_miss", NULL}, 1, NOT_DERIVED},
Packit Service a1973e
	{PAPI_L2_ICM,
Packit Service a1973e
	 {"L2_imiss", NULL}, 1, NOT_DERIVED},
Packit Service a1973e
	{PAPI_TLB_DM,
Packit Service a1973e
	 {"DTLB_miss", NULL}, 1, NOT_DERIVED},
Packit Service a1973e
	{PAPI_TLB_IM,
Packit Service a1973e
	 {"ITLB_miss", NULL}, 1, NOT_DERIVED},
Packit Service a1973e
	{PAPI_TLB_TL,
Packit Service a1973e
	 {"TLB_miss", NULL}, 1, NOT_DERIVED},
Packit Service a1973e
	{PAPI_L2_LDM,
Packit Service a1973e
	 {"L2_dmiss_ld", NULL}, 1, NOT_DERIVED},
Packit Service a1973e
	{PAPI_BR_TKN,
Packit Service a1973e
	 {"Br_taken", NULL}, 1, NOT_DERIVED},
Packit Service a1973e
	{PAPI_TOT_INS,
Packit Service a1973e
	 {"Instr_cnt", NULL}, 1, NOT_DERIVED},
Packit Service a1973e
	{PAPI_LD_INS,
Packit Service a1973e
	 {"Instr_ld", NULL}, 1, NOT_DERIVED},
Packit Service a1973e
	{PAPI_SR_INS,
Packit Service a1973e
	 {"Instr_st", NULL}, 1, NOT_DERIVED},
Packit Service a1973e
	{PAPI_BR_INS,
Packit Service a1973e
	 {"Br_completed", NULL}, 1, NOT_DERIVED},
Packit Service a1973e
	/* Presets additionally found, should be checked twice */
Packit Service a1973e
	{PAPI_BR_MSP,
Packit Service a1973e
	 {"Br_taken", NULL}, 1, NOT_DERIVED},
Packit Service a1973e
	{PAPI_FP_INS,
Packit Service a1973e
	 {"Instr_FGU_arithmetic", NULL}, 1, NOT_DERIVED},
Packit Service a1973e
	{PAPI_RES_STL,
Packit Service a1973e
	 {"Idle_strands", NULL}, 1, NOT_DERIVED},
Packit Service a1973e
	{PAPI_SYC_INS,
Packit Service a1973e
	 {"Atomics", NULL}, 1, NOT_DERIVED},
Packit Service a1973e
	{PAPI_L2_ICR,
Packit Service a1973e
	 {"CPU_ifetch_to_PCX", NULL}, 1, NOT_DERIVED},
Packit Service a1973e
	{PAPI_L1_TCR,
Packit Service a1973e
	 {"CPU_ld_to_PCX", NULL}, 1, NOT_DERIVED},
Packit Service a1973e
	{PAPI_L2_TCW,
Packit Service a1973e
	 {"CPU_st_to_PCX", NULL}, 1, NOT_DERIVED},
Packit Service a1973e
	/* Derived presets found, should be checked twice */
Packit Service a1973e
	{PAPI_L1_TCM,
Packit Service a1973e
	 {"IC_miss", "DC_miss"}, 2, DERIVED_ADD},
Packit Service a1973e
	{PAPI_BR_CN,
Packit Service a1973e
	 {"Br_completed", "Br_taken"}, 2, DERIVED_ADD},
Packit Service a1973e
	{PAPI_BR_PRC,
Packit Service a1973e
	 {"Br_completed", "Br_taken"}, 2, DERIVED_SUB},
Packit Service a1973e
	{PAPI_LST_INS,
Packit Service a1973e
	 {"Instr_st", "Instr_ld"}, 2, DERIVED_ADD},
Packit Service a1973e
#ifdef SYNTHETIC_EVENTS_SUPPORTED
Packit Service a1973e
	/* This preset does exist in order to support multiplexing */
Packit Service a1973e
	{PAPI_TOT_CYC,
Packit Service a1973e
	 {"_syn_cycles_elapsed", "DC_miss"}, 1, NOT_DERIVED},
Packit Service a1973e
#endif
Packit Service a1973e
	{0,
Packit Service a1973e
	 {NULL, NULL}, 0, 0},
Packit Service a1973e
};
Packit Service a1973e
Packit Service a1973e
hwi_search_t *preset_table;
Packit Service a1973e
Packit Service a1973e
#ifdef SYNTHETIC_EVENTS_SUPPORTED
Packit Service a1973e
enum
Packit Service a1973e
{
Packit Service a1973e
	SYNTHETIC_CYCLES_ELAPSED = 1,
Packit Service a1973e
	SYNTHETIC_RETURN_ONE,
Packit Service a1973e
	SYNTHETIC_RETURN_TWO,
Packit Service a1973e
} __int_synthetic_enum;
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
#ifdef SYNTHETIC_EVENTS_SUPPORTED
Packit Service a1973e
typedef struct __int_synthetic_table
Packit Service a1973e
{
Packit Service a1973e
	int code;
Packit Service a1973e
	char *name;
Packit Service a1973e
} __int_syn_table_t;
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
#ifdef SYNTHETIC_EVENTS_SUPPORTED
Packit Service a1973e
static __int_syn_table_t __int_syn_table[] = {
Packit Service a1973e
	{SYNTHETIC_CYCLES_ELAPSED, "_syn_cycles_elapsed"},
Packit Service a1973e
	{SYNTHETIC_RETURN_ONE, "_syn_return_one"},
Packit Service a1973e
	{SYNTHETIC_RETURN_TWO, "_syn_return_two"},
Packit Service a1973e
	{-1, NULL},
Packit Service a1973e
};
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
////////////////////////////////////////////////////////////////////////////////
Packit Service a1973e
/// PAPI HWD LAYER RELATED FUNCTIONS ///////////////////////////////////////////
Packit Service a1973e
////////////////////////////////////////////////////////////////////////////////
Packit Service a1973e
Packit Service a1973e
/* DESCRIPTION:
Packit Service a1973e
 * -----------------------------------------------------------------------------
Packit Service a1973e
 * Functions in this section are related to the PAPI hardware dependend layer,
Packit Service a1973e
 * also known as "HWD". In this case the HWD layer is the interface from PAPI
Packit Service a1973e
 * to libcpc 2/Solaris 10.
Packit Service a1973e
 ******************************************************************************/
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_niagara2_set_domain( hwd_control_state_t * ctrl, int domain )
Packit Service a1973e
{
Packit Service a1973e
	int i;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* Clean and set the new flag for each counter */
Packit Service a1973e
Packit Service a1973e
	for ( i = 0; i < MAX_COUNTERS; i++ ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: Setting flags for PIC#%d, old value: %p\n",
Packit Service a1973e
				__func__, i, ctrl->flags[i] );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		ctrl->flags[i] &= ~( CPC_COUNTING_DOMAINS );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: +++                      cleaned value: %p\n",
Packit Service a1973e
				__func__, ctrl->flags[i] );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		ctrl->flags[i] |= __cpc_domain_translator( domain );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: +++                      new value: %p\n",
Packit Service a1973e
				__func__, ctrl->flags[i] );
Packit Service a1973e
#endif
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	/* Recreate the set */
Packit Service a1973e
	__CHECK_ERR_PAPI( __cpc_recreate_set( ctrl ) );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_niagara2_ctl( hwd_context_t * ctx, int code, _papi_int_option_t * option )
Packit Service a1973e
{
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
	SUBDBG( " -> %s: Option #%d requested\n", __func__, code );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* Only these options are handled which are handled in PAPI_set_opt, as many
Packit Service a1973e
	   of the left out options are not settable, like PAPI_MAX_CPUS. */
Packit Service a1973e
Packit Service a1973e
	switch ( code ) {
Packit Service a1973e
	case PAPI_DEFDOM:
Packit Service a1973e
		/* From papi.h: Domain for all new eventsets. Takes non-NULL option
Packit Service a1973e
		   pointer. */
Packit Service a1973e
Packit Service a1973e
		_niagara2_vector.cmp_info.default_domain = option->domain.domain;
Packit Service a1973e
Packit Service a1973e
		return PAPI_OK;
Packit Service a1973e
	case PAPI_DOMAIN:
Packit Service a1973e
		/* From papi.h: Domain for an eventset */
Packit Service a1973e
Packit Service a1973e
		return _niagara2_set_domain( ctx, option->domain.domain );
Packit Service a1973e
	case PAPI_DEFGRN:
Packit Service a1973e
		/* From papi.h: Granularity for all new eventsets */
Packit Service a1973e
Packit Service a1973e
		_niagara2_vector.cmp_info.default_granularity =
Packit Service a1973e
			option->granularity.granularity;
Packit Service a1973e
Packit Service a1973e
		return PAPI_OK;
Packit Service a1973e
	case PAPI_GRANUL:
Packit Service a1973e
		/* From papi.h: Granularity for an eventset */
Packit Service a1973e
Packit Service a1973e
		/* Only supported granularity is PAPI_GRN_THREAD */
Packit Service a1973e
Packit Service a1973e
		return PAPI_OK;
Packit Service a1973e
	case PAPI_DEF_MPX_NS:
Packit Service a1973e
		/* From papi.h: Multiplexing/overflowing interval in ns, same as
Packit Service a1973e
		   PAPI_DEF_ITIMER_NS */
Packit Service a1973e
Packit Service a1973e
		/* From the old component */
Packit Service a1973e
		option->itimer.ns = __sol_get_itimer_ns( option->itimer.ns );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: PAPI_DEF_MPX_NS, option->itimer.ns=%d\n",
Packit Service a1973e
				__func__, option->itimer.ns );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		return PAPI_OK;
Packit Service a1973e
	case PAPI_DEF_ITIMER:	 // IN THE OLD COMPONENT // USED
Packit Service a1973e
		/* From papi.h: Option to set the type of itimer used in both software
Packit Service a1973e
		   multiplexing, overflowing and profiling */
Packit Service a1973e
Packit Service a1973e
		/* These tests are taken from the old component. For Solaris 10 the
Packit Service a1973e
		   same rules apply as documented in getitimer(2). */
Packit Service a1973e
Packit Service a1973e
		if ( ( option->itimer.itimer_num == ITIMER_REAL ) &&
Packit Service a1973e
			 ( option->itimer.itimer_sig != SIGALRM ) ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
			SUBDBG( " -> %s: PAPI_DEF_ITIMER, ITIMER_REAL needs SIGALRM\n",
Packit Service a1973e
					__func__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
			return PAPI_EINVAL;
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
		if ( ( option->itimer.itimer_num == ITIMER_VIRTUAL ) &&
Packit Service a1973e
			 ( option->itimer.itimer_sig != SIGVTALRM ) ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
			SUBDBG( " -> %s: PAPI_DEF_ITIMER, ITIMER_VIRTUAL needs SIGVTALRM\n",
Packit Service a1973e
					__func__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
			return PAPI_EINVAL;
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
		if ( ( option->itimer.itimer_num == ITIMER_PROF ) &&
Packit Service a1973e
			 ( option->itimer.itimer_sig != SIGPROF ) ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
			SUBDBG( " -> %s: PAPI_DEF_ITIMER, ITIMER_PROF needs SIGPROF\n",
Packit Service a1973e
					__func__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
			return PAPI_EINVAL;
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
		/* As in the old component defined, timer values below 0 are NOT
Packit Service a1973e
		   filtered out, but timer values greater than 0 are rounded, either to
Packit Service a1973e
		   a value which is at least itimer_res_ns or padded to a multiple of
Packit Service a1973e
		   itimer_res_ns. */
Packit Service a1973e
Packit Service a1973e
		if ( option->itimer.ns > 0 ) {
Packit Service a1973e
			option->itimer.ns = __sol_get_itimer_ns( option->itimer.ns );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
			SUBDBG( " -> %s: PAPI_DEF_ITIMER, option->itimer.ns=%d\n",
Packit Service a1973e
					__func__, option->itimer.ns );
Packit Service a1973e
#endif
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
		return PAPI_OK;
Packit Service a1973e
	case PAPI_DEF_ITIMER_NS:	// IN THE OLD COMPONENT // USED
Packit Service a1973e
		/* From papi.h: Multiplexing/overflowing interval in ns, same as
Packit Service a1973e
		   PAPI_DEF_MPX_NS */
Packit Service a1973e
Packit Service a1973e
		/* From the old component */
Packit Service a1973e
		option->itimer.ns = __sol_get_itimer_ns( option->itimer.ns );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: PAPI_DEF_ITIMER_NS, option->itimer.ns=%d\n",
Packit Service a1973e
				__func__, option->itimer.ns );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		return PAPI_OK;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( " -> %s: Option not found\n", __func__ );
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* This place should never be reached */
Packit Service a1973e
	return PAPI_EINVAL;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
void
Packit Service a1973e
_niagara2_dispatch_timer( int signal, siginfo_t * si, void *info )
Packit Service a1973e
{
Packit Service a1973e
	EventSetInfo_t *ESI = NULL;
Packit Service a1973e
	ThreadInfo_t *thread = NULL;
Packit Service a1973e
	int overflow_vector = 0;
Packit Service a1973e
	hwd_control_state_t *ctrl = NULL;
Packit Service a1973e
	long_long results[MAX_COUNTERS];
Packit Service a1973e
	int i;
Packit Service a1973e
	// Hint from perf_events.c
Packit Service a1973e
	int cidx = _niagara2_vector.cmp_info.CmpIdx;
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
	SUBDBG( " -> %s: Overflow handler called by signal #%d\n", __func__,
Packit Service a1973e
			signal );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* From the old component */
Packit Service a1973e
	thread = _papi_hwi_lookup_thread( 0 );
Packit Service a1973e
	ESI = ( EventSetInfo_t * ) thread->running_eventset[cidx];
Packit Service a1973e
Packit Service a1973e
	/* From the old component, modified */
Packit Service a1973e
	// 
Packit Service a1973e
	if ( ESI == NULL || ESI->master != thread || ESI->ctl_state == NULL ||
Packit Service a1973e
		 ( ( ESI->state & PAPI_OVERFLOWING ) == 0 ) ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: Problems with ESI, not necessarily serious\n",
Packit Service a1973e
				__func__ );
Packit Service a1973e
Packit Service a1973e
		if ( ESI == NULL ) {
Packit Service a1973e
			SUBDBG( " -> %s: +++ ESI is NULL\n", __func__ );
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
		if ( ESI->master != thread ) {
Packit Service a1973e
			SUBDBG( " -> %s: +++ Thread mismatch, ESI->master=%#x thread=%#x\n",
Packit Service a1973e
					__func__, ESI->master, thread );
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
		if ( ESI->ctl_state == NULL ) {
Packit Service a1973e
			SUBDBG( " -> %s: +++ Counter state invalid\n", __func__ );
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
		if ( ( ( ESI->state & PAPI_OVERFLOWING ) == 0 ) ) {
Packit Service a1973e
			SUBDBG
Packit Service a1973e
				( " -> %s: +++ Overflow flag missing, ESI->overflow.flags=%#x\n",
Packit Service a1973e
				  __func__, ESI->overflow.flags );
Packit Service a1973e
		}
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		return;
Packit Service a1973e
	}
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	printf( " -> %s: Preconditions valid, trying to read counters\n",
Packit Service a1973e
			__func__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	ctrl = ESI->ctl_state;
Packit Service a1973e
Packit Service a1973e
	if ( _niagara2_read
Packit Service a1973e
		 ( ctrl, ctrl, ( long_long ** ) & results, NOT_A_PAPI_HWD_READ )
Packit Service a1973e
		 != PAPI_OK ) {
Packit Service a1973e
		/* Failure */
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		printf( "%s: Failed to read counters\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		return;
Packit Service a1973e
	} else {
Packit Service a1973e
		/* Success */
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: Counters read\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		/* Iterate over all available counters in order to detect which counter
Packit Service a1973e
		   overflowed (counter value should be 0 if an hw overflow happened),
Packit Service a1973e
		   store the position in the overflow_vector, calculte the offset and
Packit Service a1973e
		   shift (value range signed long long vs. unsigned long long). */
Packit Service a1973e
		for ( i = 0; i < ctrl->count; i++ ) {
Packit Service a1973e
			if ( results[i] >= 0 ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
				SUBDBG( " -> %s: Overflow detected at PIC #%d\n", __func__, i );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
				/* Set the bit in the overflow_vector */
Packit Service a1973e
				overflow_vector = overflow_vector | ( 1 << i );
Packit Service a1973e
Packit Service a1973e
				/* hoose which method to use depending on the overflow signal. */
Packit Service a1973e
				if ( signal == SIGEMT ) {
Packit Service a1973e
					/* Store the counter value, but only if we have a real *
Packit Service a1973e
					   hardware overflow counting with libcpc/SIGEMT. */
Packit Service a1973e
					ctrl->preset[i] = UINT64_MAX - ctrl->threshold[i];
Packit Service a1973e
					ctrl->hangover[i] += ctrl->threshold[i];
Packit Service a1973e
				} else {
Packit Service a1973e
					/* Push the value back, this time PAPI does the work. This is
Packit Service a1973e
					   software overflow handling. */
Packit Service a1973e
					cpc_request_preset( cpc, ctrl->idx[i], ctrl->result[i] );
Packit Service a1973e
				}
Packit Service a1973e
			} else {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
				SUBDBG( " -> %s: No overflow detected at PIC #%d, value=%ld\n",
Packit Service a1973e
						__func__, i, results[i] );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
				/* Save the results read from the counter as we can not store the
Packit Service a1973e
				   temporary value in hardware or libcpc. */
Packit Service a1973e
				if ( signal == SIGEMT ) {
Packit Service a1973e
					ctrl->preset[i] += results[i];
Packit Service a1973e
					ctrl->hangover[i] = results[i];
Packit Service a1973e
				}
Packit Service a1973e
			}
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: Restarting set to push values back\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		/* Push all values back to the counter as preset */
Packit Service a1973e
		cpc_set_restart( cpc, ctrl->set );
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( " -> %s: Passing overflow to PAPI with overflow_vector=%p\n",
Packit Service a1973e
			__func__, overflow_vector );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	{
Packit Service a1973e
		/* hw is used as pointer in the dispatching routine of PAPI and might be
Packit Service a1973e
		   changed. For safety it is not a pseudo pointer to NULL. */
Packit Service a1973e
		int hw;
Packit Service a1973e
Packit Service a1973e
		if ( signal == SIGEMT ) {
Packit Service a1973e
			/* This is a hardware overflow */
Packit Service a1973e
			hw = 1;
Packit Service a1973e
			_papi_hwi_dispatch_overflow_signal( ctrl, ( caddr_t )
Packit Service a1973e
												_niagara2_get_overflow_address
Packit Service a1973e
												( info ), &hw, overflow_vector,
Packit Service a1973e
												1, &thread, ESI->CmpIdx );
Packit Service a1973e
		} else {
Packit Service a1973e
			/* This is a software overflow */
Packit Service a1973e
			hw = 0;
Packit Service a1973e
			_papi_hwi_dispatch_overflow_signal( ctrl, ( caddr_t )
Packit Service a1973e
												_niagara2_get_overflow_address
Packit Service a1973e
												( info ), &hw, overflow_vector,
Packit Service a1973e
												1, &thread, ESI->CmpIdx );
Packit Service a1973e
		}
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
static inline void *
Packit Service a1973e
_niagara2_get_overflow_address( void *context )
Packit Service a1973e
{
Packit Service a1973e
	ucontext_t *ctx = ( ucontext_t * ) context;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING/LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return ( void * ) ctx->uc_mcontext.gregs[REG_PC];
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
/** Although the created set in this function will be destroyed by 
Packit Service a1973e
 * _papi_update_control_state later, at least the functionality of the
Packit Service a1973e
 * underlying CPU driver will be tested completly.
Packit Service a1973e
 */
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_niagara2_init_control_state( hwd_control_state_t * ctrl )
Packit Service a1973e
{
Packit Service a1973e
	int i;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	// cpc_seterrhndlr(cpc, myapp_errfn);
Packit Service a1973e
Packit Service a1973e
	/* Clear the buffer */
Packit Service a1973e
	if ( ctrl->counter_buffer != NULL ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: Cleaning buffer\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		cpc_buf_destroy( cpc, ctrl->counter_buffer );
Packit Service a1973e
		ctrl->counter_buffer = NULL;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	/* Clear the set */
Packit Service a1973e
	if ( ctrl->set != NULL ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: Cleaning set\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		cpc_set_destroy( cpc, ctrl->set );
Packit Service a1973e
		ctrl->set = NULL;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	/* Indicate this idx has no request associated, this counter is unused. */
Packit Service a1973e
	for ( i = 0; i < MAX_COUNTERS; i++ ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: Cleaning counter state #%d\n", __func__, i );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		/* Indicate missing setup values */
Packit Service a1973e
		ctrl->idx[i] = EVENT_NOT_SET;
Packit Service a1973e
		ctrl->code[i].event_code = EVENT_NOT_SET;
Packit Service a1973e
Packit Service a1973e
		/* No flags yet set, this is for overflow and binding */
Packit Service a1973e
		ctrl->flags[i] = 0;
Packit Service a1973e
Packit Service a1973e
		/* Preset value for counting results */
Packit Service a1973e
		ctrl->preset[i] = DEFAULT_CNTR_PRESET;
Packit Service a1973e
Packit Service a1973e
		/* Needed for overflow handling, will be set later */
Packit Service a1973e
		ctrl->threshold[i] = 0;
Packit Service a1973e
		ctrl->hangover[i] = 0;
Packit Service a1973e
Packit Service a1973e
#ifdef SYNTHETIC_EVENTS_SUPPORTED
Packit Service a1973e
		ctrl->syn_hangover[i] = 0;
Packit Service a1973e
#endif
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	/* No counters active in this set */
Packit Service a1973e
	ctrl->count = 0;
Packit Service a1973e
Packit Service a1973e
#ifdef SYNTHETIC_EVENTS_SUPPORTED
Packit Service a1973e
	ctrl->syn_count = 0;
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_niagara2_init_component( int cidx )
Packit Service a1973e
{
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* Create an instance of libcpc */
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( " -> %s: Trying to initalize libcpc\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
	cpc = cpc_open( CPC_VER_CURRENT );
Packit Service a1973e
	__CHECK_ERR_NULL( cpc );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( " -> %s: Registering libcpc error handler\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
	cpc_seterrhndlr( cpc, __cpc_error_handler );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( " -> %s: Detecting supported PICs", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
	__t2_store.npic = cpc_npic( cpc );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( " -> %s: Storing component index, cidx=%d\n", __func__, cidx );
Packit Service a1973e
#endif
Packit Service a1973e
	_niagara2_vector.cmp_info.CmpIdx = cidx;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( " -> %s: Gathering system information for PAPI\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
	/* Store system info in central data structure */
Packit Service a1973e
	__CHECK_ERR_PAPI( _niagara2_get_system_info( &_papi_hwi_system_info ) );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( " -> %s: Initializing locks\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
	/* Set up the lock after initialization */
Packit Service a1973e
	_niagara2_lock_init(  );
Packit Service a1973e
Packit Service a1973e
	// Copied from the old component, _papi_init_component()
Packit Service a1973e
	SUBDBG( "Found %d %s %s CPUs at %d Mhz.\n",
Packit Service a1973e
			_papi_hwi_system_info.hw_info.totalcpus,
Packit Service a1973e
			_papi_hwi_system_info.hw_info.vendor_string,
Packit Service a1973e
			_papi_hwi_system_info.hw_info.model_string,
Packit Service a1973e
			_papi_hwi_system_info.hw_info.cpu_max_mhz );
Packit Service a1973e
Packit Service a1973e
	/* Build native event table */
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( " -> %s: Building native event table\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
	__CHECK_ERR_PAPI( __cpc_build_ntv_table(  ) );
Packit Service a1973e
Packit Service a1973e
	/* Build preset event table */
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( " -> %s: Building PAPI preset table\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
	__CHECK_ERR_PAPI( __cpc_build_pst_table(  ) );
Packit Service a1973e
Packit Service a1973e
	/* Register presets and finish event related setup */
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( " -> %s: Registering presets in PAPI\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
	__CHECK_ERR_PAPI( _papi_hwi_setup_all_presets( preset_table, NULL ) );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* Everything is ok */
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
static void
Packit Service a1973e
_niagara2_lock_init( void )
Packit Service a1973e
{
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* Copied from old component, lock_init() */
Packit Service a1973e
	memset( lock, 0x0, sizeof ( rwlock_t ) * PAPI_MAX_LOCK );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_niagara2_ntv_code_to_bits( unsigned int EventCode, hwd_register_t * bits )
Packit Service a1973e
{
Packit Service a1973e
	int event_code = EventCode & PAPI_NATIVE_AND_MASK;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	if ( event_code >= 0 &&
Packit Service a1973e
		 event_code <= _niagara2_vector.cmp_info.num_native_events ) {
Packit Service a1973e
		return PAPI_ENOEVNT;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	bits->event_code = event_code;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_niagara2_ntv_code_to_descr( unsigned int EventCode, char *ntv_descr, int len )
Packit Service a1973e
{
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING/LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* libcpc offers no descriptions, just a link to the reference manual */
Packit Service a1973e
	return _niagara2_ntv_code_to_name( EventCode, ntv_descr, len );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_niagara2_ntv_code_to_name( unsigned int EventCode, char *ntv_name, int len )
Packit Service a1973e
{
Packit Service a1973e
	int event_code = EventCode & PAPI_NATIVE_AND_MASK;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	if ( event_code >= 0 &&
Packit Service a1973e
		 event_code <= _niagara2_vector.cmp_info.num_native_events ) {
Packit Service a1973e
		strlcpy( ntv_name, __t2_ntv_events[event_code], len );
Packit Service a1973e
Packit Service a1973e
		if ( strlen( __t2_ntv_events[event_code] ) > len - 1 ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
			SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
					__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
			/* It's not a real error, but at least a hint */
Packit Service a1973e
			return PAPI_EBUF;
Packit Service a1973e
		}
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
				__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		return PAPI_OK;
Packit Service a1973e
	}
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return PAPI_ENOEVNT;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_niagara2_ntv_enum_events( unsigned int *EventCode, int modifier )
Packit Service a1973e
{
Packit Service a1973e
	/* This code is very similar to the code from the old component. */
Packit Service a1973e
Packit Service a1973e
	int event_code = *EventCode & PAPI_NATIVE_AND_MASK;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	if ( modifier == PAPI_ENUM_FIRST ) {
Packit Service a1973e
		*EventCode = PAPI_NATIVE_MASK + 1;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
				__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		return PAPI_OK;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	/* The table needs to be shifted by one position (starting index 1), as PAPI
Packit Service a1973e
	   expects native event codes not to be 0 (papi_internal.c:744). */
Packit Service a1973e
Packit Service a1973e
	if ( event_code >= 1 &&
Packit Service a1973e
		 event_code <= _niagara2_vector.cmp_info.num_native_events - 1 ) {
Packit Service a1973e
		*EventCode = *EventCode + 1;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
				__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		return PAPI_OK;
Packit Service a1973e
	}
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	// If nothing found report an error
Packit Service a1973e
	return PAPI_ENOEVNT;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_niagara2_read( hwd_context_t * ctx, hwd_control_state_t * ctrl,
Packit Service a1973e
				long_long ** events, int flags )
Packit Service a1973e
{
Packit Service a1973e
	int i;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
	SUBDBG( " -> %s: called with flags=%p\n", __func__, flags );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* Take a new sample from the PIC to the buffer */
Packit Service a1973e
	__CHECK_ERR_DFLT( cpc_set_sample( cpc, ctrl->set, ctrl->counter_buffer ) );
Packit Service a1973e
Packit Service a1973e
	/* Copy the buffer values from all active counters */
Packit Service a1973e
	for ( i = 0; i < ctrl->count; i++ ) {
Packit Service a1973e
		/* Retrieve the counting results of libcpc */
Packit Service a1973e
		__CHECK_ERR_DFLT( cpc_buf_get( cpc, ctrl->counter_buffer, ctrl->idx[i],
Packit Service a1973e
									   &ctrl->result[i] ) );
Packit Service a1973e
Packit Service a1973e
		/* As libcpc uses uint64_t and PAPI uses int64_t, we need to normalize
Packit Service a1973e
		   the result back to a value that PAPI can handle, otherwise the result
Packit Service a1973e
		   is not usable as its in the negative range of int64_t and the result
Packit Service a1973e
		   becomes useless for PAPI. */
Packit Service a1973e
		if ( ctrl->threshold[i] > 0 ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
			SUBDBG( " -> %s: Normalizing result on PIC#%d to %lld\n",
Packit Service a1973e
					__func__, i, ctrl->result[i] );
Packit Service a1973e
#endif /* DEBUG */
Packit Service a1973e
Packit Service a1973e
			/* This shifts the retrieved value back to the PAPI value range */
Packit Service a1973e
			ctrl->result[i] = ctrl->result[i] -
Packit Service a1973e
				( UINT64_MAX - ctrl->threshold[i] ) - 1;
Packit Service a1973e
Packit Service a1973e
			/* Needed if called internally if a PIC didn't really overflow, but
Packit Service a1973e
			   was programmed in the same set. */
Packit Service a1973e
			if ( flags != NOT_A_PAPI_HWD_READ ) {
Packit Service a1973e
				ctrl->result[i] = ctrl->hangover[i];
Packit Service a1973e
			}
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
			SUBDBG( " -> %s: Overflow scaling on PIC#%d:\n", __func__, i );
Packit Service a1973e
			SUBDBG( " -> %s: +++ ctrl->result[%d]=%llu\n",
Packit Service a1973e
					__func__, i, ctrl->result[i] );
Packit Service a1973e
			SUBDBG( " -> %s: +++ ctrl->threshold[%d]=%lld\n",
Packit Service a1973e
					__func__, i, ctrl->threshold[i] );
Packit Service a1973e
			SUBDBG( " -> %s: +++ ctrl->hangover[%d]=%lld\n",
Packit Service a1973e
					__func__, i, ctrl->hangover[i] );
Packit Service a1973e
#endif
Packit Service a1973e
		}
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: +++ ctrl->result[%d]=%llu\n",
Packit Service a1973e
				__func__, i, ctrl->result[i] );
Packit Service a1973e
#endif
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
#ifdef SYNTHETIC_EVENTS_SUPPORTED
Packit Service a1973e
	{
Packit Service a1973e
		int i;
Packit Service a1973e
		const int syn_barrier = _niagara2_vector.cmp_info.num_native_events
Packit Service a1973e
			- __t2_store.syn_evt_count;
Packit Service a1973e
Packit Service a1973e
		for ( i = 0; i < ctrl->count; i++ ) {
Packit Service a1973e
			if ( ctrl->code[i].event_code >= syn_barrier ) {
Packit Service a1973e
				ctrl->result[i] =
Packit Service a1973e
					__int_get_synthetic_event( ctrl->code[i].event_code
Packit Service a1973e
											   - syn_barrier, ctrl, &i );
Packit Service a1973e
			}
Packit Service a1973e
		}
Packit Service a1973e
	}
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* Pass the address of the results back to the calling function */
Packit Service a1973e
	*events = ( long_long * ) & ctrl->result[0];
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING: %s\n", "_papi_read" );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_niagara2_reset( hwd_context_t * ctx, hwd_control_state_t * ctrl )
Packit Service a1973e
{
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* This does a restart of the whole set, setting the internal counters back
Packit Service a1973e
	   to the value passed as preset of the last call of cpc_set_add_request or
Packit Service a1973e
	   cpc_request_preset. */
Packit Service a1973e
	cpc_set_restart( cpc, ctrl->set );
Packit Service a1973e
Packit Service a1973e
#ifdef SYNTHETIC_EVENTS_SUPPORTED
Packit Service a1973e
	{
Packit Service a1973e
		const int syn_barrier = _niagara2_vector.cmp_info.num_native_events
Packit Service a1973e
			- __t2_store.syn_evt_count;
Packit Service a1973e
		int i;
Packit Service a1973e
Packit Service a1973e
		if ( ctrl->syn_count > 0 ) {
Packit Service a1973e
			for ( i = 0; i < MAX_COUNTERS; i++ ) {
Packit Service a1973e
				if ( ctrl->code[i].event_code >= syn_barrier ) {
Packit Service a1973e
Packit Service a1973e
					ctrl->syn_hangover[i] +=
Packit Service a1973e
						__int_get_synthetic_event( ctrl->code[i].event_code -
Packit Service a1973e
												   syn_barrier, ctrl, &i );
Packit Service a1973e
				}
Packit Service a1973e
			}
Packit Service a1973e
		}
Packit Service a1973e
	}
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_niagara2_set_profile( EventSetInfo_t * ESI, int EventIndex, int threshold )
Packit Service a1973e
{
Packit Service a1973e
	/* Seems not to be used. */
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING/LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return PAPI_ENOSUPP;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_niagara2_set_overflow( EventSetInfo_t * ESI, int EventIndex, int threshold )
Packit Service a1973e
{
Packit Service a1973e
	hwd_control_state_t *ctrl = ESI->ctl_state;
Packit Service a1973e
	struct sigaction sigact;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
	SUBDBG( " -> %s: Overflow handling for %#x on PIC#%d requested\n",
Packit Service a1973e
			__func__, ctrl, EventIndex );
Packit Service a1973e
	SUBDBG( " -> %s: ESI->overflow.flags=%#x\n\n", __func__, ctrl,
Packit Service a1973e
			ESI->overflow.flags );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* If threshold > 0, then activate hardware overflow handling, otherwise
Packit Service a1973e
	   disable it. */
Packit Service a1973e
	if ( threshold > 0 ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: Activating overflow handling\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		ctrl->preset[EventIndex] = UINT64_MAX - threshold;
Packit Service a1973e
		ctrl->threshold[EventIndex] = threshold;
Packit Service a1973e
Packit Service a1973e
		/* If SIGEMT is not yet enabled, enable it. In libcpc this means to re-
Packit Service a1973e
		   recreate the used set. In order not to break PAPI operations only the
Packit Service a1973e
		   event referred by EventIndex will be updated to use SIGEMT. */
Packit Service a1973e
		if ( !( ctrl->flags[EventIndex] & CPC_OVF_NOTIFY_EMT ) ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
			SUBDBG( " -> %s: Need to activate SIGEMT on PIC %d\n",
Packit Service a1973e
					__func__, EventIndex );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
			/* Enable overflow handling */
Packit Service a1973e
			if ( __cpc_enable_sigemt( ctrl, EventIndex ) != PAPI_OK ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
				SUBDBG( " -> %s: Activating SIGEMT failed for PIC %d\n",
Packit Service a1973e
						__func__, EventIndex );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
				return PAPI_ESYS;
Packit Service a1973e
			}
Packit Service a1973e
		}
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: SIGEMT activated, will install signal handler\n",
Packit Service a1973e
				__func__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		// FIXME: Not really sure that this construct is working
Packit Service a1973e
		return _papi_hwi_start_signal( SIGEMT, 1, 0 );
Packit Service a1973e
Packit Service a1973e
	} else {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: Disabling overflow handling\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		/* Resetting values which were used for overflow handling */
Packit Service a1973e
		ctrl->preset[EventIndex] = DEFAULT_CNTR_PRESET;
Packit Service a1973e
		ctrl->flags[EventIndex] &= ~( CPC_OVF_NOTIFY_EMT );
Packit Service a1973e
		ctrl->threshold[EventIndex] = 0;
Packit Service a1973e
		ctrl->hangover[EventIndex] = 0;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s:ctrl->preset[%d]=%d, ctrl->flags[%d]=%p\n",
Packit Service a1973e
				__func__, EventIndex, ctrl->preset[EventIndex],
Packit Service a1973e
				EventIndex, ctrl->flags[EventIndex] );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		/* Recreate the undelying set and disable the signal handler */
Packit Service a1973e
		__CHECK_ERR_PAPI( __cpc_recreate_set( ctrl ) );
Packit Service a1973e
		__CHECK_ERR_PAPI( _papi_hwi_stop_signal( SIGEMT ) );
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_niagara2_shutdown( hwd_context_t * ctx )
Packit Service a1973e
{
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	cpc_buf_destroy( cpc, ctx->counter_buffer );
Packit Service a1973e
	cpc_set_destroy( cpc, ctx->set );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_niagara2_shutdown_global( void )
Packit Service a1973e
{
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* Free allocated memory */
Packit Service a1973e
Packit Service a1973e
	// papi_calloc in __cpc_build_ntv_table
Packit Service a1973e
	papi_free( __t2_store.pic_ntv_count );
Packit Service a1973e
	// papi_calloc in __cpc_build_ntv_table
Packit Service a1973e
	papi_free( __t2_ntv_events );
Packit Service a1973e
	// papi_calloc in __cpc_build_pst_table
Packit Service a1973e
	papi_free( preset_table );
Packit Service a1973e
Packit Service a1973e
	/* Shutdown libcpc */
Packit Service a1973e
Packit Service a1973e
	// cpc_open in _papi_init_component
Packit Service a1973e
	cpc_close( cpc );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_niagara2_start( hwd_context_t * ctx, hwd_control_state_t * ctrl )
Packit Service a1973e
{
Packit Service a1973e
	int retval;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
	SUBDBG( " -> %s: Starting EventSet %p\n", __func__, ctrl );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
#ifdef SYNTHETIC_EVENTS_SUPPORTED
Packit Service a1973e
	{
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: Event count: ctrl->count=%d, ctrl->syn_count=%d\n",
Packit Service a1973e
				__func__, ctrl->count, ctrl->syn_count );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		if ( ctrl->count > 0 && ctrl->count == ctrl->syn_count ) {
Packit Service a1973e
			ctrl->idx[0] = cpc_set_add_request( cpc, ctrl->set, "Instr_cnt",
Packit Service a1973e
												ctrl->preset[0], ctrl->flags[0],
Packit Service a1973e
												0, NULL );
Packit Service a1973e
			ctrl->counter_buffer = cpc_buf_create( cpc, ctrl->set );
Packit Service a1973e
		}
Packit Service a1973e
	}
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	{
Packit Service a1973e
		int i;
Packit Service a1973e
Packit Service a1973e
		for ( i = 0; i < MAX_COUNTERS; i++ ) {
Packit Service a1973e
			SUBDBG( " -> %s: Flags for PIC#%d: ctrl->flags[%d]=%d\n", __func__,
Packit Service a1973e
					i, i, ctrl->flags[i] );
Packit Service a1973e
		}
Packit Service a1973e
	}
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	__CHECK_ERR_DFLT( cpc_bind_curlwp( cpc, ctrl->set, CPC_BIND_LWP_INHERIT ) );
Packit Service a1973e
Packit Service a1973e
	/* Ensure the set is working properly */
Packit Service a1973e
	retval = cpc_set_sample( cpc, ctrl->set, ctrl->counter_buffer );
Packit Service a1973e
Packit Service a1973e
	if ( retval != 0 ) {
Packit Service a1973e
		printf( "%s: cpc_set_sample failed, return=%d, errno=%d\n",
Packit Service a1973e
				__func__, retval, errno );
Packit Service a1973e
		return PAPI_ECMP;
Packit Service a1973e
	}
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_niagara2_stop( hwd_context_t * ctx, hwd_control_state_t * ctrl )
Packit Service a1973e
{
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	__CHECK_ERR_DFLT( cpc_unbind( cpc, ctrl->set ) );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_niagara2_update_control_state( hwd_control_state_t * ctrl,
Packit Service a1973e
								NativeInfo_t * native, int count,
Packit Service a1973e
								hwd_context_t * ctx )
Packit Service a1973e
{
Packit Service a1973e
	int i;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* Delete everything as we can't change an existing set */
Packit Service a1973e
	if ( ctrl->counter_buffer != NULL ) {
Packit Service a1973e
		__CHECK_ERR_DFLT( cpc_buf_destroy( cpc, ctrl->counter_buffer ) );
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	if ( ctrl->set != NULL ) {
Packit Service a1973e
		__CHECK_ERR_DFLT( cpc_set_destroy( cpc, ctrl->set ) );
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	for ( i = 0; i < MAX_COUNTERS; i++ ) {
Packit Service a1973e
		ctrl->idx[i] = EVENT_NOT_SET;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	/* New setup */
Packit Service a1973e
Packit Service a1973e
	ctrl->set = cpc_set_create( cpc );
Packit Service a1973e
	__CHECK_ERR_NULL( ctrl->set );
Packit Service a1973e
Packit Service a1973e
	ctrl->count = count;
Packit Service a1973e
	ctrl->syn_count = 0;
Packit Service a1973e
Packit Service a1973e
	for ( i = 0; i < count; i++ ) {
Packit Service a1973e
		/* Store the active event */
Packit Service a1973e
		ctrl->code[i].event_code = native[i].ni_event & PAPI_NATIVE_AND_MASK;
Packit Service a1973e
Packit Service a1973e
		ctrl->flags[i] = __cpc_domain_translator( PAPI_DOM_USER );
Packit Service a1973e
		ctrl->preset[i] = DEFAULT_CNTR_PRESET;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG
Packit Service a1973e
			( " -> %s: EventSet@%p/PIC#%d - ntv request >>%s<< (%d), flags=%#x\n",
Packit Service a1973e
			  __func__, ctrl, i, __t2_ntv_events[ctrl->code[i].event_code],
Packit Service a1973e
			  ctrl->code[i].event_code, ctrl->flags[i] );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		/* Store the counter position (???) */
Packit Service a1973e
		native[i].ni_position = i;
Packit Service a1973e
Packit Service a1973e
#ifdef SYNTHETIC_EVENTS_SUPPORTED
Packit Service a1973e
		{
Packit Service a1973e
			int syn_code = ctrl->code[i].event_code -
Packit Service a1973e
				( _niagara2_vector.cmp_info.num_native_events
Packit Service a1973e
				  - __t2_store.syn_evt_count ) - 1;
Packit Service a1973e
Packit Service a1973e
			/* Check if the event code is bigger than the CPC provided events. */
Packit Service a1973e
			if ( syn_code >= 0 ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
				SUBDBG
Packit Service a1973e
					( " -> %s: Adding synthetic event %#x (%s) on position %d\n",
Packit Service a1973e
					  __func__, native[i].ni_event,
Packit Service a1973e
					  __t2_ntv_events[ctrl->code[i].event_code], i );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
				/* Call the setup routine */
Packit Service a1973e
				__int_setup_synthetic_event( syn_code, ctrl, NULL );
Packit Service a1973e
Packit Service a1973e
				/* Clean the hangover count as this event is new */
Packit Service a1973e
				ctrl->syn_hangover[i] = 0;
Packit Service a1973e
Packit Service a1973e
				/* Register this event as being synthetic, as an event set only
Packit Service a1973e
				   based on synthetic events can not be actived through libcpc */
Packit Service a1973e
				ctrl->syn_count++;
Packit Service a1973e
Packit Service a1973e
				/* Jump to next iteration */
Packit Service a1973e
				continue;
Packit Service a1973e
			}
Packit Service a1973e
		}
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: Adding native event %#x (%s) on position %d\n",
Packit Service a1973e
				__func__, native[i].ni_event,
Packit Service a1973e
				__t2_ntv_events[ctrl->code[i].event_code], i );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		/* Pass the event as request to libcpc */
Packit Service a1973e
		ctrl->idx[i] = cpc_set_add_request( cpc, ctrl->set,
Packit Service a1973e
											__t2_ntv_events[ctrl->code[i].
Packit Service a1973e
															event_code],
Packit Service a1973e
											ctrl->preset[i], ctrl->flags[i], 0,
Packit Service a1973e
											NULL );
Packit Service a1973e
		__CHECK_ERR_NEGV( ctrl->idx[i] );
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	if ( i == 0 ) {
Packit Service a1973e
		SUBDBG( " -> %s: nothing added\n", __func__ );
Packit Service a1973e
	}
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	ctrl->counter_buffer = cpc_buf_create( cpc, ctrl->set );
Packit Service a1973e
	__CHECK_ERR_NULL( ctrl->counter_buffer );
Packit Service a1973e
Packit Service a1973e
	/* Finished the new setup */
Packit Service a1973e
Packit Service a1973e
	/* Linking to context (same data type by typedef!) */
Packit Service a1973e
	ctx = ctrl;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_niagara2_update_shlib_info( papi_mdi_t *mdi )
Packit Service a1973e
{
Packit Service a1973e
	char *file = "/proc/self/map";
Packit Service a1973e
	char *resolve_pattern = "/proc/self/path/%s";
Packit Service a1973e
Packit Service a1973e
	char lastobject[PRMAPSZ];
Packit Service a1973e
	char link[PAPI_HUGE_STR_LEN];
Packit Service a1973e
	char path[PAPI_HUGE_STR_LEN];
Packit Service a1973e
Packit Service a1973e
	prmap_t mapping;
Packit Service a1973e
Packit Service a1973e
	int fd, count = 0, total = 0, position = -1, first = 1;
Packit Service a1973e
	caddr_t t_min, t_max, d_min, d_max;
Packit Service a1973e
Packit Service a1973e
	PAPI_address_map_t *pam, *cur;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	fd = open( file, O_RDONLY );
Packit Service a1973e
Packit Service a1973e
	if ( fd == -1 ) {
Packit Service a1973e
		return PAPI_ESYS;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	memset( lastobject, 0, PRMAPSZ );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( " -> %s: Preprocessing memory maps from procfs\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* Search through the list of mappings in order to identify a) how many
Packit Service a1973e
	   mappings are available and b) how many unique mappings are available. */
Packit Service a1973e
	while ( read( fd, &mapping, sizeof ( prmap_t ) ) > 0 ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: Found a new memory map entry\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
		/* Another entry found, just the total count of entries. */
Packit Service a1973e
		total++;
Packit Service a1973e
Packit Service a1973e
		/* Is the mapping accessible and not anonymous? */
Packit Service a1973e
		if ( mapping.pr_mflags & ( MA_READ | MA_WRITE | MA_EXEC ) &&
Packit Service a1973e
			 !( mapping.pr_mflags & MA_ANON ) ) {
Packit Service a1973e
			/* Test if a new library has been found. If a new library has been
Packit Service a1973e
			   found a new entry needs to be counted. */
Packit Service a1973e
			if ( strcmp( lastobject, mapping.pr_mapname ) != 0 ) {
Packit Service a1973e
				strncpy( lastobject, mapping.pr_mapname, PRMAPSZ );
Packit Service a1973e
				count++;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
				SUBDBG( " -> %s: Memory mapping entry valid for %s\n", __func__,
Packit Service a1973e
						mapping.pr_mapname );
Packit Service a1973e
#endif
Packit Service a1973e
			}
Packit Service a1973e
		}
Packit Service a1973e
	}
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( " -> %s: Preprocessing done, starting to analyze\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
	/* Start from the beginning, now fill in the found mappings */
Packit Service a1973e
	if ( lseek( fd, 0, SEEK_SET ) == -1 ) {
Packit Service a1973e
		return PAPI_ESYS;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	memset( lastobject, 0, PRMAPSZ );
Packit Service a1973e
Packit Service a1973e
	/* Allocate memory */
Packit Service a1973e
	pam =
Packit Service a1973e
		( PAPI_address_map_t * ) papi_calloc( count,
Packit Service a1973e
											  sizeof ( PAPI_address_map_t ) );
Packit Service a1973e
Packit Service a1973e
	while ( read( fd, &mapping, sizeof ( prmap_t ) ) > 0 ) {
Packit Service a1973e
Packit Service a1973e
		if ( mapping.pr_mflags & MA_ANON ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
			SUBDBG
Packit Service a1973e
				( " -> %s: Anonymous mapping (MA_ANON) found for %s, skipping\n",
Packit Service a1973e
				  __func__, mapping.pr_mapname );
Packit Service a1973e
#endif
Packit Service a1973e
			continue;
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
		/* Check for a new entry */
Packit Service a1973e
		if ( strcmp( mapping.pr_mapname, lastobject ) != 0 ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
			SUBDBG( " -> %s: Analyzing mapping for %s\n", __func__,
Packit Service a1973e
					mapping.pr_mapname );
Packit Service a1973e
#endif
Packit Service a1973e
			cur = &( pam[++position] );
Packit Service a1973e
			strncpy( lastobject, mapping.pr_mapname, PRMAPSZ );
Packit Service a1973e
			snprintf( link, PAPI_HUGE_STR_LEN, resolve_pattern, lastobject );
Packit Service a1973e
			memset( path, 0, PAPI_HUGE_STR_LEN );
Packit Service a1973e
			readlink( link, path, PAPI_HUGE_STR_LEN );
Packit Service a1973e
			strncpy( cur->name, path, PAPI_HUGE_STR_LEN );
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
			SUBDBG( " -> %s: Resolved name for %s: %s\n", __func__,
Packit Service a1973e
					mapping.pr_mapname, cur->name );
Packit Service a1973e
#endif
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
		if ( mapping.pr_mflags & MA_READ ) {
Packit Service a1973e
			/* Data (MA_WRITE) or text (MA_READ) segment? */
Packit Service a1973e
			if ( mapping.pr_mflags & MA_WRITE ) {
Packit Service a1973e
				cur->data_start = ( caddr_t ) mapping.pr_vaddr;
Packit Service a1973e
				cur->data_end =
Packit Service a1973e
					( caddr_t ) ( mapping.pr_vaddr + mapping.pr_size );
Packit Service a1973e
Packit Service a1973e
				if ( strcmp
Packit Service a1973e
					 ( cur->name,
Packit Service a1973e
					   _papi_hwi_system_info.exe_info.fullname ) == 0 ) {
Packit Service a1973e
					_papi_hwi_system_info.exe_info.address_info.data_start =
Packit Service a1973e
						cur->data_start;
Packit Service a1973e
					_papi_hwi_system_info.exe_info.address_info.data_end =
Packit Service a1973e
						cur->data_end;
Packit Service a1973e
				}
Packit Service a1973e
Packit Service a1973e
				if ( first )
Packit Service a1973e
					d_min = cur->data_start;
Packit Service a1973e
				if ( first )
Packit Service a1973e
					d_max = cur->data_end;
Packit Service a1973e
Packit Service a1973e
				if ( cur->data_start < d_min ) {
Packit Service a1973e
					d_min = cur->data_start;
Packit Service a1973e
				}
Packit Service a1973e
Packit Service a1973e
				if ( cur->data_end > d_max ) {
Packit Service a1973e
					d_max = cur->data_end;
Packit Service a1973e
				}
Packit Service a1973e
			} else if ( mapping.pr_mflags & MA_EXEC ) {
Packit Service a1973e
				cur->text_start = ( caddr_t ) mapping.pr_vaddr;
Packit Service a1973e
				cur->text_end =
Packit Service a1973e
					( caddr_t ) ( mapping.pr_vaddr + mapping.pr_size );
Packit Service a1973e
Packit Service a1973e
				if ( strcmp
Packit Service a1973e
					 ( cur->name,
Packit Service a1973e
					   _papi_hwi_system_info.exe_info.fullname ) == 0 ) {
Packit Service a1973e
					_papi_hwi_system_info.exe_info.address_info.text_start =
Packit Service a1973e
						cur->text_start;
Packit Service a1973e
					_papi_hwi_system_info.exe_info.address_info.text_end =
Packit Service a1973e
						cur->text_end;
Packit Service a1973e
				}
Packit Service a1973e
Packit Service a1973e
				if ( first )
Packit Service a1973e
					t_min = cur->text_start;
Packit Service a1973e
				if ( first )
Packit Service a1973e
					t_max = cur->text_end;
Packit Service a1973e
Packit Service a1973e
				if ( cur->text_start < t_min ) {
Packit Service a1973e
					t_min = cur->text_start;
Packit Service a1973e
				}
Packit Service a1973e
Packit Service a1973e
				if ( cur->text_end > t_max ) {
Packit Service a1973e
					t_max = cur->text_end;
Packit Service a1973e
				}
Packit Service a1973e
			}
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
		first = 0;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	close( fd );
Packit Service a1973e
Packit Service a1973e
	/* During the walk of shared objects the upper and lower bound of the
Packit Service a1973e
	   segments could be discovered. The bounds are stored in the PAPI info
Packit Service a1973e
	   structure. The information is important for the profiling functions of
Packit Service a1973e
	   PAPI. */
Packit Service a1973e
Packit Service a1973e
/* This variant would pass the addresses of all text and data segments 
Packit Service a1973e
  _papi_hwi_system_info.exe_info.address_info.text_start = t_min;
Packit Service a1973e
  _papi_hwi_system_info.exe_info.address_info.text_end = t_max;
Packit Service a1973e
  _papi_hwi_system_info.exe_info.address_info.data_start = d_min;
Packit Service a1973e
  _papi_hwi_system_info.exe_info.address_info.data_end = d_max;
Packit Service a1973e
*/
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( " -> %s: Analysis of memory maps done, results:\n", __func__ );
Packit Service a1973e
	SUBDBG( " -> %s: text_start=%#x, text_end=%#x, text_size=%lld\n", __func__,
Packit Service a1973e
			_papi_hwi_system_info.exe_info.address_info.text_start,
Packit Service a1973e
			_papi_hwi_system_info.exe_info.address_info.text_end,
Packit Service a1973e
			_papi_hwi_system_info.exe_info.address_info.text_end
Packit Service a1973e
			- _papi_hwi_system_info.exe_info.address_info.text_start );
Packit Service a1973e
	SUBDBG( " -> %s: data_start=%#x, data_end=%#x, data_size=%lld\n", __func__,
Packit Service a1973e
			_papi_hwi_system_info.exe_info.address_info.data_start,
Packit Service a1973e
			_papi_hwi_system_info.exe_info.address_info.data_end,
Packit Service a1973e
			_papi_hwi_system_info.exe_info.address_info.data_end
Packit Service a1973e
			- _papi_hwi_system_info.exe_info.address_info.data_start );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* Store the map read and the total count of shlibs found */
Packit Service a1973e
	_papi_hwi_system_info.shlib_info.map = pam;
Packit Service a1973e
	_papi_hwi_system_info.shlib_info.count = count;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
//////////////////////////////////////////////////////////////////////////////////
Packit Service a1973e
/// UTILITY FUNCTIONS FOR ACCESS TO LIBCPC AND SOLARIS /////////////////////////
Packit Service a1973e
////////////////////////////////////////////////////////////////////////////////
Packit Service a1973e
Packit Service a1973e
/* DESCRIPTION:
Packit Service a1973e
 * -----------------------------------------------------------------------------
Packit Service a1973e
 * The following functions are for accessing libcpc 2 and Solaris related stuff
Packit Service a1973e
 * needed for PAPI.
Packit Service a1973e
 ******************************************************************************/
Packit Service a1973e
Packit Service a1973e
static inline int
Packit Service a1973e
__cpc_build_ntv_table( void )
Packit Service a1973e
{
Packit Service a1973e
	int i, tmp;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	__t2_store.pic_ntv_count = papi_calloc( __t2_store.npic, sizeof ( int ) );
Packit Service a1973e
	__CHECK_ERR_NULL( __t2_store.pic_ntv_count );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( " -> %s: Checking PICs for functionality\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	for ( i = 0; i < __t2_store.npic; i++ ) {
Packit Service a1973e
		cpc_walk_events_pic( cpc, i, NULL, __cpc_walk_events_pic_action_count );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: Found %d events on PIC#%d\n", __func__,
Packit Service a1973e
				__t2_store.pic_ntv_count[i], i );
Packit Service a1973e
#endif
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	tmp = __t2_store.pic_ntv_count[0];
Packit Service a1973e
Packit Service a1973e
	/* There should be at least one counter... */
Packit Service a1973e
	if ( tmp == 0 ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: PIC#0 has 0 events\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		return PAPI_ECMP;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	/* Check if all PICs have the same number of counters */
Packit Service a1973e
	for ( i = 0; i < __t2_store.npic; i++ ) {
Packit Service a1973e
		if ( __t2_store.pic_ntv_count[i] != tmp ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
			SUBDBG( " -> %s: PIC#%d has %d events, should have %d\n",
Packit Service a1973e
					__func__, i, __t2_store.pic_ntv_count[i], tmp );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
			return PAPI_ECMP;
Packit Service a1973e
		}
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	/* Count synthetic events which add functionality to libcpc */
Packit Service a1973e
#ifdef SYNTHETIC_EVENTS_SUPPORTED
Packit Service a1973e
	__t2_store.syn_evt_count = 0;
Packit Service a1973e
	__int_walk_synthetic_events_action_count(  );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* Store the count of events available in central data structure */
Packit Service a1973e
#ifndef SYNTHETIC_EVENTS_SUPPORTED
Packit Service a1973e
	_niagara2_vector.cmp_info.num_native_events = __t2_store.pic_ntv_count[0];
Packit Service a1973e
#else
Packit Service a1973e
	_niagara2_vector.cmp_info.num_native_events =
Packit Service a1973e
		__t2_store.pic_ntv_count[0] + __t2_store.syn_evt_count;
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
	/* Allocate memory for storing all events found, including the first empty
Packit Service a1973e
	   slot */
Packit Service a1973e
	__t2_ntv_events =
Packit Service a1973e
		papi_calloc( _niagara2_vector.cmp_info.num_native_events + 1,
Packit Service a1973e
					 sizeof ( char * ) );
Packit Service a1973e
Packit Service a1973e
	__t2_ntv_events[0] = "THIS IS A BUG!";
Packit Service a1973e
Packit Service a1973e
	tmp = 1;
Packit Service a1973e
	cpc_walk_events_pic( cpc, 0, ( void * ) &tmp,
Packit Service a1973e
						 __cpc_walk_events_pic_action_store );
Packit Service a1973e
Packit Service a1973e
#ifdef SYNTHETIC_EVENTS_SUPPORTED
Packit Service a1973e
	__int_walk_synthetic_events_action_store(  );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	for ( i = 1; i < __t2_store.pic_ntv_count[0]; i++ ) {
Packit Service a1973e
		SUBDBG( " -> %s: Event #%d: %s\n", __func__, i, __t2_ntv_events[i] );
Packit Service a1973e
	}
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
/* Return event code for event_name */
Packit Service a1973e
Packit Service a1973e
static inline int
Packit Service a1973e
__cpc_search_ntv_event( char *event_name, int *event_code )
Packit Service a1973e
{
Packit Service a1973e
	int i;
Packit Service a1973e
Packit Service a1973e
	for ( i = 0; i < _niagara2_vector.cmp_info.num_native_events; i++ ) {
Packit Service a1973e
		if ( strcmp( event_name, __t2_ntv_events[i] ) == 0 ) {
Packit Service a1973e
			*event_code = i;
Packit Service a1973e
			return PAPI_OK;
Packit Service a1973e
		}
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	return PAPI_ENOEVNT;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
static inline int
Packit Service a1973e
__cpc_build_pst_table( void )
Packit Service a1973e
{
Packit Service a1973e
	int num_psts, i, j, event_code, pst_events;
Packit Service a1973e
	hwi_search_t tmp;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	num_psts = 0;
Packit Service a1973e
Packit Service a1973e
	while ( __t2_table[num_psts].papi_pst != 0 ) {
Packit Service a1973e
		num_psts++;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( " -> %s: Found %d presets\n", __func__, num_psts );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	preset_table = papi_calloc( num_psts + 1, sizeof ( hwi_search_t ) );
Packit Service a1973e
	__CHECK_ERR_NULL( preset_table );
Packit Service a1973e
Packit Service a1973e
	pst_events = 0;
Packit Service a1973e
Packit Service a1973e
	for ( i = 0; i < num_psts; i++ ) {
Packit Service a1973e
		memset( &tmp, PAPI_NULL, sizeof ( tmp ) );
Packit Service a1973e
Packit Service a1973e
		/* Mark counters as unused. If they are needed, they will be overwritten
Packit Service a1973e
		   later. See papi_preset.c:51 for more details. */
Packit Service a1973e
		for ( j = 0; j < PAPI_EVENTS_IN_DERIVED_EVENT; j++ ) {
Packit Service a1973e
			tmp.data.native[j] = PAPI_NULL;
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
		tmp.event_code = __t2_table[i].papi_pst;
Packit Service a1973e
		tmp.data.derived = __t2_table[i].ntv_opcode;
Packit Service a1973e
		tmp.data.operation[0] = '\0';
Packit Service a1973e
Packit Service a1973e
		switch ( __t2_table[i].ntv_opcode ) {
Packit Service a1973e
		case DERIVED_ADD:
Packit Service a1973e
			tmp.data.operation[0] = '+';
Packit Service a1973e
			break;
Packit Service a1973e
		case DERIVED_SUB:
Packit Service a1973e
			tmp.data.operation[0] = '-';
Packit Service a1973e
			break;
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
		for ( j = 0; j < __t2_table[i].ntv_ctrs; j++ ) {
Packit Service a1973e
			if ( __cpc_search_ntv_event
Packit Service a1973e
				 ( __t2_table[i].ntv_event[j], &event_code )
Packit Service a1973e
				 >= PAPI_OK ) {
Packit Service a1973e
				tmp.data.native[j] = event_code;
Packit Service a1973e
			} else {
Packit Service a1973e
				continue;
Packit Service a1973e
			}
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: pst row %d - event_code=%d\n",
Packit Service a1973e
				__func__, i, tmp.event_code );
Packit Service a1973e
		SUBDBG( " -> %s: pst row %d - data.derived=%d, data.operation=%c\n",
Packit Service a1973e
				__func__, i, tmp.data.derived, tmp.data.operation[0] );
Packit Service a1973e
		SUBDBG( " -> %s: pst row %d - native event codes:\n", __func__, i );
Packit Service a1973e
		{
Packit Service a1973e
			int d_i;
Packit Service a1973e
Packit Service a1973e
			for ( d_i = 0; d_i < PAPI_EVENTS_IN_DERIVED_EVENT; d_i++ ) {
Packit Service a1973e
				SUBDBG( " -> %s: pst row %d - +++ data.native[%d]=%d\n",
Packit Service a1973e
						__func__, i, d_i, tmp.data.native[d_i] );
Packit Service a1973e
			}
Packit Service a1973e
		}
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		memcpy( &preset_table[i], &tmp, sizeof ( tmp ) );
Packit Service a1973e
Packit Service a1973e
		pst_events++;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	// Check!
Packit Service a1973e
	memset( &preset_table[num_psts], 0, sizeof ( hwi_search_t ) );
Packit Service a1973e
Packit Service a1973e
	_niagara2_vector.cmp_info.num_preset_events = pst_events;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
static inline int
Packit Service a1973e
__cpc_recreate_set( hwd_control_state_t * ctrl )
Packit Service a1973e
{
Packit Service a1973e
#ifdef SYNTHETIC_EVENTS_SUPPORTED
Packit Service a1973e
	const int syn_barrier = _niagara2_vector.cmp_info.num_native_events
Packit Service a1973e
		- __t2_store.syn_evt_count;
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	int i;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* Destroy the old buffer and the old set if they exist, we need to do a full
Packit Service a1973e
	   recreate as changing flags or events through libcpc is not possible */
Packit Service a1973e
	if ( ctrl->counter_buffer != NULL ) {
Packit Service a1973e
		__CHECK_ERR_DFLT( cpc_buf_destroy( cpc, ctrl->counter_buffer ) );
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	if ( ctrl->set != NULL ) {
Packit Service a1973e
		__CHECK_ERR_DFLT( cpc_set_destroy( cpc, ctrl->set ) );
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	/* Create a new set */
Packit Service a1973e
	ctrl->set = cpc_set_create( cpc );
Packit Service a1973e
	__CHECK_ERR_NULL( ctrl->set );
Packit Service a1973e
Packit Service a1973e
	for ( i = 0; i < ctrl->count; i++ ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: Adding native event %#x (%s) on position %d\n",
Packit Service a1973e
				__func__, ctrl->code[i].event_code,
Packit Service a1973e
				__t2_ntv_events[ctrl->code[i].event_code], i );
Packit Service a1973e
		SUBDBG( " -> %s: Event setup: ctrl->code[%d].event_code=%#x\n",
Packit Service a1973e
				__func__, i, ctrl->code[i].event_code );
Packit Service a1973e
		SUBDBG( " -> %s: Event setup: ctrl->preset[%d]=%d\n",
Packit Service a1973e
				__func__, i, ctrl->preset[i] );
Packit Service a1973e
		SUBDBG( " -> %s: Event setup: ctrl->flags[%d]=%#x\n",
Packit Service a1973e
				__func__, i, ctrl->flags[i] );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
#ifdef SYNTHETIC_EVENTS_SUPPORTED
Packit Service a1973e
		/* Ensure that synthetic events are skipped */
Packit Service a1973e
		if ( ctrl->code[i].event_code >= syn_barrier ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
			SUBDBG( " -> %s: Skipping counter %d, synthetic event found\n",
Packit Service a1973e
					__func__, i );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
			/* Next iteration */
Packit Service a1973e
			continue;
Packit Service a1973e
		}
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		ctrl->idx[i] = cpc_set_add_request( cpc, ctrl->set,
Packit Service a1973e
											__t2_ntv_events[ctrl->code[i].
Packit Service a1973e
															event_code],
Packit Service a1973e
											ctrl->preset[i], ctrl->flags[i], 0,
Packit Service a1973e
											NULL );
Packit Service a1973e
		__CHECK_ERR_NEGV( ctrl->idx[i] );
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	ctrl->counter_buffer = cpc_buf_create( cpc, ctrl->set );
Packit Service a1973e
	__CHECK_ERR_NULL( ctrl->counter_buffer );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
static inline int
Packit Service a1973e
__cpc_domain_translator( const int papi_domain )
Packit Service a1973e
{
Packit Service a1973e
	int domain = 0;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
	SUBDBG( " -> %s: papi_domain=%d requested\n", __func__, papi_domain );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	if ( papi_domain & PAPI_DOM_USER ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: Domain PAPI_DOM_USER/CPC_COUNT_USER selected\n",
Packit Service a1973e
				__func__ );
Packit Service a1973e
#endif
Packit Service a1973e
		domain |= CPC_COUNT_USER;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	if ( papi_domain & PAPI_DOM_KERNEL ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: Domain PAPI_DOM_KERNEL/CPC_COUNT_SYSTEM selected\n",
Packit Service a1973e
				__func__ );
Packit Service a1973e
#endif
Packit Service a1973e
		domain |= CPC_COUNT_SYSTEM;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	if ( papi_domain & PAPI_DOM_SUPERVISOR ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: Domain PAPI_DOM_SUPERVISOR/CPC_COUNT_HV selected\n",
Packit Service a1973e
				__func__ );
Packit Service a1973e
#endif
Packit Service a1973e
		domain |= CPC_COUNT_HV;
Packit Service a1973e
	}
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( " -> %s: domain=%d\n", __func__, domain );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return domain;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
void
Packit Service a1973e
__cpc_error_handler( const char *fn, int subcode, const char *fmt, va_list ap )
Packit Service a1973e
{
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* From the libcpc manpages */
Packit Service a1973e
	fprintf( stderr, "ERROR - libcpc error handler in %s() called!\n", fn );
Packit Service a1973e
	vfprintf( stderr, fmt, ap );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
static inline int
Packit Service a1973e
__cpc_enable_sigemt( hwd_control_state_t * ctrl, int position )
Packit Service a1973e
{
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	if ( position >= MAX_COUNTERS ) {
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: Position of the counter does not exist\n", __func__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		return PAPI_EINVAL;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	ctrl->flags[position] = ctrl->flags[position] | CPC_OVF_NOTIFY_EMT;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return __cpc_recreate_set( ctrl );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
void
Packit Service a1973e
__cpc_walk_events_pic_action_count( void *arg, uint_t picno, const char *event )
Packit Service a1973e
{
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	__t2_store.pic_ntv_count[picno]++;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG
Packit Service a1973e
		( " -> %s: Found one native event on PIC#%d (now totally %d events)\n",
Packit Service a1973e
		  __func__, picno, __t2_store.pic_ntv_count[picno] );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
void
Packit Service a1973e
__cpc_walk_events_pic_action_store( void *arg, uint_t picno, const char *event )
Packit Service a1973e
{
Packit Service a1973e
	int *tmp = ( int * ) arg;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	__t2_ntv_events[*tmp] = papi_strdup( event );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( " -> %s: Native event >>%s<< registered\n",
Packit Service a1973e
			__func__, __t2_ntv_events[*tmp] );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	*tmp = *tmp + 1;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
static inline int
Packit Service a1973e
__sol_get_processor_clock( void )
Packit Service a1973e
{
Packit Service a1973e
	processor_info_t pinfo;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	// Fetch information from the first processor in the system
Packit Service a1973e
	if ( processor_info( getcpuid(  ), &pinfo ) == 0 ) {
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( " -> %s: Clock at %d MHz\n", __func__, pinfo.pi_clock );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
		return pinfo.pi_clock;
Packit Service a1973e
	}
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return PAPI_ESYS;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
/* This function either increases the ns supplied to itimer_res_ns or pads it up
Packit Service a1973e
 * to a multiple of itimer_res_ns if the value is bigger than itimer_res_ns.
Packit Service a1973e
 *
Packit Service a1973e
 * The source is taken from the old component.
Packit Service a1973e
 */
Packit Service a1973e
static inline int
Packit Service a1973e
__sol_get_itimer_ns( int ns )
Packit Service a1973e
{
Packit Service a1973e
	if ( ns < _papi_os_info.itimer_res_ns ) {
Packit Service a1973e
		return _papi_os_info.itimer_res_ns;
Packit Service a1973e
	} else {
Packit Service a1973e
		int leftover_ns = ns % _papi_os_info.itimer_res_ns;
Packit Service a1973e
		return ns + leftover_ns;
Packit Service a1973e
	}
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
static inline lwpstatus_t *
Packit Service a1973e
__sol_get_lwp_status( const pid_t pid, const lwpid_t lwpid )
Packit Service a1973e
{
Packit Service a1973e
	char *pattern = "/proc/%d/lwp/%d/lwpstatus";
Packit Service a1973e
	char filename[PAPI_MIN_STR_LEN];
Packit Service a1973e
	int fd;
Packit Service a1973e
	static lwpstatus_t lwp;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	memset( &lwp, 0, sizeof ( lwp ) );
Packit Service a1973e
	snprintf( filename, PAPI_MIN_STR_LEN, pattern, pid, lwpid );
Packit Service a1973e
Packit Service a1973e
	fd = open( filename, O_RDONLY );
Packit Service a1973e
	if ( fd == -1 )
Packit Service a1973e
		return NULL;
Packit Service a1973e
Packit Service a1973e
	read( fd, ( void * ) &lwp, sizeof ( lwp ) );
Packit Service a1973e
Packit Service a1973e
	close( fd );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return &lw;;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
static inline psinfo_t *
Packit Service a1973e
__sol_get_proc_info( const pid_t pid )
Packit Service a1973e
{
Packit Service a1973e
	char *pattern = "/proc/%d/psinfo";
Packit Service a1973e
	char filename[PAPI_MIN_STR_LEN];
Packit Service a1973e
	int fd;
Packit Service a1973e
	static psinfo_t proc;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	memset( &proc, 0, sizeof ( proc ) );
Packit Service a1973e
	snprintf( filename, PAPI_MIN_STR_LEN, pattern, pid );
Packit Service a1973e
Packit Service a1973e
	fd = open( filename, O_RDONLY );
Packit Service a1973e
	if ( fd == -1 )
Packit Service a1973e
		return NULL;
Packit Service a1973e
Packit Service a1973e
	read( fd, ( void * ) &proc, sizeof ( proc ) );
Packit Service a1973e
Packit Service a1973e
	close( fd );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return &proc;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
static inline pstatus_t *
Packit Service a1973e
__sol_get_proc_status( const pid_t pid )
Packit Service a1973e
{
Packit Service a1973e
	char *pattern = "/proc/%d/status";
Packit Service a1973e
	char filename[PAPI_MIN_STR_LEN];
Packit Service a1973e
	int fd;
Packit Service a1973e
	static pstatus_t proc;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	memset( &proc, 0, sizeof ( proc ) );
Packit Service a1973e
	snprintf( filename, PAPI_MIN_STR_LEN, pattern, pid );
Packit Service a1973e
Packit Service a1973e
	fd = open( filename, O_RDONLY );
Packit Service a1973e
	if ( fd == -1 )
Packit Service a1973e
		return NULL;
Packit Service a1973e
Packit Service a1973e
	read( fd, ( void * ) &proc, sizeof ( proc ) );
Packit Service a1973e
Packit Service a1973e
	close( fd );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	return &proc;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
/* This function handles synthetic events and returns their result. Synthetic 
Packit Service a1973e
 * events are events retrieved from outside of libcpc, e.g. all events which
Packit Service a1973e
 * can not be retrieved using cpc_set_add_request/cpc_buf_get. */
Packit Service a1973e
Packit Service a1973e
#ifdef SYNTHETIC_EVENTS_SUPPORTED
Packit Service a1973e
Packit Service a1973e
uint64_t
Packit Service a1973e
__int_get_synthetic_event( int code, hwd_control_state_t * ctrl, void *arg )
Packit Service a1973e
{
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	switch ( code ) {
Packit Service a1973e
	case SYNTHETIC_CYCLES_ELAPSED:
Packit Service a1973e
		/* Return the count of ticks this set was bound. If a reset of the set
Packit Service a1973e
		   has been executed the last count will be subtracted. */
Packit Service a1973e
	{
Packit Service a1973e
		int *i = ( int * ) arg;
Packit Service a1973e
		return cpc_buf_tick( cpc,
Packit Service a1973e
							 ctrl->counter_buffer ) - ctrl->syn_hangover[*i];
Packit Service a1973e
	}
Packit Service a1973e
	case SYNTHETIC_RETURN_ONE:
Packit Service a1973e
		// The name says it - only for testing purposes.
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
				__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
		return 1;
Packit Service a1973e
	case SYNTHETIC_RETURN_TWO:
Packit Service a1973e
		// The name says it - only for testing purposes.
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
				__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
		return 2;
Packit Service a1973e
	default:
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
				__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
		return PAPI_EINVAL;
Packit Service a1973e
	}
Packit Service a1973e
}
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
#ifdef SYNTHETIC_EVENTS_SUPPORTED
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
__int_setup_synthetic_event( int code, hwd_control_state_t * ctrl, void *arg )
Packit Service a1973e
{
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	switch ( code ) {
Packit Service a1973e
	case SYNTHETIC_CYCLES_ELAPSED:
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
				__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
		return PAPI_OK;
Packit Service a1973e
	default:
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
		SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
				__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
		return PAPI_EINVAL;
Packit Service a1973e
	}
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
}
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
#ifdef SYNTHETIC_EVENTS_SUPPORTED
Packit Service a1973e
Packit Service a1973e
void
Packit Service a1973e
__int_walk_synthetic_events_action_count( void )
Packit Service a1973e
{
Packit Service a1973e
	int i = 0;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	/* Count all synthetic events in __int_syn_table, the last event is marked
Packit Service a1973e
	   with an event code of -1. */
Packit Service a1973e
	while ( __int_syn_table[i].code != -1 ) {
Packit Service a1973e
		__t2_store.syn_evt_count++;
Packit Service a1973e
		i++;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
}
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
#ifdef SYNTHETIC_EVENTS_SUPPORTED
Packit Service a1973e
Packit Service a1973e
void
Packit Service a1973e
__int_walk_synthetic_events_action_store( void )
Packit Service a1973e
{
Packit Service a1973e
	/* The first index of a synthetic event starts after last native event */
Packit Service a1973e
	int i = 0;
Packit Service a1973e
	int offset = _niagara2_vector.cmp_info.num_native_events + 1 -
Packit Service a1973e
		__t2_store.syn_evt_count;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	while ( i < __t2_store.syn_evt_count ) {
Packit Service a1973e
		__t2_ntv_events[i + offset] = papi_strdup( __int_syn_table[i].name );
Packit Service a1973e
		i++;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit Service a1973e
			__LINE__ );
Packit Service a1973e
#endif
Packit Service a1973e
}
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
papi_vector_t _niagara2_vector = {
Packit Service a1973e
/************* COMPONENT CAPABILITIES/INFORMATION/ETC ************************/
Packit Service a1973e
	.cmp_info = {
Packit Service a1973e
                                 .name = "solaris-niagara2",
Packit Service a1973e
                                 .description = "Solaris Counters",
Packit Service a1973e
				 .num_cntrs = MAX_COUNTERS,
Packit Service a1973e
				 .num_mpx_cntrs = MAX_COUNTERS,
Packit Service a1973e
				 .default_domain = PAPI_DOM_USER,
Packit Service a1973e
				 .available_domains = ( PAPI_DOM_USER | PAPI_DOM_KERNEL
Packit Service a1973e
										| PAPI_DOM_SUPERVISOR ),
Packit Service a1973e
				 .default_granularity = PAPI_GRN_THR,
Packit Service a1973e
				 .available_granularities = PAPI_GRN_THR,
Packit Service a1973e
				 .fast_real_timer = 1,
Packit Service a1973e
				 .fast_virtual_timer = 1,
Packit Service a1973e
				 .attach = 1,
Packit Service a1973e
				 .attach_must_ptrace = 1,
Packit Service a1973e
				 .hardware_intr = 1,
Packit Service a1973e
				 .hardware_intr_sig = SIGEMT,
Packit Service a1973e
				 .precise_intr = 1,
Packit Service a1973e
				 }
Packit Service a1973e
	,
Packit Service a1973e
/************* COMPONENT DATA STRUCTURE SIZES ********************************/
Packit Service a1973e
	.size = {
Packit Service a1973e
			 .context = sizeof ( hwd_context_t ),
Packit Service a1973e
			 .control_state = sizeof ( hwd_control_state_t ),
Packit Service a1973e
			 .reg_value = sizeof ( hwd_register_t ),
Packit Service a1973e
			 .reg_alloc = sizeof ( niagara2_reg_alloc_t ),
Packit Service a1973e
			 }
Packit Service a1973e
	,
Packit Service a1973e
/************* COMPONENT INTERFACE FUNCTIONS *********************************/
Packit Service a1973e
	.init_control_state = _niagara2_init_control_state,
Packit Service a1973e
	.start = _niagara2_start,
Packit Service a1973e
	.stop = _niagara2_stop,
Packit Service a1973e
	.read = _niagara2_read,
Packit Service a1973e
	.write = NULL,			 /* NOT IMPLEMENTED */
Packit Service a1973e
	.shutdown_thread = _niagara2_shutdown,
Packit Service a1973e
	.shutdown_component = _niagara2_shutdown_global,
Packit Service a1973e
	.ctl = _niagara2_ctl,
Packit Service a1973e
	.update_control_state = _niagara2_update_control_state,
Packit Service a1973e
	.set_domain = _niagara2_set_domain,
Packit Service a1973e
	.reset = _niagara2_reset,
Packit Service a1973e
	.set_overflow = _niagara2_set_overflow,
Packit Service a1973e
	.set_profile = _niagara2_set_profile,
Packit Service a1973e
	.stop_profiling = NULL,	 /* NOT IMPLEMENTED */
Packit Service a1973e
	.ntv_enum_events = _niagara2_ntv_enum_events,
Packit Service a1973e
	.ntv_name_to_code = NULL,	/* NOT IMPLEMENTED */
Packit Service a1973e
	.ntv_code_to_name = _niagara2_ntv_code_to_name,
Packit Service a1973e
	.ntv_code_to_descr = _niagara2_ntv_code_to_descr,
Packit Service a1973e
	.ntv_code_to_bits = _niagara2_ntv_code_to_bits,
Packit Service a1973e
	.init_component = _niagara2_init_component,
Packit Service a1973e
	.dispatch_timer = _niagara2_dispatch_timer,
Packit Service a1973e
};
Packit Service a1973e
Packit Service a1973e
papi_os_vector_t _papi_os_vector = {
Packit Service a1973e
	.get_memory_info = _niagara2_get_memory_info,
Packit Service a1973e
	.get_dmem_info   = _solaris_get_dmem_info,
Packit Service a1973e
Packit Service a1973e
	.get_real_usec =     _solaris_get_real_usec,
Packit Service a1973e
	.get_real_cycles =   _solaris_get_real_cycles,
Packit Service a1973e
	.get_virt_usec =     _solaris_get_virt_usec,
Packit Service a1973e
	.update_shlib_info = _solaris_update_shlib_info,
Packit Service a1973e
	.get_system_info =   _solaris_get_system_info,
Packit Service a1973e
};