Blame src/solaris-ultra.c

Packit Service a1973e
/* 
Packit Service a1973e
* File:    solaris-ultra.c
Packit Service a1973e
* Author:  Philip Mucci
Packit Service a1973e
*          mucci@cs.utk.edu
Packit Service a1973e
* Mods:    Kevin London
Packit Service a1973e
*          london@cs.utk.edu
Packit Service a1973e
* Mods:    Min Zhou
Packit Service a1973e
*          min@cs.utk.edu
Packit Service a1973e
* Mods:    Larry Meadows(helped us to build the native table dynamically) 
Packit Service a1973e
* Mods:    Brian Sheely
Packit Service a1973e
*          bsheely@eecs.utk.edu 
Packit Service a1973e
* Mods:    Vince Weaver
Packit Service a1973e
*          vweaver1@eecs.utk.edu 
Packit Service a1973e
*/
Packit Service a1973e
Packit Service a1973e
/* to understand this program, first you should read the user's manual
Packit Service a1973e
   about UltraSparc II and UltraSparc III, then the man pages
Packit Service a1973e
   about cpc_take_sample(cpc_event_t *event)
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 "papi_memory.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
#ifdef CPC_ULTRA3_I
Packit Service a1973e
#define LASTULTRA3 CPC_ULTRA3_I
Packit Service a1973e
#else
Packit Service a1973e
#define LASTULTRA3 CPC_ULTRA3_PLUS
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
#define MAX_ENAME 40
Packit Service a1973e
Packit Service a1973e
static void action( void *arg, int regno, const char *name, uint8_t bits );
Packit Service a1973e
Packit Service a1973e
/* Probably could dispense with this and just use native_table */
Packit Service a1973e
typedef struct ctr_info
Packit Service a1973e
{
Packit Service a1973e
	char *name;						   /* Counter name */
Packit Service a1973e
	int bits[2];					   /* bits for register */
Packit Service a1973e
	int bitmask;					   /* 1 = pic0; 2 = pic1; 3 = both */
Packit Service a1973e
} ctr_info_t;
Packit Service a1973e
Packit Service a1973e
typedef struct einfo
Packit Service a1973e
{
Packit Service a1973e
	unsigned int papi_event;
Packit Service a1973e
	char *event_str;
Packit Service a1973e
} einfo_t;
Packit Service a1973e
static einfo_t us3info[] = {
Packit Service a1973e
	{PAPI_FP_INS, "FA_pipe_completion+FM_pipe_completion"},
Packit Service a1973e
	{PAPI_FAD_INS, "FA_pipe_completion"},
Packit Service a1973e
	{PAPI_FML_INS, "FM_pipe_completion"},
Packit Service a1973e
	{PAPI_TLB_IM, "ITLB_miss"},
Packit Service a1973e
	{PAPI_TLB_DM, "DTLB_miss"},
Packit Service a1973e
	{PAPI_TOT_CYC, "Cycle_cnt"},
Packit Service a1973e
	{PAPI_TOT_IIS, "Instr_cnt"},
Packit Service a1973e
	{PAPI_TOT_INS, "Instr_cnt"},
Packit Service a1973e
	{PAPI_L2_TCM, "EC_misses"},
Packit Service a1973e
	{PAPI_L2_ICM, "EC_ic_miss"},
Packit Service a1973e
	{PAPI_L1_ICM, "IC_miss"},
Packit Service a1973e
	{PAPI_L1_LDM, "DC_rd_miss"},
Packit Service a1973e
	{PAPI_L1_STM, "DC_wr_miss"},
Packit Service a1973e
	{PAPI_L2_LDM, "EC_rd_miss"},
Packit Service a1973e
	{PAPI_BR_MSP, "IU_Stat_Br_miss_taken+IU_Stat_Br_miss_untaken"},
Packit Service a1973e
	{PAPI_L1_DCR, "DC_rd"},
Packit Service a1973e
	{PAPI_L1_DCW, "DC_wr"},
Packit Service a1973e
	{PAPI_L1_ICH, "IC_ref-IC_miss"},	/* Is this really hits only? */
Packit Service a1973e
	{PAPI_L1_ICA, "IC_ref"}, /* Ditto? */
Packit Service a1973e
	{PAPI_L2_TCH, "EC_ref-EC_misses"},
Packit Service a1973e
	{PAPI_L2_TCA, "EC_ref"},
Packit Service a1973e
};
Packit Service a1973e
Packit Service a1973e
static einfo_t us2info[] = {
Packit Service a1973e
	{PAPI_L1_ICM, "IC_ref-IC_hit"},
Packit Service a1973e
	{PAPI_L2_TCM, "EC_ref-EC_hit"},
Packit Service a1973e
	{PAPI_CA_SNP, "EC_snoop_cb"},
Packit Service a1973e
	{PAPI_CA_INV, "EC_snoop_inv"},
Packit Service a1973e
	{PAPI_L1_LDM, "DC_rd-DC_rd_hit"},
Packit Service a1973e
	{PAPI_L1_STM, "DC_wr-DC_wr_hit"},
Packit Service a1973e
	{PAPI_L2_LDM, "EC_rd_miss"},
Packit Service a1973e
	{PAPI_BR_MSP, "Dispatch0_mispred"},
Packit Service a1973e
	{PAPI_TOT_IIS, "Instr_cnt"},
Packit Service a1973e
	{PAPI_TOT_INS, "Instr_cnt"},
Packit Service a1973e
	{PAPI_LD_INS, "DC_rd"},
Packit Service a1973e
	{PAPI_SR_INS, "DC_wr"},
Packit Service a1973e
	{PAPI_TOT_CYC, "Cycle_cnt"},
Packit Service a1973e
	{PAPI_L1_DCR, "DC_rd"},
Packit Service a1973e
	{PAPI_L1_DCW, "DC_wr"},
Packit Service a1973e
	{PAPI_L1_ICH, "IC_hit"},
Packit Service a1973e
	{PAPI_L2_ICH, "EC_ic_hit"},
Packit Service a1973e
	{PAPI_L1_ICA, "IC_ref"},
Packit Service a1973e
	{PAPI_L2_TCH, "EC_hit"},
Packit Service a1973e
	{PAPI_L2_TCA, "EC_ref"},
Packit Service a1973e
};
Packit Service a1973e
Packit Service a1973e
papi_vector_t _solaris_vector;
Packit Service a1973e
Packit Service a1973e
static native_info_t *native_table;
Packit Service a1973e
static hwi_search_t *preset_table;
Packit Service a1973e
Packit Service a1973e
static struct ctr_info *ctrs;
Packit Service a1973e
static int nctrs;
Packit Service a1973e
Packit Service a1973e
static int build_tables( void );
Packit Service a1973e
static void add_preset( hwi_search_t * tab, int *np, einfo_t e );
Packit Service a1973e
Packit Service a1973e
/* Globals used to access the counter registers. */
Packit Service a1973e
Packit Service a1973e
static int cpuver;
Packit Service a1973e
static int pcr_shift[2];
Packit Service a1973e
Packit Service a1973e
hwi_search_t *preset_search_map;
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
static void
Packit Service a1973e
dump_cmd( papi_cpc_event_t * t )
Packit Service a1973e
{
Packit Service a1973e
	SUBDBG( "cpc_event_t.ce_cpuver %d\n", t->cmd.ce_cpuver );
Packit Service a1973e
	SUBDBG( "ce_tick %llu\n", t->cmd.ce_tick );
Packit Service a1973e
	SUBDBG( "ce_pic[0] %llu ce_pic[1] %llu\n", t->cmd.ce_pic[0],
Packit Service a1973e
			t->cmd.ce_pic[1] );
Packit Service a1973e
	SUBDBG( "ce_pcr %#llx\n", t->cmd.ce_pcr );
Packit Service a1973e
	SUBDBG( "flags %#x\n", t->flags );
Packit Service a1973e
}
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
static void
Packit Service a1973e
dispatch_emt( int signal, siginfo_t * sip, void *arg )
Packit Service a1973e
{
Packit Service a1973e
	int event_counter;
Packit Service a1973e
	_papi_hwi_context_t ctx;
Packit Service a1973e
	caddr_t address;
Packit Service a1973e
	ctx.si = sip;
Packit Service a1973e
	ctx.ucontext = arg;
Packit Service a1973e
	SUBDBG( "%d, %p, %p\n", signal, sip, arg );
Packit Service a1973e
Packit Service a1973e
	if ( sip->si_code == EMT_CPCOVF ) {
Packit Service a1973e
		papi_cpc_event_t *sample;
Packit Service a1973e
		EventSetInfo_t *ESI;
Packit Service a1973e
		ThreadInfo_t *thread = NULL;
Packit Service a1973e
		int t, overflow_vector, readvalue;
Packit Service a1973e
Packit Service a1973e
		thread = _papi_hwi_lookup_thread( 0 );
Packit Service a1973e
		ESI = ( EventSetInfo_t * ) thread->running_eventset;
Packit Service a1973e
		int cidx = ESI->CmpIdx;
Packit Service a1973e
Packit Service a1973e
		if ( ( ESI == NULL ) || ( ( ESI->state & PAPI_OVERFLOWING ) == 0 ) ) {
Packit Service a1973e
			OVFDBG( "Either no eventset or eventset not set to overflow.\n" );
Packit Service a1973e
			return;
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
		if ( ESI->master != thread ) {
Packit Service a1973e
			PAPIERROR
Packit Service a1973e
				( "eventset->thread %%lx vs. current thread %#lx mismatch",
Packit Service a1973e
				  ESI->master, thread );
Packit Service a1973e
			return;
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
		event_counter = ESI->overflow.event_counter;
Packit Service a1973e
		sample = &( ESI->ctl_state->counter_cmd );
Packit Service a1973e
Packit Service a1973e
		/* GROSS! This is a hack to 'push' the correct values 
Packit Service a1973e
		   back into the hardware, such that when PAPI handles
Packit Service a1973e
		   the overflow and reads the values, it gets the correct ones.
Packit Service a1973e
		 */
Packit Service a1973e
Packit Service a1973e
		/* Find which HW counter overflowed */
Packit Service a1973e
Packit Service a1973e
		if ( ESI->EventInfoArray[ESI->overflow.EventIndex[0]].pos[0] == 0 )
Packit Service a1973e
			t = 0;
Packit Service a1973e
		else
Packit Service a1973e
			t = 1;
Packit Service a1973e
Packit Service a1973e
		if ( cpc_take_sample( &sample->cmd ) == -1 )
Packit Service a1973e
			return;
Packit Service a1973e
		if ( event_counter == 1 ) {
Packit Service a1973e
			/* only one event is set to be the overflow monitor */
Packit Service a1973e
Packit Service a1973e
			/* generate the overflow vector */
Packit Service a1973e
			overflow_vector = 1 << t;
Packit Service a1973e
			/* reset the threshold */
Packit Service a1973e
			sample->cmd.ce_pic[t] = UINT64_MAX - ESI->overflow.threshold[0];
Packit Service a1973e
		} else {
Packit Service a1973e
			/* two events are set to be the overflow monitors */
Packit Service a1973e
			overflow_vector = 0;
Packit Service a1973e
			readvalue = sample->cmd.ce_pic[0];
Packit Service a1973e
			if ( readvalue >= 0 ) {
Packit Service a1973e
				/* the first counter overflowed */
Packit Service a1973e
Packit Service a1973e
				/* generate the overflow vector */
Packit Service a1973e
				overflow_vector = 1;
Packit Service a1973e
				/* reset the threshold */
Packit Service a1973e
				if ( t == 0 )
Packit Service a1973e
					sample->cmd.ce_pic[0] =
Packit Service a1973e
						UINT64_MAX - ESI->overflow.threshold[0];
Packit Service a1973e
				else
Packit Service a1973e
					sample->cmd.ce_pic[0] =
Packit Service a1973e
						UINT64_MAX - ESI->overflow.threshold[1];
Packit Service a1973e
			}
Packit Service a1973e
			readvalue = sample->cmd.ce_pic[1];
Packit Service a1973e
			if ( readvalue >= 0 ) {
Packit Service a1973e
				/* the second counter overflowed */
Packit Service a1973e
Packit Service a1973e
				/* generate the overflow vector */
Packit Service a1973e
				overflow_vector ^= 1 << 1;
Packit Service a1973e
				/* reset the threshold */
Packit Service a1973e
				if ( t == 0 )
Packit Service a1973e
					sample->cmd.ce_pic[1] =
Packit Service a1973e
						UINT64_MAX - ESI->overflow.threshold[1];
Packit Service a1973e
				else
Packit Service a1973e
					sample->cmd.ce_pic[1] =
Packit Service a1973e
						UINT64_MAX - ESI->overflow.threshold[0];
Packit Service a1973e
			}
Packit Service a1973e
			SUBDBG( "overflow_vector, = %d\n", overflow_vector );
Packit Service a1973e
			/* something is wrong here */
Packit Service a1973e
			if ( overflow_vector == 0 ) {
Packit Service a1973e
				PAPIERROR( "BUG! overflow_vector is 0, dropping interrupt" );
Packit Service a1973e
				return;
Packit Service a1973e
			}
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
		/* Call the regular overflow function in extras.c */
Packit Service a1973e
		if ( thread->running_eventset[cidx]->overflow.
Packit Service a1973e
			 flags & PAPI_OVERFLOW_FORCE_SW ) {
Packit Service a1973e
			address = GET_OVERFLOW_ADDRESS(ctx);
Packit Service a1973e
			_papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address, NULL,
Packit Service a1973e
												overflow_vector, 0, &thread,
Packit Service a1973e
												cidx );
Packit Service a1973e
		} else {
Packit Service a1973e
			PAPIERROR( "Additional implementation needed in dispatch_emt!" );
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
#if DEBUG
Packit Service a1973e
		dump_cmd( sample );
Packit Service a1973e
#endif
Packit Service a1973e
		/* push back the correct values and start counting again */
Packit Service a1973e
		if ( cpc_bind_event( &sample->cmd, sample->flags ) == -1 )
Packit Service a1973e
			return;
Packit Service a1973e
	} else {
Packit Service a1973e
		SUBDBG( "dispatch_emt() dropped, si_code = %d\n", sip->si_code );
Packit Service a1973e
		return;
Packit Service a1973e
	}
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
static int
Packit Service a1973e
scan_prtconf( char *cpuname, int len_cpuname, int *hz, int *ver )
Packit Service a1973e
{
Packit Service a1973e
	/* This code courtesy of our friends in Germany. Thanks Rudolph Berrendorf! */
Packit Service a1973e
	/* See the PCL home page for the German version of PAPI. */
Packit Service a1973e
	/* Modified by Nils Smeds, all new bugs are my fault */
Packit Service a1973e
	/*    The routine now looks for the first "Node" with the following: */
Packit Service a1973e
	/*           "device_type"     = 'cpu'                    */
Packit Service a1973e
	/*           "name"            = (Any value)              */
Packit Service a1973e
	/*           "sparc-version"   = (Any value)              */
Packit Service a1973e
	/*           "clock-frequency" = (Any value)              */
Packit Service a1973e
	int ihz, version;
Packit Service a1973e
	char line[256], cmd[80], name[256];
Packit Service a1973e
	FILE *f = NULL;
Packit Service a1973e
	char cmd_line[PAPI_HUGE_STR_LEN + PAPI_HUGE_STR_LEN], fname[L_tmpnam];
Packit Service a1973e
	unsigned int matched;
Packit Service a1973e
Packit Service a1973e
	/*??? system call takes very long */
Packit Service a1973e
	/* get system configuration and put output into file */
Packit Service a1973e
Packit Service a1973e
	tmpnam( fname );
Packit Service a1973e
	SUBDBG( "Temporary name %s\n", fname );
Packit Service a1973e
Packit Service a1973e
	sprintf( cmd_line, "/usr/sbin/prtconf -vp > %s", fname );
Packit Service a1973e
	SUBDBG( "Executing %s\n", cmd_line );
Packit Service a1973e
	if ( system( cmd_line ) == -1 ) {
Packit Service a1973e
		remove( fname );
Packit Service a1973e
		return -1;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	f = fopen( fname, "r" );
Packit Service a1973e
	/* open output file */
Packit Service a1973e
	if ( f == NULL ) {
Packit Service a1973e
		remove( fname );
Packit Service a1973e
		return -1;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	/* ignore all lines until we reach something with a sparc line */
Packit Service a1973e
	matched = 0x0;
Packit Service a1973e
	ihz = -1;
Packit Service a1973e
	while ( fgets( line, 256, f ) != NULL ) {
Packit Service a1973e
		/*SUBDBG(">>> %s",line); */
Packit Service a1973e
		if ( ( sscanf( line, "%s", cmd ) == 1 )
Packit Service a1973e
			 && strstr( line, "Node 0x" ) ) {
Packit Service a1973e
			matched = 0x0;
Packit Service a1973e
			/*SUBDBG("Found 'Node' -- search reset. (%#2.2x)\n",matched); */
Packit Service a1973e
		} else {
Packit Service a1973e
			if ( strstr( cmd, "device_type:" ) && strstr( line, "'cpu'" ) ) {
Packit Service a1973e
				matched |= 0x1;
Packit Service a1973e
				SUBDBG( "Found 'cpu'. (%#2.2x)\n", matched );
Packit Service a1973e
			} else if ( !strcmp( cmd, "sparc-version:" ) &&
Packit Service a1973e
						( sscanf( line, "%s %#x", cmd, &version ) == 2 ) ) {
Packit Service a1973e
				matched |= 0x2;
Packit Service a1973e
				SUBDBG( "Found version=%d. (%#2.2x)\n", version, matched );
Packit Service a1973e
			} else if ( !strcmp( cmd, "clock-frequency:" ) &&
Packit Service a1973e
						( sscanf( line, "%s %#x", cmd, &ihz ) == 2 ) ) {
Packit Service a1973e
				matched |= 0x4;
Packit Service a1973e
				SUBDBG( "Found ihz=%d. (%#2.2x)\n", ihz, matched );
Packit Service a1973e
			} else if ( !strcmp( cmd, "name:" ) &&
Packit Service a1973e
						( sscanf( line, "%s %s", cmd, name ) == 2 ) ) {
Packit Service a1973e
				matched |= 0x8;
Packit Service a1973e
				SUBDBG( "Found name: %s. (%#2.2x)\n", name, matched );
Packit Service a1973e
			}
Packit Service a1973e
		}
Packit Service a1973e
		if ( ( matched & 0xF ) == 0xF )
Packit Service a1973e
			break;
Packit Service a1973e
	}
Packit Service a1973e
	SUBDBG( "Parsing found name=%s, speed=%dHz, version=%d\n", name, ihz,
Packit Service a1973e
			version );
Packit Service a1973e
Packit Service a1973e
	if ( matched ^ 0x0F )
Packit Service a1973e
		ihz = -1;
Packit Service a1973e
	else {
Packit Service a1973e
		*hz = ( float ) ihz;
Packit Service a1973e
		*ver = version;
Packit Service a1973e
		strncpy( cpuname, name, len_cpuname );
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	return ihz;
Packit Service a1973e
Packit Service a1973e
	/* End stolen code */
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_ultra_set_domain( hwd_control_state_t * this_state, int domain )
Packit Service a1973e
{
Packit Service a1973e
	papi_cpc_event_t *command = &this_state->counter_cmd;
Packit Service a1973e
	cpc_event_t *event = &command->cmd;
Packit Service a1973e
	uint64_t pcr = event->ce_pcr;
Packit Service a1973e
	int did = 0;
Packit Service a1973e
Packit Service a1973e
	pcr = pcr | 0x7;
Packit Service a1973e
	pcr = pcr ^ 0x7;
Packit Service a1973e
Packit Service a1973e
	if ( domain & PAPI_DOM_USER ) {
Packit Service a1973e
		pcr = pcr | 1 << CPC_ULTRA_PCR_USR;
Packit Service a1973e
		did = 1;
Packit Service a1973e
	}
Packit Service a1973e
	if ( domain & PAPI_DOM_KERNEL ) {
Packit Service a1973e
		pcr = pcr | 1 << CPC_ULTRA_PCR_SYS;
Packit Service a1973e
		did = 1;
Packit Service a1973e
	}
Packit Service a1973e
	/* DOMAIN ERROR */
Packit Service a1973e
	if ( !did ) {
Packit Service a1973e
		return ( PAPI_EINVAL );
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	event->ce_pcr = pcr;
Packit Service a1973e
Packit Service a1973e
	return ( PAPI_OK );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
static int
Packit Service a1973e
set_granularity( hwd_control_state_t * this_state, int domain )
Packit Service a1973e
{
Packit Service a1973e
	switch ( domain ) {
Packit Service a1973e
	case PAPI_GRN_PROCG:
Packit Service a1973e
	case PAPI_GRN_SYS:
Packit Service a1973e
	case PAPI_GRN_SYS_CPU:
Packit Service a1973e
	case PAPI_GRN_PROC:
Packit Service a1973e
		return PAPI_ECMP;
Packit Service a1973e
	case PAPI_GRN_THR:
Packit Service a1973e
		break;
Packit Service a1973e
	default:
Packit Service a1973e
		return ( PAPI_EINVAL );
Packit Service a1973e
	}
Packit Service a1973e
	return ( PAPI_OK );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
/* Utility functions */
Packit Service a1973e
Packit Service a1973e
/* This is a wrapper arount fprintf(stderr,...) for cpc_walk_events() */
Packit Service a1973e
void
Packit Service a1973e
print_walk_names( void *arg, int regno, const char *name, uint8_t bits )
Packit Service a1973e
{
Packit Service a1973e
	SUBDBG( arg, regno, name, bits );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
static int
Packit Service a1973e
build_tables( void )
Packit Service a1973e
{
Packit Service a1973e
	int i;
Packit Service a1973e
	int regno;
Packit Service a1973e
	int npic;
Packit Service a1973e
	einfo_t *ep;
Packit Service a1973e
	int n;
Packit Service a1973e
	int npresets;
Packit Service a1973e
	npic = cpc_getnpic( cpuver );
Packit Service a1973e
	nctrs = 0;
Packit Service a1973e
	for ( regno = 0; regno < npic; ++regno ) {
Packit Service a1973e
		cpc_walk_names( cpuver, regno, 0, action );
Packit Service a1973e
	}
Packit Service a1973e
	SUBDBG( "%d counters\n", nctrs );
Packit Service a1973e
	if ( ( ctrs = papi_malloc( nctrs * sizeof ( struct ctr_info ) ) ) == 0 ) {
Packit Service a1973e
		return PAPI_ENOMEM;
Packit Service a1973e
	}
Packit Service a1973e
	nctrs = 0;
Packit Service a1973e
	for ( regno = 0; regno < npic; ++regno ) {
Packit Service a1973e
		cpc_walk_names( cpuver, regno, ( void * ) 1, action );
Packit Service a1973e
	}
Packit Service a1973e
	SUBDBG( "%d counters\n", nctrs );
Packit Service a1973e
#if DEBUG
Packit Service a1973e
	if ( ISLEVEL( DEBUG_SUBSTRATE ) ) {
Packit Service a1973e
		for ( i = 0; i < nctrs; ++i ) {
Packit Service a1973e
			SUBDBG( "%s: bits (%#x,%#x) pics %#x\n", ctrs[i].name, ctrs[i].bits[0],
Packit Service a1973e
					ctrs[i].bits[1], ctrs[i].bitmask );
Packit Service a1973e
		}
Packit Service a1973e
	}
Packit Service a1973e
#endif
Packit Service a1973e
	/* Build the native event table */
Packit Service a1973e
	if ( ( native_table =
Packit Service a1973e
		   papi_malloc( nctrs * sizeof ( native_info_t ) ) ) == 0 ) {
Packit Service a1973e
		papi_free( ctrs );
Packit Service a1973e
		return PAPI_ENOMEM;
Packit Service a1973e
	}
Packit Service a1973e
	for ( i = 0; i < nctrs; ++i ) {
Packit Service a1973e
		native_table[i].name[39] = 0;
Packit Service a1973e
		strncpy( native_table[i].name, ctrs[i].name, 39 );
Packit Service a1973e
		if ( ctrs[i].bitmask & 1 )
Packit Service a1973e
			native_table[i].encoding[0] = ctrs[i].bits[0];
Packit Service a1973e
		else
Packit Service a1973e
			native_table[i].encoding[0] = -1;
Packit Service a1973e
		if ( ctrs[i].bitmask & 2 )
Packit Service a1973e
			native_table[i].encoding[1] = ctrs[i].bits[1];
Packit Service a1973e
		else
Packit Service a1973e
			native_table[i].encoding[1] = -1;
Packit Service a1973e
	}
Packit Service a1973e
	papi_free( ctrs );
Packit Service a1973e
Packit Service a1973e
	/* Build the preset table */
Packit Service a1973e
	if ( cpuver <= CPC_ULTRA2 ) {
Packit Service a1973e
		n = sizeof ( us2info ) / sizeof ( einfo_t );
Packit Service a1973e
		ep = us2info;
Packit Service a1973e
	} else if ( cpuver <= LASTULTRA3 ) {
Packit Service a1973e
		n = sizeof ( us3info ) / sizeof ( einfo_t );
Packit Service a1973e
		ep = us3info;
Packit Service a1973e
	} else
Packit Service a1973e
		return PAPI_ECMP;
Packit Service a1973e
	preset_table = papi_malloc( ( n + 1 ) * sizeof ( hwi_search_t ) );
Packit Service a1973e
	npresets = 0;
Packit Service a1973e
	for ( i = 0; i < n; ++i ) {
Packit Service a1973e
		add_preset( preset_table, &npresets, ep[i] );
Packit Service a1973e
	}
Packit Service a1973e
	memset( &preset_table[npresets], 0, sizeof ( hwi_search_t ) );
Packit Service a1973e
Packit Service a1973e
#ifdef DEBUG
Packit Service a1973e
	if ( ISLEVEL( DEBUG_SUBSTRATE ) ) {
Packit Service a1973e
		SUBDBG( "Native table: %d\n", nctrs );
Packit Service a1973e
		for ( i = 0; i < nctrs; ++i ) {
Packit Service a1973e
			SUBDBG( "%40s: %8x %8x\n", native_table[i].name,
Packit Service a1973e
					native_table[i].encoding[0], native_table[i].encoding[1] );
Packit Service a1973e
		}
Packit Service a1973e
		SUBDBG( "\nPreset table: %d\n", npresets );
Packit Service a1973e
		for ( i = 0; preset_table[i].event_code != 0; ++i ) {
Packit Service a1973e
			SUBDBG( "%8x: op %2d e0 %8x e1 %8x\n",
Packit Service a1973e
					preset_table[i].event_code,
Packit Service a1973e
					preset_table[i].data.derived,
Packit Service a1973e
					preset_table[i].data.native[0],
Packit Service a1973e
					preset_table[i].data.native[1] );
Packit Service a1973e
		}
Packit Service a1973e
	}
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	_solaris_vector.cmp_info.num_native_events = nctrs;
Packit Service a1973e
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
static int
Packit Service a1973e
srch_event( char *e1 )
Packit Service a1973e
{
Packit Service a1973e
	int i;
Packit Service a1973e
Packit Service a1973e
	for ( i = 0; i < nctrs; ++i ) {
Packit Service a1973e
		if ( strcmp( e1, native_table[i].name ) == 0 )
Packit Service a1973e
			break;
Packit Service a1973e
	}
Packit Service a1973e
	if ( i >= nctrs )
Packit Service a1973e
		return -1;
Packit Service a1973e
	return i;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
/* we should read from the CSV file and make this all unnecessary */
Packit Service a1973e
Packit Service a1973e
static void
Packit Service a1973e
add_preset( hwi_search_t * tab, int *np, einfo_t e )
Packit Service a1973e
{
Packit Service a1973e
	/* Parse the event info string and build the PAPI preset.
Packit Service a1973e
	 * If parse fails, just return, otherwise increment the table
Packit Service a1973e
	 * size. We assume that the table is big enough.
Packit Service a1973e
	 */
Packit Service a1973e
	char *p;
Packit Service a1973e
	char *q;
Packit Service a1973e
	char op;
Packit Service a1973e
	char e1[MAX_ENAME], e2[MAX_ENAME];
Packit Service a1973e
	int i;
Packit Service a1973e
	int ne;
Packit Service a1973e
	int ne2;
Packit Service a1973e
Packit Service a1973e
	p = e.event_str;
Packit Service a1973e
	/* Assume p is the name of a native event, the sum of two
Packit Service a1973e
	 * native events, or the difference of two native events.
Packit Service a1973e
	 * This could be extended with a real parser (hint).
Packit Service a1973e
	 */
Packit Service a1973e
	while ( isspace( *p ) )
Packit Service a1973e
		++p;
Packit Service a1973e
	q = p;
Packit Service a1973e
	i = 0;
Packit Service a1973e
	while ( isalnum( *p ) || ( *p == '_' ) ) {
Packit Service a1973e
		if ( i >= MAX_ENAME - 1 )
Packit Service a1973e
			break;
Packit Service a1973e
		e1[i] = *p++;
Packit Service a1973e
		++i;
Packit Service a1973e
	}
Packit Service a1973e
	e1[i] = 0;
Packit Service a1973e
	if ( *p == '+' || *p == '-' )
Packit Service a1973e
		op = *p++;
Packit Service a1973e
	else
Packit Service a1973e
		op = 0;
Packit Service a1973e
	while ( isspace( *p ) )
Packit Service a1973e
		++p;
Packit Service a1973e
	q = p;
Packit Service a1973e
	i = 0;
Packit Service a1973e
	while ( isalnum( *p ) || ( *p == '_' ) ) {
Packit Service a1973e
		if ( i >= MAX_ENAME - 1 )
Packit Service a1973e
			break;
Packit Service a1973e
		e2[i] = *p++;
Packit Service a1973e
		++i;
Packit Service a1973e
	}
Packit Service a1973e
	e2[i] = 0;
Packit Service a1973e
Packit Service a1973e
	if ( e2[0] == 0 && e1[0] == 0 ) {
Packit Service a1973e
		return;
Packit Service a1973e
	}
Packit Service a1973e
	if ( e2[0] == 0 || op == 0 ) {
Packit Service a1973e
		ne = srch_event( e1 );
Packit Service a1973e
		if ( ne == -1 )
Packit Service a1973e
			return;
Packit Service a1973e
		tab[*np].event_code = e.papi_event;
Packit Service a1973e
		tab[*np].data.derived = 0;
Packit Service a1973e
		tab[*np].data.native[0] = PAPI_NATIVE_MASK | ne;
Packit Service a1973e
		tab[*np].data.native[1] = PAPI_NULL;
Packit Service a1973e
		memset( tab[*np].data.operation, 0,
Packit Service a1973e
				sizeof ( tab[*np].data.operation ) );
Packit Service a1973e
		++*np;
Packit Service a1973e
		return;
Packit Service a1973e
	}
Packit Service a1973e
	ne = srch_event( e1 );
Packit Service a1973e
	ne2 = srch_event( e2 );
Packit Service a1973e
	if ( ne == -1 || ne2 == -1 )
Packit Service a1973e
		return;
Packit Service a1973e
	tab[*np].event_code = e.papi_event;
Packit Service a1973e
	tab[*np].data.derived = ( op == '-' ) ? DERIVED_SUB : DERIVED_ADD;
Packit Service a1973e
	tab[*np].data.native[0] = PAPI_NATIVE_MASK | ne;
Packit Service a1973e
	tab[*np].data.native[1] = PAPI_NATIVE_MASK | ne2;
Packit Service a1973e
	tab[*np].data.native[2] = PAPI_NULL;
Packit Service a1973e
	memset( tab[*np].data.operation, 0, sizeof ( tab[*np].data.operation ) );
Packit Service a1973e
	++*np;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
void
Packit Service a1973e
action( void *arg, int regno, const char *name, uint8_t bits )
Packit Service a1973e
{
Packit Service a1973e
	int i;
Packit Service a1973e
Packit Service a1973e
	if ( arg == 0 ) {
Packit Service a1973e
		++nctrs;
Packit Service a1973e
		return;
Packit Service a1973e
	}
Packit Service a1973e
	assert( regno == 0 || regno == 1 );
Packit Service a1973e
	for ( i = 0; i < nctrs; ++i ) {
Packit Service a1973e
		if ( strcmp( ctrs[i].name, name ) == 0 ) {
Packit Service a1973e
			ctrs[i].bits[regno] = bits;
Packit Service a1973e
			ctrs[i].bitmask |= ( 1 << regno );
Packit Service a1973e
			return;
Packit Service a1973e
		}
Packit Service a1973e
	}
Packit Service a1973e
	memset( &ctrs[i], 0, sizeof ( ctrs[i] ) );
Packit Service a1973e
	ctrs[i].name = papi_strdup( name );
Packit Service a1973e
	ctrs[i].bits[regno] = bits;
Packit Service a1973e
	ctrs[i].bitmask = ( 1 << regno );
Packit Service a1973e
	++nctrs;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
/* This function should tell your kernel extension that your children
Packit Service a1973e
   inherit performance register information and propagate the values up
Packit Service a1973e
   upon child exit and parent wait. */
Packit Service a1973e
Packit Service a1973e
static int
Packit Service a1973e
set_inherit( EventSetInfo_t * global, int arg )
Packit Service a1973e
{
Packit Service a1973e
	return PAPI_ECMP;
Packit Service a1973e
Packit Service a1973e
/*
Packit Service a1973e
  hwd_control_state_t *machdep = (hwd_control_state_t *)global->machdep;
Packit Service a1973e
  papi_cpc_event_t *command= &machdep->counter_cmd;
Packit Service a1973e
Packit Service a1973e
  return(PAPI_EINVAL);
Packit Service a1973e
*/
Packit Service a1973e
Packit Service a1973e
#if 0
Packit Service a1973e
	if ( arg == 0 ) {
Packit Service a1973e
		if ( command->flags & CPC_BIND_LWP_INHERIT )
Packit Service a1973e
			command->flags = command->flags ^ CPC_BIND_LWP_INHERIT;
Packit Service a1973e
	} else if ( arg == 1 ) {
Packit Service a1973e
		command->flags = command->flags | CPC_BIND_LWP_INHERIT;
Packit Service a1973e
	} else
Packit Service a1973e
		return ( PAPI_EINVAL );
Packit Service a1973e
Packit Service a1973e
	return ( PAPI_OK );
Packit Service a1973e
#endif
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
static int
Packit Service a1973e
set_default_domain( hwd_control_state_t * ctrl_state, int domain )
Packit Service a1973e
{
Packit Service a1973e
	/* This doesn't exist on this platform */
Packit Service a1973e
Packit Service a1973e
	if ( domain == PAPI_DOM_OTHER )
Packit Service a1973e
		return ( PAPI_EINVAL );
Packit Service a1973e
Packit Service a1973e
	return ( _ultra_set_domain( ctrl_state, domain ) );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
static int
Packit Service a1973e
set_default_granularity( hwd_control_state_t * current_state, int granularity )
Packit Service a1973e
{
Packit Service a1973e
	return ( set_granularity( current_state, granularity ) );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
rwlock_t lock[PAPI_MAX_LOCK];
Packit Service a1973e
Packit Service a1973e
static void
Packit Service a1973e
lock_init( void )
Packit Service a1973e
{
Packit Service a1973e
	memset( lock, 0x0, sizeof ( rwlock_t ) * PAPI_MAX_LOCK );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_ultra_hwd_shutdown_component( void )
Packit Service a1973e
{
Packit Service a1973e
	( void ) cpc_rele(  );
Packit Service a1973e
	return ( PAPI_OK );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_ultra_hwd_init_component( int cidx )
Packit Service a1973e
{
Packit Service a1973e
	int retval;
Packit Service a1973e
 /* retval = _papi_hwi_setup_vector_table(vtable, _solaris_ultra_table);
Packit Service a1973e
	if ( retval != PAPI_OK ) return(retval); */
Packit Service a1973e
Packit Service a1973e
	/* Fill in what we can of the papi_system_info. */
Packit Service a1973e
	retval = _solaris_get_system_info( &_papi_hwi_system_info );
Packit Service a1973e
	if ( retval )
Packit Service a1973e
		return ( retval );
Packit Service a1973e
Packit Service a1973e
	/* Setup memory info */
Packit Service a1973e
        retval = _papi_os_vector.get_memory_info( &_papi_hwi_system_info.hw_info,
Packit Service a1973e
				     0 );
Packit Service a1973e
        if ( retval )
Packit Service a1973e
	  return ( retval );
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
	lock_init(  );
Packit Service a1973e
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
	return ( PAPI_OK );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
/* reset the hardware counter */
Packit Service a1973e
int
Packit Service a1973e
_ultra_hwd_reset( hwd_context_t * ctx, hwd_control_state_t * ctrl )
Packit Service a1973e
{
Packit Service a1973e
	int retval;
Packit Service a1973e
Packit Service a1973e
	/* reset the hardware counter */
Packit Service a1973e
	ctrl->counter_cmd.cmd.ce_pic[0] = 0;
Packit Service a1973e
	ctrl->counter_cmd.cmd.ce_pic[1] = 0;
Packit Service a1973e
	/* let's rock and roll */
Packit Service a1973e
	retval = cpc_bind_event( &ctrl->counter_cmd.cmd, ctrl->counter_cmd.flags );
Packit Service a1973e
	if ( retval == -1 )
Packit Service a1973e
		return ( PAPI_ESYS );
Packit Service a1973e
Packit Service a1973e
	return ( PAPI_OK );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_ultra_hwd_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 retval;
Packit Service a1973e
Packit Service a1973e
	retval = cpc_take_sample( &ctrl->counter_cmd.cmd );
Packit Service a1973e
	if ( retval == -1 )
Packit Service a1973e
		return ( PAPI_ESYS );
Packit Service a1973e
Packit Service a1973e
	*events = ( long long * ) ctrl->counter_cmd.cmd.ce_pic;
Packit Service a1973e
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_ultra_hwd_ctl( hwd_context_t * ctx, int code, _papi_int_option_t * option )
Packit Service a1973e
{
Packit Service a1973e
Packit Service a1973e
	switch ( code ) {
Packit Service a1973e
	case PAPI_DEFDOM:
Packit Service a1973e
		return ( set_default_domain
Packit Service a1973e
				 ( option->domain.ESI->ctl_state, option->domain.domain ) );
Packit Service a1973e
	case PAPI_DOMAIN:
Packit Service a1973e
		return ( _ultra_set_domain
Packit Service a1973e
				 ( option->domain.ESI->ctl_state, option->domain.domain ) );
Packit Service a1973e
	case PAPI_DEFGRN:
Packit Service a1973e
		return ( set_default_granularity
Packit Service a1973e
				 ( option->domain.ESI->ctl_state,
Packit Service a1973e
				   option->granularity.granularity ) );
Packit Service a1973e
	case PAPI_GRANUL:
Packit Service a1973e
		return ( set_granularity
Packit Service a1973e
				 ( option->granularity.ESI->ctl_state,
Packit Service a1973e
				   option->granularity.granularity ) );
Packit Service a1973e
	default:
Packit Service a1973e
		return ( PAPI_EINVAL );
Packit Service a1973e
	}
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
void
Packit Service a1973e
_ultra_hwd_dispatch_timer( int signal, siginfo_t * si, void *context )
Packit Service a1973e
{
Packit Service a1973e
Packit Service a1973e
  _papi_hwi_context_t ctx;
Packit Service a1973e
  ThreadInfo_t *master = NULL;
Packit Service a1973e
  int isHardware = 0;
Packit Service a1973e
  caddr_t address;
Packit Service a1973e
  int cidx = _solaris_vector.cmp_info.CmpIdx;
Packit Service a1973e
Packit Service a1973e
  ctx.si = si;
Packit Service a1973e
  ctx.ucontext = ( ucontext_t * ) context;
Packit Service a1973e
Packit Service a1973e
  address = GET_OVERFLOW_ADDRESS( ctx );
Packit Service a1973e
  _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address, &isHardware,
Packit Service a1973e
				      0, 0, &master, _solaris_vector.cmp_info.CmpIdx );
Packit Service a1973e
Packit Service a1973e
  /* We are done, resume interrupting counters */
Packit Service a1973e
  if ( isHardware ) {
Packit Service a1973e
    //    errno = vperfctr_iresume( master->context[cidx]->perfctr );
Packit Service a1973e
    //if ( errno < 0 ) {
Packit Service a1973e
    //  PAPIERROR( "vperfctr_iresume errno %d", errno );
Packit Service a1973e
    //}
Packit Service a1973e
  }
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
#if 0
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
        _papi_hwi_context_t ctx;
Packit Service a1973e
	caddr_t address;
Packit Service a1973e
	int cidx = _solaris_vector.cmp_info.CmpIdx;
Packit Service a1973e
Packit Service a1973e
        ctx.si = si;
Packit Service a1973e
        ctx.ucontext = ( hwd_ucontext_t * ) info;
Packit Service a1973e
Packit Service a1973e
	thread = _papi_hwi_lookup_thread( 0 );
Packit Service a1973e
Packit Service a1973e
	if ( thread == NULL ) {
Packit Service a1973e
		PAPIERROR( "thread == NULL in _papi_hwd_dispatch_timer");
Packit Service a1973e
		return;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
        ESI = ( EventSetInfo_t * ) thread->running_eventset[cidx];
Packit Service a1973e
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
Packit Service a1973e
	  if ( ESI == NULL )
Packit Service a1973e
	     PAPIERROR( "ESI is NULL\n");
Packit Service a1973e
Packit Service a1973e
	  if ( ESI->master != thread )
Packit Service a1973e
	     PAPIERROR( "Thread mismatch, ESI->master=%#x thread=%#x\n",
Packit Service a1973e
		        ESI->master, thread );
Packit Service a1973e
Packit Service a1973e
	  if ( ESI->ctl_state == NULL )
Packit Service a1973e
	     PAPIERROR( "Counter state invalid\n");
Packit Service a1973e
Packit Service a1973e
	  if ( ( ( ESI->state & PAPI_OVERFLOWING ) == 0 ) )
Packit Service a1973e
	    PAPIERROR( "Overflow flag missing");
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	ctrl = ESI->ctl_state;
Packit Service a1973e
Packit Service a1973e
	if ( thread->running_eventset[cidx]->overflow.flags & PAPI_OVERFLOW_FORCE_SW ) {
Packit Service a1973e
		address = GET_OVERFLOW_ADDRESS( ctx );
Packit Service a1973e
		_papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address, NULL, 0,
Packit Service a1973e
											0, &thread, cidx );
Packit Service a1973e
       } else {
Packit Service a1973e
	     PAPIERROR ( "Need to implement additional code in _papi_hwd_dispatch_timer!" );
Packit Service a1973e
       }
Packit Service a1973e
#endif
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_ultra_hwd_set_overflow( EventSetInfo_t * ESI, int EventIndex, int threshold )
Packit Service a1973e
{
Packit Service a1973e
	hwd_control_state_t *this_state = ESI->ctl_state;
Packit Service a1973e
	papi_cpc_event_t *arg = &this_state->counter_cmd;
Packit Service a1973e
	int hwcntr;
Packit Service a1973e
Packit Service a1973e
	if ( threshold == 0 ) {
Packit Service a1973e
		if ( this_state->overflow_num == 1 ) {
Packit Service a1973e
			arg->flags ^= CPC_BIND_EMT_OVF;
Packit Service a1973e
			if ( sigaction
Packit Service a1973e
				 ( _solaris_vector.cmp_info.hardware_intr_sig, NULL,
Packit Service a1973e
				   NULL ) == -1 )
Packit Service a1973e
				return ( PAPI_ESYS );
Packit Service a1973e
			this_state->overflow_num = 0;
Packit Service a1973e
		} else
Packit Service a1973e
			this_state->overflow_num--;
Packit Service a1973e
Packit Service a1973e
	} else {
Packit Service a1973e
		struct sigaction act;
Packit Service a1973e
		/* increase the counter for overflow events */
Packit Service a1973e
		this_state->overflow_num++;
Packit Service a1973e
Packit Service a1973e
		act.sa_sigaction = dispatch_emt;
Packit Service a1973e
		memset( &act.sa_mask, 0x0, sizeof ( act.sa_mask ) );
Packit Service a1973e
		act.sa_flags = SA_RESTART | SA_SIGINFO;
Packit Service a1973e
		if ( sigaction
Packit Service a1973e
			 ( _solaris_vector.cmp_info.hardware_intr_sig, &act,
Packit Service a1973e
			   NULL ) == -1 )
Packit Service a1973e
			return ( PAPI_ESYS );
Packit Service a1973e
Packit Service a1973e
		arg->flags |= CPC_BIND_EMT_OVF;
Packit Service a1973e
		hwcntr = ESI->EventInfoArray[EventIndex].pos[0];
Packit Service a1973e
		if ( hwcntr == 0 )
Packit Service a1973e
			arg->cmd.ce_pic[0] = UINT64_MAX - ( uint64_t ) threshold;
Packit Service a1973e
		else if ( hwcntr == 1 )
Packit Service a1973e
			arg->cmd.ce_pic[1] = UINT64_MAX - ( uint64_t ) threshold;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	return ( PAPI_OK );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
_ultra_shutdown( hwd_context_t * ctx )
Packit Service a1973e
{
Packit Service a1973e
Packit Service a1973e
  return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
/*
Packit Service a1973e
int _papi_hwd_stop_profiling(ThreadInfo_t * master, EventSetInfo_t * ESI)
Packit Service a1973e
{
Packit Service a1973e
   ESI->profile.overflowcount = 0;
Packit Service a1973e
   return (PAPI_OK);
Packit Service a1973e
}
Packit Service a1973e
*/
Packit Service a1973e
Packit Service a1973e
void *
Packit Service a1973e
_ultra_hwd_get_overflow_address( void *context )
Packit Service a1973e
{
Packit Service a1973e
	void *location;
Packit Service a1973e
	ucontext_t *info = ( ucontext_t * ) context;
Packit Service a1973e
	location = ( void * ) info->uc_mcontext.gregs[REG_PC];
Packit Service a1973e
Packit Service a1973e
	return ( location );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_ultra_hwd_start( hwd_context_t * ctx, hwd_control_state_t * ctrl )
Packit Service a1973e
{
Packit Service a1973e
	int retval;
Packit Service a1973e
Packit Service a1973e
	/* reset the hardware counter */
Packit Service a1973e
	if ( ctrl->overflow_num == 0 ) {
Packit Service a1973e
		ctrl->counter_cmd.cmd.ce_pic[0] = 0;
Packit Service a1973e
		ctrl->counter_cmd.cmd.ce_pic[1] = 0;
Packit Service a1973e
	}
Packit Service a1973e
	/* let's rock and roll */
Packit Service a1973e
	retval = cpc_bind_event( &ctrl->counter_cmd.cmd, ctrl->counter_cmd.flags );
Packit Service a1973e
	if ( retval == -1 )
Packit Service a1973e
		return ( PAPI_ESYS );
Packit Service a1973e
Packit Service a1973e
	return ( PAPI_OK );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_ultra_hwd_stop( hwd_context_t * ctx, hwd_control_state_t * ctrl )
Packit Service a1973e
{
Packit Service a1973e
	cpc_bind_event( NULL, 0 );
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_ultra_hwd_remove_event( hwd_register_map_t * chosen,
Packit Service a1973e
						unsigned int hardware_index, hwd_control_state_t * out )
Packit Service a1973e
{
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_ultra_hwd_encode_native( char *name, int *code )
Packit Service a1973e
{
Packit Service a1973e
	return ( PAPI_OK );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_ultra_hwd_ntv_enum_events( unsigned int *EventCode, int modifier )
Packit Service a1973e
{
Packit Service a1973e
	int index = *EventCode & PAPI_NATIVE_AND_MASK;
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
	   return PAPI_OK;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	if ( cpuver <= CPC_ULTRA2 ) {
Packit Service a1973e
		if ( index < MAX_NATIVE_EVENT_USII - 1 ) {
Packit Service a1973e
			*EventCode = *EventCode + 1;
Packit Service a1973e
			return ( PAPI_OK );
Packit Service a1973e
		} else
Packit Service a1973e
			return ( PAPI_ENOEVNT );
Packit Service a1973e
	} else if ( cpuver <= LASTULTRA3 ) {
Packit Service a1973e
		if ( index < MAX_NATIVE_EVENT - 1 ) {
Packit Service a1973e
			*EventCode = *EventCode + 1;
Packit Service a1973e
			return ( PAPI_OK );
Packit Service a1973e
		} else
Packit Service a1973e
			return ( PAPI_ENOEVNT );
Packit Service a1973e
	};
Packit Service a1973e
	return ( PAPI_ENOEVNT );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_ultra_hwd_ntv_code_to_name( unsigned int EventCode, char *ntv_name, int len )
Packit Service a1973e
{
Packit Service a1973e
Packit Service a1973e
        int event_code = EventCode & PAPI_NATIVE_AND_MASK;
Packit Service a1973e
Packit Service a1973e
	if ( event_code >= 0 && event_code < nctrs ) {
Packit Service a1973e
	  strlcpy( ntv_name, native_table[event_code].name, len );
Packit Service a1973e
	  return PAPI_OK;
Packit Service a1973e
	}
Packit Service a1973e
	return PAPI_ENOEVNT;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_ultra_hwd_ntv_code_to_descr( unsigned int EventCode, char *hwd_descr, int len )
Packit Service a1973e
{
Packit Service a1973e
	return ( _ultra_hwd_ntv_code_to_name( EventCode, hwd_descr, len ) );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
static void
Packit Service a1973e
copy_value( unsigned int val, char *nam, char *names, unsigned int *values,
Packit Service a1973e
			int len )
Packit Service a1973e
{
Packit Service a1973e
	*values = val;
Packit Service a1973e
	strncpy( names, nam, len );
Packit Service a1973e
	names[len - 1] = 0;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_ultra_hwd_ntv_code_to_bits( unsigned int EventCode, hwd_register_t * bits )
Packit Service a1973e
{
Packit Service a1973e
	int index = EventCode & PAPI_NATIVE_AND_MASK;
Packit Service a1973e
Packit Service a1973e
	if ( cpuver <= CPC_ULTRA2 ) {
Packit Service a1973e
		if ( index >= MAX_NATIVE_EVENT_USII ) {
Packit Service a1973e
			return ( PAPI_ENOEVNT );
Packit Service a1973e
		}
Packit Service a1973e
	} else if ( cpuver <= LASTULTRA3 ) {
Packit Service a1973e
		if ( index >= MAX_NATIVE_EVENT ) {
Packit Service a1973e
			return ( PAPI_ENOEVNT );
Packit Service a1973e
		}
Packit Service a1973e
	} else
Packit Service a1973e
		return ( PAPI_ENOEVNT );
Packit Service a1973e
Packit Service a1973e
	bits->event[0] = native_table[index].encoding[0];
Packit Service a1973e
	bits->event[1] = native_table[index].encoding[1];
Packit Service a1973e
	return ( PAPI_OK );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_ultra_hwd_init_control_state( hwd_control_state_t * ptr )
Packit Service a1973e
{
Packit Service a1973e
	ptr->counter_cmd.flags = 0x0;
Packit Service a1973e
	ptr->counter_cmd.cmd.ce_cpuver = cpuver;
Packit Service a1973e
	ptr->counter_cmd.cmd.ce_pcr = 0x0;
Packit Service a1973e
	ptr->counter_cmd.cmd.ce_pic[0] = 0;
Packit Service a1973e
	ptr->counter_cmd.cmd.ce_pic[1] = 0;
Packit Service a1973e
Packit Service a1973e
	_ultra_set_domain( ptr, _solaris_vector.cmp_info.default_domain );
Packit Service a1973e
	set_granularity( ptr, _solaris_vector.cmp_info.default_granularity );
Packit Service a1973e
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_ultra_hwd_update_control_state( hwd_control_state_t * this_state,
Packit Service a1973e
								NativeInfo_t * native, int count,
Packit Service a1973e
								hwd_context_t * zero )
Packit Service a1973e
{
Packit Service a1973e
	int nidx1, nidx2, hwcntr;
Packit Service a1973e
	uint64_t tmp = 0;
Packit Service a1973e
	uint64_t pcr;
Packit Service a1973e
	int64_t cmd0, cmd1;
Packit Service a1973e
Packit Service a1973e
/* save the last three bits */
Packit Service a1973e
	pcr = this_state->counter_cmd.cmd.ce_pcr & 0x7;
Packit Service a1973e
Packit Service a1973e
/* clear the control register */
Packit Service a1973e
	this_state->counter_cmd.cmd.ce_pcr = pcr;
Packit Service a1973e
Packit Service a1973e
/* no native events left */
Packit Service a1973e
	if ( count == 0 )
Packit Service a1973e
		return ( PAPI_OK );
Packit Service a1973e
Packit Service a1973e
	cmd0 = -1;
Packit Service a1973e
	cmd1 = -1;
Packit Service a1973e
/* one native event */
Packit Service a1973e
	if ( count == 1 ) {
Packit Service a1973e
		nidx1 = native[0].ni_event & PAPI_NATIVE_AND_MASK;
Packit Service a1973e
		hwcntr = 0;
Packit Service a1973e
		cmd0 = native_table[nidx1].encoding[0];
Packit Service a1973e
		native[0].ni_position = 0;
Packit Service a1973e
		if ( cmd0 == -1 ) {
Packit Service a1973e
			cmd1 = native_table[nidx1].encoding[1];
Packit Service a1973e
			native[0].ni_position = 1;
Packit Service a1973e
		}
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
/* two native events */
Packit Service a1973e
	if ( count == 2 ) {
Packit Service a1973e
		int avail1, avail2;
Packit Service a1973e
Packit Service a1973e
		avail1 = 0;
Packit Service a1973e
		avail2 = 0;
Packit Service a1973e
		nidx1 = native[0].ni_event & PAPI_NATIVE_AND_MASK;
Packit Service a1973e
		nidx2 = native[1].ni_event & PAPI_NATIVE_AND_MASK;
Packit Service a1973e
		if ( native_table[nidx1].encoding[0] != -1 )
Packit Service a1973e
			avail1 = 0x1;
Packit Service a1973e
		if ( native_table[nidx1].encoding[1] != -1 )
Packit Service a1973e
			avail1 += 0x2;
Packit Service a1973e
		if ( native_table[nidx2].encoding[0] != -1 )
Packit Service a1973e
			avail2 = 0x1;
Packit Service a1973e
		if ( native_table[nidx2].encoding[1] != -1 )
Packit Service a1973e
			avail2 += 0x2;
Packit Service a1973e
		if ( ( avail1 | avail2 ) != 0x3 )
Packit Service a1973e
			return ( PAPI_ECNFLCT );
Packit Service a1973e
		if ( avail1 == 0x3 ) {
Packit Service a1973e
			if ( avail2 == 0x1 ) {
Packit Service a1973e
				cmd0 = native_table[nidx2].encoding[0];
Packit Service a1973e
				cmd1 = native_table[nidx1].encoding[1];
Packit Service a1973e
				native[0].ni_position = 1;
Packit Service a1973e
				native[1].ni_position = 0;
Packit Service a1973e
			} else {
Packit Service a1973e
				cmd1 = native_table[nidx2].encoding[1];
Packit Service a1973e
				cmd0 = native_table[nidx1].encoding[0];
Packit Service a1973e
				native[0].ni_position = 0;
Packit Service a1973e
				native[1].ni_position = 1;
Packit Service a1973e
			}
Packit Service a1973e
		} else {
Packit Service a1973e
			if ( avail1 == 0x1 ) {
Packit Service a1973e
				cmd0 = native_table[nidx1].encoding[0];
Packit Service a1973e
				cmd1 = native_table[nidx2].encoding[1];
Packit Service a1973e
				native[0].ni_position = 0;
Packit Service a1973e
				native[1].ni_position = 1;
Packit Service a1973e
			} else {
Packit Service a1973e
				cmd0 = native_table[nidx2].encoding[0];
Packit Service a1973e
				cmd1 = native_table[nidx1].encoding[1];
Packit Service a1973e
				native[0].ni_position = 1;
Packit Service a1973e
				native[1].ni_position = 0;
Packit Service a1973e
			}
Packit Service a1973e
		}
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
/* set the control register */
Packit Service a1973e
	if ( cmd0 != -1 ) {
Packit Service a1973e
		tmp = ( ( uint64_t ) cmd0 << pcr_shift[0] );
Packit Service a1973e
	}
Packit Service a1973e
	if ( cmd1 != -1 ) {
Packit Service a1973e
		tmp = tmp | ( ( uint64_t ) cmd1 << pcr_shift[1] );
Packit Service a1973e
	}
Packit Service a1973e
	this_state->counter_cmd.cmd.ce_pcr = tmp | pcr;
Packit Service a1973e
#if DEBUG
Packit Service a1973e
	dump_cmd( &this_state->counter_cmd );
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
Packit Service a1973e
papi_vector_t _solaris_vector = {
Packit Service a1973e
	.cmp_info = {
Packit Service a1973e
                                 .name = "solaris.ultra",
Packit Service a1973e
                                 .description = "Solaris CPU 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
				 .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 = 0,
Packit Service a1973e
				 .hardware_intr_sig = PAPI_INT_SIGNAL,
Packit Service a1973e
				 .precise_intr = 0,
Packit Service a1973e
				 }
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 ( hwd_reg_alloc_t ),
Packit Service a1973e
			 }
Packit Service a1973e
	,
Packit Service a1973e
Packit Service a1973e
	/* component interface functions */
Packit Service a1973e
	.init_control_state = _ultra_hwd_init_control_state,
Packit Service a1973e
	.start = _ultra_hwd_start,
Packit Service a1973e
	.stop = _ultra_hwd_stop,
Packit Service a1973e
	.read = _ultra_hwd_read,
Packit Service a1973e
        .shutdown = _ultra_shutdown,
Packit Service a1973e
	.shutdown_component = _ultra_hwd_shutdown_component,
Packit Service a1973e
	.ctl = _ultra_hwd_ctl,
Packit Service a1973e
	.update_control_state = _ultra_hwd_update_control_state,
Packit Service a1973e
        .set_domain = _ultra_set_domain,
Packit Service a1973e
	.reset = _ultra_hwd_reset,
Packit Service a1973e
	.set_overflow = _ultra_hwd_set_overflow,
Packit Service a1973e
	/* .set_profile */
Packit Service a1973e
	/* .stop_profiling = _papi_hwd_stop_profiling, */
Packit Service a1973e
	.ntv_enum_events = _ultra_hwd_ntv_enum_events,
Packit Service a1973e
        /* .ntv_name_to_code */
Packit Service a1973e
	.ntv_code_to_name = _ultra_hwd_ntv_code_to_name,
Packit Service a1973e
	.ntv_code_to_descr = _ultra_hwd_ntv_code_to_descr,
Packit Service a1973e
	.ntv_code_to_bits = _ultra_hwd_ntv_code_to_bits,
Packit Service a1973e
	.init_component = _ultra_hwd_init_component,
Packit Service a1973e
	.dispatch_timer = _ultra_hwd_dispatch_timer,
Packit Service a1973e
Packit Service a1973e
};
Packit Service a1973e
Packit Service a1973e
papi_os_vector_t _papi_os_vector = {
Packit Service a1973e
Packit Service a1973e
	/* OS dependent local routines */
Packit Service a1973e
        .get_memory_info =    _solaris_get_memory_info,
Packit Service a1973e
        .get_dmem_info =      _solaris_get_dmem_info,
Packit Service a1973e
	.update_shlib_info =  _solaris_update_shlib_info,
Packit Service a1973e
	.get_system_info =    _solaris_get_system_info,
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
};