Blame src/linux-bgq.c

Packit 577717
/****************************/
Packit 577717
/* THIS IS OPEN SOURCE CODE */
Packit 577717
/****************************/
Packit 577717
Packit 577717
/** 
Packit 577717
 * @file    linux-bgq.c
Packit 577717
 * @author  Heike Jagode
Packit 577717
 *          jagode@eecs.utk.edu
Packit 577717
 * Mods:	< your name here >
Packit 577717
 *			< your email address >
Packit 577717
 * Blue Gene/Q CPU component: BGPM / Punit
Packit 577717
 * 
Packit 577717
 * Tested version of bgpm (early access)
Packit 577717
 *
Packit 577717
 * @brief
Packit 577717
 *  This file has the source code for a component that enables PAPI-C to 
Packit 577717
 *  access hardware monitoring counters for BG/Q through the BGPM library.
Packit 577717
 */
Packit 577717
Packit 577717
#include "papi.h"
Packit 577717
#include "papi_internal.h"
Packit 577717
#include "papi_lock.h"
Packit 577717
#include "papi_memory.h"
Packit 577717
#include "extras.h"
Packit 577717
Packit 577717
#include "linux-bgq.h"
Packit 577717
Packit 577717
#include "papi_vector.h"
Packit 577717
#include "error.h"
Packit 577717
Packit 577717
/*
Packit 577717
 * BG/Q specific 'stuff'
Packit 577717
 */
Packit 577717
#include <ucontext.h>
Packit 577717
#include <stdlib.h>
Packit 577717
#include <signal.h>
Packit 577717
#include <sys/time.h>
Packit 577717
#include <errno.h>
Packit 577717
#include <stdio.h>
Packit 577717
#include <string.h>
Packit 577717
#include <sys/utsname.h>
Packit 577717
#include "spi/include/upci/upci.h"
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
#include <inttypes.h>
Packit 577717
#endif
Packit 577717
Packit 577717
// BG/Q macros
Packit 577717
#define get_cycles GetTimeBase
Packit 577717
Packit 577717
// BG/Q external structures/functions/stuff
Packit 577717
#if 1
Packit 577717
UPC_Lock_t thdLocks[PAPI_MAX_LOCK];
Packit 577717
#else
Packit 577717
pthread_mutex_t thdLocks[PAPI_MAX_LOCK];
Packit 577717
#endif
Packit 577717
Packit 577717
/* Defined in papi_data.c */
Packit 577717
//extern papi_mdi_t _papi_hwi_system_info;
Packit 577717
Packit 577717
papi_vector_t _bgq_vectors;
Packit 577717
PAPI_os_info_t _papi_os_info;
Packit 577717
Packit 577717
#define OPCODE_EVENT_CHUNK 8
Packit 577717
static int allocated_opcode_events = 0;
Packit 577717
static int num_opcode_events = 0;
Packit 577717
Packit 577717
struct bgq_generic_events_t {
Packit 577717
	int idx;
Packit 577717
	int eventId;
Packit 577717
	char mask[PAPI_MIN_STR_LEN];
Packit 577717
	char opcode[PAPI_MIN_STR_LEN];
Packit 577717
	uint64_t opcode_mask;
Packit 577717
};
Packit 577717
Packit 577717
static struct bgq_generic_events_t *GenericEvent;
Packit 577717
Packit 577717
/* Defined in linux-bgq-memory.c */
Packit 577717
extern int _bgq_get_memory_info( PAPI_hw_info_t * pHwInfo, int pCPU_Type );
Packit 577717
extern int _bgq_get_dmem_info( PAPI_dmem_info_t * pDmemInfo );
Packit 577717
Packit 577717
/* prototypes */
Packit 577717
void user_signal_handler( int hEvtSet, uint64_t address, uint64_t ovfVector, const ucontext_t *pContext );
Packit 577717
Packit 577717
/*******************************************************************************
Packit 577717
 ********  BEGIN FUNCTIONS USED INTERNALLY SPECIFIC TO THIS COMPONENT **********
Packit 577717
 ******************************************************************************/
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Lock
Packit 577717
 */
Packit 577717
void
Packit 577717
_papi_hwd_lock( int lock ) 
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( _AT_ " _papi_hwd_lock %d\n", lock);
Packit 577717
#endif
Packit 577717
	assert( lock < PAPI_MAX_LOCK );
Packit 577717
#if 1
Packit 577717
	UPC_Lock( &thdLocks[lock] );
Packit 577717
#else
Packit 577717
	pthread_mutex_lock( &thdLocks[lock] );
Packit 577717
#endif
Packit 577717
	
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( _AT_ " _papi_hwd_lock got lock %d\n", lock );
Packit 577717
#endif
Packit 577717
	
Packit 577717
	return;
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Unlock
Packit 577717
 */
Packit 577717
void
Packit 577717
_papi_hwd_unlock( int lock )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
    printf( _AT_ " _papi_hwd_unlock %d\n", lock );
Packit 577717
#endif
Packit 577717
    assert( lock < PAPI_MAX_LOCK );
Packit 577717
#if 1
Packit 577717
	UPC_Unlock( &thdLocks[lock] );
Packit 577717
#else
Packit 577717
	pthread_mutex_unlock( &thdLocks[lock] );
Packit 577717
#endif
Packit 577717
	
Packit 577717
	return;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Get System Information
Packit 577717
 *
Packit 577717
 * Initialize system information structure
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_get_system_info( papi_mdi_t *mdi )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "_bgq_get_system_info\n" );
Packit 577717
#endif
Packit 577717
	
Packit 577717
	( void ) mdi;
Packit 577717
	Personality_t personality;
Packit 577717
	int retval;
Packit 577717
	
Packit 577717
	/* Hardware info */
Packit 577717
	retval = Kernel_GetPersonality( &personality, sizeof( Personality_t ) );
Packit 577717
	if ( retval ) {
Packit 577717
		fprintf( stdout, "Kernel_GetPersonality returned %d (sys error=%d).\n"
Packit 577717
				"\t%s\n", retval, errno, strerror( errno ) );
Packit 577717
		return PAPI_ESYS;
Packit 577717
	}
Packit 577717
Packit 577717
	/* Returns the number of processors that are associated with the currently
Packit 577717
	 * running process */
Packit 577717
	_papi_hwi_system_info.hw_info.ncpu = Kernel_ProcessorCount( );
Packit 577717
	// TODO: HJ Those values need to be fixed
Packit 577717
	_papi_hwi_system_info.hw_info.nnodes = Kernel_ProcessCount( );
Packit 577717
	_papi_hwi_system_info.hw_info.totalcpus = _papi_hwi_system_info.hw_info.ncpu;
Packit 577717
	
Packit 577717
	_papi_hwi_system_info.hw_info.cpu_max_mhz = personality.Kernel_Config.FreqMHz;
Packit 577717
	_papi_hwi_system_info.hw_info.cpu_min_mhz = personality.Kernel_Config.FreqMHz;
Packit 577717
Packit 577717
	_papi_hwi_system_info.hw_info.mhz = ( float ) personality.Kernel_Config.FreqMHz;
Packit 577717
	SUBDBG( "_bgq_get_system_info:  Detected MHZ is %f\n",
Packit 577717
		   _papi_hwi_system_info.hw_info.mhz );
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Initialize Control State
Packit 577717
 *
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_init_control_state( hwd_control_state_t * ptr )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "_bgq_init_control_state\n" );
Packit 577717
#endif
Packit 577717
	int retval;
Packit 577717
	
Packit 577717
	ptr->EventGroup = Bgpm_CreateEventSet();
Packit 577717
	retval = _check_BGPM_error( ptr->EventGroup, "Bgpm_CreateEventSet" );
Packit 577717
	if ( retval < 0 ) return retval;
Packit 577717
Packit 577717
	// initialize multiplexing flag to OFF (0)
Packit 577717
	ptr->muxOn = 0;
Packit 577717
	// initialize overflow flag to OFF (0)
Packit 577717
	ptr->overflow = 0;
Packit 577717
    ptr->overflow_count = 0;
Packit 577717
	// initialized BGPM eventGroup flag to NOT applied yet (0)
Packit 577717
	ptr->bgpm_eventset_applied = 0;
Packit 577717
	
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Set Domain
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_set_domain( hwd_control_state_t * cntrl, int domain )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "_bgq_set_domain\n" );
Packit 577717
#endif
Packit 577717
	int found = 0;
Packit 577717
	( void ) cntrl;
Packit 577717
	
Packit 577717
	if ( PAPI_DOM_USER & domain )
Packit 577717
		found = 1;
Packit 577717
	
Packit 577717
	if ( PAPI_DOM_KERNEL & domain )
Packit 577717
		found = 1;
Packit 577717
	
Packit 577717
	if ( PAPI_DOM_OTHER & domain )
Packit 577717
		found = 1;
Packit 577717
	
Packit 577717
	if ( !found )
Packit 577717
		return ( PAPI_EINVAL );
Packit 577717
	
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Initialization
Packit 577717
 * This is called whenever a thread is initialized
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_init( hwd_context_t * ctx )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "_bgq_init\n" );
Packit 577717
#endif
Packit 577717
	( void ) ctx;
Packit 577717
	int retval;
Packit 577717
Packit 577717
#ifdef DEBUG_BGPM
Packit 577717
	Bgpm_PrintOnError(1);
Packit 577717
	Bgpm_ExitOnError(0);
Packit 577717
#else
Packit 577717
	Bgpm_PrintOnError(0);
Packit 577717
	// avoid bgpm default of exiting when error occurs - caller will check return code instead.
Packit 577717
	Bgpm_ExitOnError(0);	
Packit 577717
#endif
Packit 577717
	
Packit 577717
	retval = Bgpm_Init( BGPM_MODE_SWDISTRIB );
Packit 577717
	retval = _check_BGPM_error( retval, "Bgpm_Init" );
Packit 577717
	if ( retval < 0 ) return retval;
Packit 577717
Packit 577717
	//_common_initBgpm();
Packit 577717
	
Packit 577717
	return PAPI_OK;	
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
int
Packit 577717
_bgq_multiplex( hwd_control_state_t * bgq_state )
Packit 577717
{
Packit 577717
	int retval;
Packit 577717
	uint64_t bgpm_period;
Packit 577717
	double Sec, Hz;	
Packit 577717
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf("_bgq_multiplex BEGIN: Num of Events = %d (vs %d)\n", Bgpm_NumEvents( bgq_state->EventGroup ), bgq_state->count );
Packit 577717
#endif
Packit 577717
	
Packit 577717
	// convert Mhz to Hz ( = cycles / sec )
Packit 577717
	Hz = (double) _papi_hwi_system_info.hw_info.cpu_max_mhz * 1000 * 1000;
Packit 577717
	// convert PAPI multiplex period (in ns) to BGPM period (in cycles)
Packit 577717
	Sec = (double) _papi_os_info.itimer_ns / ( 1000 * 1000 * 1000 );
Packit 577717
	bgpm_period = Hz * Sec;
Packit 577717
Packit 577717
	// if EventGroup is not empty -- which is required by BGPM before 
Packit 577717
	// we can call SetMultiplex() -- then drain the events from the 
Packit 577717
	// BGPM EventGroup, turn on multiplex flag, and rebuild BGPM EventGroup.
Packit 577717
	if ( 0 < bgq_state->count ) {
Packit 577717
		// Delete and re-create BGPM eventset
Packit 577717
		retval = _common_deleteRecreate( &bgq_state->EventGroup );
Packit 577717
		if ( retval < 0 ) return retval;
Packit 577717
Packit 577717
		// turn on multiplex for BGPM
Packit 577717
		retval = Bgpm_SetMultiplex( bgq_state->EventGroup, bgpm_period, BGPM_NORMAL ); 		
Packit 577717
		retval = _check_BGPM_error( retval, "Bgpm_SetMultiplex" );
Packit 577717
		if ( retval < 0 ) return retval;
Packit 577717
Packit 577717
		// rebuild BGPM EventGroup
Packit 577717
		retval = _common_rebuildEventgroup( bgq_state->count, 
Packit 577717
								   bgq_state->EventGroup_local, 
Packit 577717
								   &bgq_state->EventGroup );	
Packit 577717
		if ( retval < 0 ) return retval;
Packit 577717
	}
Packit 577717
	else {
Packit 577717
		// need to pass either BGPM_NORMAL or BGPM_NOTNORMAL 
Packit 577717
		// BGPM_NORMAL: numbers reported by Bgpm_ReadEvent() are normalized 
Packit 577717
		// to the maximum time spent in a multiplexed group
Packit 577717
		retval = Bgpm_SetMultiplex( bgq_state->EventGroup, bgpm_period, BGPM_NORMAL ); 		
Packit 577717
		retval = _check_BGPM_error( retval, "Bgpm_SetMultiplex" );
Packit 577717
		if ( retval < 0 ) return retval;
Packit 577717
	}
Packit 577717
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf("_bgq_multiplex END: Num of Events = %d (vs %d) --- retval = %d\n", 
Packit 577717
		   Bgpm_NumEvents( bgq_state->EventGroup ), bgq_state->count, retval );
Packit 577717
#endif
Packit 577717
	
Packit 577717
	return ( retval );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Register Allocation
Packit 577717
 *
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_allocate_registers( EventSetInfo_t * ESI )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf("_bgq_allocate_registers\n");
Packit 577717
#endif
Packit 577717
	int i, natNum;
Packit 577717
	int xEventId;
Packit 577717
Packit 577717
	/*
Packit 577717
	 * Start monitoring the events...
Packit 577717
	 */
Packit 577717
	natNum = ESI->NativeCount;
Packit 577717
Packit 577717
	for ( i = 0; i < natNum; i++ ) {
Packit 577717
		xEventId = ( ESI->NativeInfoArray[i].ni_event & PAPI_NATIVE_AND_MASK ) + 1;
Packit 577717
		ESI->NativeInfoArray[i].ni_position = i;		
Packit 577717
	}
Packit 577717
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Cleanup Eventset
Packit 577717
 *
Packit 577717
 * Destroy and re-create the BGPM / Punit EventSet
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_cleanup_eventset( hwd_control_state_t * ctrl )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "_bgq_cleanup_eventset\n" );
Packit 577717
#endif
Packit 577717
	
Packit 577717
	// set multiplexing flag to OFF (0)
Packit 577717
	ctrl->muxOn = 0;
Packit 577717
	// set overflow flag to OFF (0)
Packit 577717
	ctrl->overflow = 0;
Packit 577717
    ctrl->overflow_count = 0;
Packit 577717
	// set BGPM eventGroup flag back to NOT applied yet (0)
Packit 577717
	ctrl->bgpm_eventset_applied = 0;
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Update Control State
Packit 577717
 *
Packit 577717
 * This function clears the current contents of the control
Packit 577717
 * structure and updates it with whatever resources are allocated
Packit 577717
 * for all the native events in the native info structure array.
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_update_control_state( hwd_control_state_t * ptr,
Packit 577717
						   NativeInfo_t * native, int count,
Packit 577717
						   hwd_context_t * ctx )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( _AT_ " _bgq_update_control_state: count = %d, EventGroup=%d\n", count, ptr->EventGroup );
Packit 577717
#endif
Packit 577717
	( void ) ctx;
Packit 577717
	int i, j, k, index, retval;
Packit 577717
	unsigned evtIdx;
Packit 577717
	
Packit 577717
	// Delete and re-create BGPM eventset
Packit 577717
	retval = _common_deleteRecreate( &ptr->EventGroup );
Packit 577717
	if ( retval < 0 ) return retval;
Packit 577717
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
    printf( _AT_ " _bgq_update_control_state: EventGroup=%d, muxOn = %d, overflow = %d\n",
Packit 577717
		   ptr->EventGroup, ptr->muxOn, ptr->overflow );
Packit 577717
#endif
Packit 577717
	
Packit 577717
	// add the events to the eventset
Packit 577717
	for ( i = 0; i < count; i++ ) {
Packit 577717
		index = ( native[i].ni_event & PAPI_NATIVE_AND_MASK ) + 1;
Packit 577717
		
Packit 577717
		ptr->EventGroup_local[i] = index;
Packit 577717
Packit 577717
		// we found an opcode event
Packit 577717
		if ( index > BGQ_PUNIT_MAX_EVENTS ) {
Packit 577717
			for( j = 0; j < num_opcode_events; j++ ) {
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
				printf(_AT_ " _bgq_update_control_state: %d out of %d OPCODES\n",
Packit 577717
					   j, num_opcode_events );
Packit 577717
#endif
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
				printf(_AT_ " _bgq_update_control_state: j's idx = %d, index = %d\n",
Packit 577717
					   GenericEvent[j].idx, index );
Packit 577717
#endif
Packit 577717
				if ( GenericEvent[j].idx == ( index - 1) ) {
Packit 577717
					/* Add events to the BGPM eventGroup */
Packit 577717
					retval = Bgpm_AddEvent( ptr->EventGroup, GenericEvent[j].eventId );
Packit 577717
					retval = _check_BGPM_error( retval, "Bgpm_AddEvent" );
Packit 577717
					if ( retval < 0 ) return retval;
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
					printf(_AT_ " _bgq_update_control_state: ADD event: i = %d, eventId = %d\n", i, GenericEvent[j].eventId );
Packit 577717
#endif
Packit 577717
					
Packit 577717
					evtIdx = Bgpm_GetEventIndex( ptr->EventGroup,
Packit 577717
												 GenericEvent[j].eventId,
Packit 577717
												 i );
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
					printf(_AT_ " _bgq_update_control_state: evtIdx in EventGroup = %d\n",
Packit 577717
						   evtIdx );
Packit 577717
#endif
Packit 577717
					if ( 0 == strcmp( GenericEvent[j].mask, "PEVT_INST_XU_GRP_MASK" ) ) {
Packit 577717
						retval = Bgpm_SetXuGrpMask( ptr->EventGroup,
Packit 577717
												    evtIdx,
Packit 577717
												    GenericEvent[j].opcode_mask );
Packit 577717
						retval = _check_BGPM_error( retval, "Bgpm_SetXuGrpMask" );
Packit 577717
						if ( retval < 0 ) return retval;
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
						printf(_AT_ " _bgq_update_control_state: it's PEVT_INST_XU_GRP_MASK\n" );
Packit 577717
#endif
Packit 577717
					} else if ( 0 == strcmp( GenericEvent[j].mask, "PEVT_INST_QFPU_GRP_MASK" ) ) {
Packit 577717
						retval = Bgpm_SetQfpuGrpMask( ptr->EventGroup,
Packit 577717
												      evtIdx,
Packit 577717
													  GenericEvent[j].opcode_mask );
Packit 577717
						retval = _check_BGPM_error( retval, "Bgpm_SetQfpuGrpMask" );
Packit 577717
						if ( retval < 0 ) return retval;
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
						printf(_AT_ " _bgq_update_control_state: it's PEVT_INST_QFPU_GRP_MASK\n" );
Packit 577717
#endif
Packit 577717
					}
Packit 577717
				}	
Packit 577717
			}
Packit 577717
		}
Packit 577717
		else {
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
			printf(_AT_ " _bgq_update_control_state: no OPCODE\n" );
Packit 577717
#endif
Packit 577717
			
Packit 577717
			/* Add events to the BGPM eventGroup */
Packit 577717
			retval = Bgpm_AddEvent( ptr->EventGroup, index );
Packit 577717
			retval = _check_BGPM_error( retval, "Bgpm_AddEvent" );
Packit 577717
			if ( retval < 0 ) return retval;
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
			printf(_AT_ " _bgq_update_control_state: ADD event: i = %d, index = %d\n", i, index );
Packit 577717
#endif
Packit 577717
			
Packit 577717
		}
Packit 577717
	}
Packit 577717
	
Packit 577717
	// store how many events we added to an EventSet
Packit 577717
	ptr->count = count;
Packit 577717
Packit 577717
	// if muxOn and EventGroup is not empty -- which is required by BGPM before 
Packit 577717
	// we can call SetMultiplex() -- then drain the events from the 
Packit 577717
	// BGPM EventGroup, turn on multiplex flag, and rebuild BGPM EventGroup.
Packit 577717
	if ( 1 == ptr->muxOn ) {
Packit 577717
		retval = _bgq_multiplex( ptr );
Packit 577717
	}
Packit 577717
		
Packit 577717
    // since update_control_state trashes overflow settings, this puts things
Packit 577717
    // back into balance for BGPM
Packit 577717
    if ( 1 == ptr->overflow ) {
Packit 577717
        for ( k = 0; k < ptr->overflow_count; k++ ) {
Packit 577717
            retval = _common_set_overflow_BGPM( ptr->EventGroup,
Packit 577717
                                       ptr->overflow_list[k].EventIndex,
Packit 577717
                                       ptr->overflow_list[k].threshold,
Packit 577717
                                       user_signal_handler );
Packit 577717
			if ( retval < 0 ) return retval;
Packit 577717
        }
Packit 577717
    }
Packit 577717
		
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Start
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_start( hwd_context_t * ctx, hwd_control_state_t * ptr )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "BEGIN _bgq_start\n" );
Packit 577717
#endif
Packit 577717
	( void ) ctx;
Packit 577717
	int retval;
Packit 577717
		
Packit 577717
	retval = Bgpm_Apply( ptr->EventGroup ); 
Packit 577717
	retval = _check_BGPM_error( retval, "Bgpm_Apply" );
Packit 577717
	if ( retval < 0 ) return retval;
Packit 577717
	
Packit 577717
	// set flag to 1: BGPM eventGroup HAS BEEN applied
Packit 577717
	ptr->bgpm_eventset_applied = 1;
Packit 577717
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	int i;
Packit 577717
	int numEvts = Bgpm_NumEvents( ptr->EventGroup );
Packit 577717
	for ( i = 0; i < numEvts; i++ ) {
Packit 577717
		printf("%d = %s\n", i, Bgpm_GetEventLabel( ptr->EventGroup, i) );
Packit 577717
	}
Packit 577717
#endif	
Packit 577717
	
Packit 577717
	/* Bgpm_Apply() does an implicit reset; 
Packit 577717
	 hence no need to use Bgpm_ResetStart */
Packit 577717
	retval = Bgpm_Start( ptr->EventGroup );
Packit 577717
	retval = _check_BGPM_error( retval, "Bgpm_Start" );
Packit 577717
	if ( retval < 0 ) return retval;
Packit 577717
	
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Stop
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_stop( hwd_context_t * ctx, hwd_control_state_t * ptr )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "BEGIN _bgq_stop\n" );
Packit 577717
#endif
Packit 577717
	( void ) ctx;
Packit 577717
	int retval;
Packit 577717
	
Packit 577717
	retval = Bgpm_Stop( ptr->EventGroup );
Packit 577717
	retval = _check_BGPM_error( retval, "Bgpm_Stop" );
Packit 577717
	if ( retval < 0 ) return retval;
Packit 577717
	
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Read Counters
Packit 577717
 *
Packit 577717
 * Read the counters into local storage
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_read( hwd_context_t * ctx, hwd_control_state_t * ptr,
Packit 577717
		   long_long ** dp, int flags )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "_bgq_read\n" );
Packit 577717
#endif
Packit 577717
	( void ) ctx;
Packit 577717
	( void ) flags;
Packit 577717
	int i, numEvts;
Packit 577717
	
Packit 577717
	numEvts = Bgpm_NumEvents( ptr->EventGroup );
Packit 577717
	if ( numEvts == 0 ) {
Packit 577717
#ifdef DEBUG_BGPM
Packit 577717
		printf ("Error: ret value is %d for BGPM API function Bgpm_NumEvents.\n", numEvts );
Packit 577717
		//return ( EXIT_FAILURE );
Packit 577717
#endif
Packit 577717
	}
Packit 577717
	
Packit 577717
	for ( i = 0; i < numEvts; i++ ) 
Packit 577717
		ptr->counters[i] = _common_getEventValue( i, ptr->EventGroup );
Packit 577717
Packit 577717
	*dp = ptr->counters;
Packit 577717
		
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Reset
Packit 577717
 *
Packit 577717
 * Zero the counter values
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_reset( hwd_context_t * ctx, hwd_control_state_t * ptr )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "_bgq_reset\n" );
Packit 577717
#endif
Packit 577717
	( void ) ctx;
Packit 577717
	int retval;
Packit 577717
	
Packit 577717
	/* we can't simply call Bgpm_Reset() since PAPI doesn't have the 
Packit 577717
	   restriction that an EventSet has to be stopped before resetting is
Packit 577717
	   possible. However, BGPM does have this restriction. 
Packit 577717
	   Hence we need to stop, reset and start */
Packit 577717
	retval = Bgpm_Stop( ptr->EventGroup );
Packit 577717
	retval = _check_BGPM_error( retval, "Bgpm_Stop" );
Packit 577717
	if ( retval < 0 ) return retval;
Packit 577717
	
Packit 577717
	retval = Bgpm_ResetStart( ptr->EventGroup );
Packit 577717
	retval = _check_BGPM_error( retval, "Bgpm_ResetStart" );
Packit 577717
	if ( retval < 0 ) return retval;
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Shutdown
Packit 577717
 *
Packit 577717
 * This routine is for shutting down threads,
Packit 577717
 * including the master thread.
Packit 577717
 * Effectively a no-op, same as BG/L/P...
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_shutdown( hwd_context_t * ctx )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "_bgq_shutdown\n" );
Packit 577717
#endif
Packit 577717
	( void ) ctx;
Packit 577717
	int retval;
Packit 577717
	
Packit 577717
	/* Disable BGPM library */	
Packit 577717
	retval = Bgpm_Disable();
Packit 577717
	retval = _check_BGPM_error( retval, "Bgpm_Disable" );
Packit 577717
	if ( retval < 0 ) return retval;
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Write
Packit 577717
 *
Packit 577717
 * Write counter values
Packit 577717
 * NOTE:  Could possible support, but signal error as BG/L/P does...
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_write( hwd_context_t * ctx, hwd_control_state_t * cntrl, long_long * from )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "_bgq_write\n" );
Packit 577717
#endif
Packit 577717
	( void ) ctx;
Packit 577717
	( void ) cntrl;
Packit 577717
	( void ) from;
Packit 577717
	
Packit 577717
	return PAPI_ECMP;
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Dispatch Timer
Packit 577717
 *
Packit 577717
 * NOT the same as BG/L/P where we simply return
Packit 577717
 * This function is used when hardware overflows are working or when
Packit 577717
 * software overflows are forced
Packit 577717
 */
Packit 577717
void
Packit 577717
_bgq_dispatch_timer( int signal, hwd_siginfo_t * info, void *uc )
Packit 577717
{
Packit 577717
	( void ) signal;
Packit 577717
	( void ) info;
Packit 577717
	( void ) uc;
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf("BEGIN _bgq_dispatch_timer\n");
Packit 577717
#endif
Packit 577717
	
Packit 577717
	return;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * user_signal_handler
Packit 577717
 *
Packit 577717
 * This function is used when hardware overflows are working or when
Packit 577717
 * software overflows are forced
Packit 577717
 */
Packit 577717
void
Packit 577717
user_signal_handler( int hEvtSet, uint64_t address, uint64_t ovfVector, const ucontext_t *pContext )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "user_signal_handler start\n" );
Packit 577717
#endif
Packit 577717
	( void ) address;
Packit 577717
	int retval; 
Packit 577717
	unsigned i;
Packit 577717
	int isHardware = 1;
Packit 577717
	int cidx = _bgq_vectors.cmp_info.CmpIdx;
Packit 577717
	long_long overflow_bit = 0;
Packit 577717
	caddr_t address1;
Packit 577717
	_papi_hwi_context_t ctx;
Packit 577717
	ctx.ucontext = ( hwd_ucontext_t * ) pContext;
Packit 577717
	ThreadInfo_t *thread = _papi_hwi_lookup_thread( 0 );
Packit 577717
	
Packit 577717
	//printf(_AT_ " thread = %p\n", thread);	// <<<<<<<<<<<<<<<<<<
Packit 577717
	
Packit 577717
	EventSetInfo_t *ESI;
Packit 577717
	ESI = thread->running_eventset[cidx];
Packit 577717
    // Get the indices of all events which have overflowed.
Packit 577717
    unsigned ovfIdxs[BGPM_MAX_OVERFLOW_EVENTS];
Packit 577717
    unsigned len = BGPM_MAX_OVERFLOW_EVENTS;
Packit 577717
	
Packit 577717
    retval = Bgpm_GetOverflowEventIndices( hEvtSet, ovfVector, ovfIdxs, &len );
Packit 577717
Packit 577717
	if ( retval < 0 ) {
Packit 577717
#ifdef DEBUG_BGPM
Packit 577717
		printf ( "Error: ret value is %d for BGPM API function Bgpm_GetOverflowEventIndices.\n", 
Packit 577717
				 retval ); 
Packit 577717
#endif
Packit 577717
		return;
Packit 577717
	}
Packit 577717
		
Packit 577717
	if ( thread == NULL ) {
Packit 577717
		PAPIERROR( "thread == NULL in user_signal_handler!" );
Packit 577717
		return;
Packit 577717
	}
Packit 577717
		
Packit 577717
	if ( ESI == NULL ) {
Packit 577717
		PAPIERROR( "ESI == NULL in user_signal_handler!");
Packit 577717
		return;
Packit 577717
	}
Packit 577717
		
Packit 577717
	if ( ESI->overflow.flags == 0 ) {
Packit 577717
		PAPIERROR( "ESI->overflow.flags == 0 in user_signal_handler!");
Packit 577717
		return;
Packit 577717
	}
Packit 577717
Packit 577717
	for ( i = 0; i < len; i++ ) {
Packit 577717
		uint64_t hProf;
Packit 577717
        Bgpm_GetEventUser1( hEvtSet, ovfIdxs[i], &hProf );
Packit 577717
        if ( hProf ) {
Packit 577717
			overflow_bit ^= 1 << ovfIdxs[i];
Packit 577717
			break;
Packit 577717
        }
Packit 577717
		
Packit 577717
	}
Packit 577717
	
Packit 577717
	if ( ESI->overflow.flags & PAPI_OVERFLOW_FORCE_SW ) {
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
		printf("OVERFLOW_SOFTWARE\n");
Packit 577717
#endif
Packit 577717
		address1 = GET_OVERFLOW_ADDRESS( ctx );
Packit 577717
		_papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address1, NULL, 0, 0, &thread, cidx );
Packit 577717
		return;
Packit 577717
	}
Packit 577717
	else if ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) {
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
		printf("OVERFLOW_HARDWARE\n");
Packit 577717
#endif
Packit 577717
		address1 = GET_OVERFLOW_ADDRESS( ctx );
Packit 577717
		_papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address1, &isHardware, overflow_bit, 0, &thread, cidx );
Packit 577717
	}
Packit 577717
	else {
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
		printf("OVERFLOW_NONE\n");
Packit 577717
#endif
Packit 577717
		PAPIERROR( "ESI->overflow.flags is set to something other than PAPI_OVERFLOW_HARDWARE or PAPI_OVERFLOW_FORCE_SW (%#x)", thread->running_eventset[cidx]->overflow.flags);
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Set Overflow
Packit 577717
 *
Packit 577717
 * This is commented out in BG/L/P - need to explore and complete...
Packit 577717
 * However, with true 64-bit counters in BG/Q and all counters for PAPI
Packit 577717
 * always starting from a true zero (we don't allow write...), the possibility
Packit 577717
 * for overflow is remote at best...
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_set_overflow( EventSetInfo_t * ESI, int EventIndex, int threshold )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf("BEGIN _bgq_set_overflow\n");
Packit 577717
#endif
Packit 577717
	hwd_control_state_t * this_state = ( hwd_control_state_t * ) ESI->ctl_state;
Packit 577717
	int retval;
Packit 577717
	int evt_idx;
Packit 577717
	
Packit 577717
	/*
Packit 577717
	 * In case an BGPM eventGroup HAS BEEN applied or attached before
Packit 577717
	 * overflow is set, delete the eventGroup and create an new empty one,
Packit 577717
	 * and rebuild as it was prior to deletion
Packit 577717
	 */
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "_bgq_set_overflow: bgpm_eventset_applied = %d, threshold = %d\n",
Packit 577717
		    this_state->bgpm_eventset_applied, threshold );
Packit 577717
#endif	
Packit 577717
	if ( 1 == this_state->bgpm_eventset_applied && 0 != threshold ) {
Packit 577717
		retval = _common_deleteRecreate( &this_state->EventGroup );
Packit 577717
		if ( retval < 0 ) return retval;
Packit 577717
Packit 577717
		retval = _common_rebuildEventgroup( this_state->count,
Packit 577717
								   this_state->EventGroup_local,
Packit 577717
								   &this_state->EventGroup );
Packit 577717
		if ( retval < 0 ) return retval;
Packit 577717
Packit 577717
		/* set BGPM eventGroup flag back to NOT applied yet (0) 
Packit 577717
		 * because the eventGroup has been recreated from scratch */
Packit 577717
		this_state->bgpm_eventset_applied = 0;
Packit 577717
	}
Packit 577717
	
Packit 577717
	
Packit 577717
	evt_idx = ESI->EventInfoArray[EventIndex].pos[0];
Packit 577717
	//evt_id = ( ESI->NativeInfoArray[EventIndex].ni_event & PAPI_NATIVE_AND_MASK ) + 1;
Packit 577717
	SUBDBG( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
Packit 577717
		    evt_idx, EventIndex, threshold );
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
Packit 577717
		    evt_idx, EventIndex, threshold );
Packit 577717
#endif
Packit 577717
	
Packit 577717
	/* If this counter isn't set to overflow, it's an error */
Packit 577717
	if ( threshold == 0 ) {
Packit 577717
		/* Remove the signal handler */
Packit 577717
		retval = _papi_hwi_stop_signal( _bgq_vectors.cmp_info.hardware_intr_sig );
Packit 577717
		if ( retval != PAPI_OK )
Packit 577717
			return ( retval );
Packit 577717
	}
Packit 577717
	else {
Packit 577717
		this_state->overflow = 1;
Packit 577717
        this_state->overflow_count++;
Packit 577717
		this_state->overflow_list[this_state->overflow_count-1].threshold = threshold;
Packit 577717
		this_state->overflow_list[this_state->overflow_count-1].EventIndex = evt_idx;
Packit 577717
	
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
		printf( "_bgq_set_overflow: Enable the signal handler\n" );
Packit 577717
#endif		
Packit 577717
		/* Enable the signal handler */
Packit 577717
		retval = _papi_hwi_start_signal( _bgq_vectors.cmp_info.hardware_intr_sig, 
Packit 577717
										 NEED_CONTEXT, 
Packit 577717
										 _bgq_vectors.cmp_info.CmpIdx );
Packit 577717
		if ( retval != PAPI_OK )
Packit 577717
			return ( retval );
Packit 577717
		
Packit 577717
		retval = _common_set_overflow_BGPM( this_state->EventGroup,
Packit 577717
                                  this_state->overflow_list[this_state->overflow_count-1].EventIndex,
Packit 577717
                                  this_state->overflow_list[this_state->overflow_count-1].threshold,
Packit 577717
                                  user_signal_handler );
Packit 577717
		if ( retval < 0 ) return retval;
Packit 577717
	}
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Set Profile
Packit 577717
 *
Packit 577717
 * Same as for BG/L/P, routine not used and returns error
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_set_profile( EventSetInfo_t * ESI, int EventIndex, int threshold )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf("BEGIN _bgq_set_profile\n");
Packit 577717
#endif
Packit 577717
	
Packit 577717
	( void ) ESI;
Packit 577717
	( void ) EventIndex;
Packit 577717
	( void ) threshold;
Packit 577717
	
Packit 577717
	return PAPI_ECMP;
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Stop Profiling
Packit 577717
 *
Packit 577717
 * Same as for BG/L/P...
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_stop_profiling( ThreadInfo_t * master, EventSetInfo_t * ESI )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf("BEGIN _bgq_stop_profiling\n");
Packit 577717
#endif
Packit 577717
	
Packit 577717
	( void ) master;
Packit 577717
	( void ) ESI;
Packit 577717
	
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Control
Packit 577717
 *
Packit 577717
 * Same as for BG/L/P - initialize the domain
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_ctl( hwd_context_t * ctx, int code, _papi_int_option_t * option )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "_bgq_ctl\n" );
Packit 577717
#endif
Packit 577717
	( void ) ctx;
Packit 577717
	int retval;
Packit 577717
	
Packit 577717
	switch ( code ) {
Packit 577717
		case PAPI_MULTIPLEX:
Packit 577717
		{
Packit 577717
			hwd_control_state_t * bgq_state = ( ( hwd_control_state_t * ) option->multiplex.ESI->ctl_state );
Packit 577717
			bgq_state->muxOn = 1;
Packit 577717
			retval = _bgq_multiplex( bgq_state );
Packit 577717
			return ( retval );
Packit 577717
		}
Packit 577717
		default:
Packit 577717
			return ( PAPI_OK );
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Get Real Micro-seconds
Packit 577717
 */
Packit 577717
long long
Packit 577717
_bgq_get_real_usec( void )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "_bgq_get_real_usec\n" );
Packit 577717
#endif
Packit 577717
	
Packit 577717
	/*
Packit 577717
	 * NOTE:  _papi_hwi_system_info.hw_info.mhz is really a representation of unit of time per cycle.
Packit 577717
	 *        On BG/P, it's value is 8.5e-4.  Therefore, to get cycles per sec, we have to multiply
Packit 577717
	 *        by 1.0e12.  To then convert to usec, we have to divide by 1.0e-3.
Packit 577717
	 */
Packit 577717
	return ( ( long long ) ( ( ( float ) get_cycles(  ) ) /
Packit 577717
							 ( ( _papi_hwi_system_info.hw_info.cpu_max_mhz ) ) ) );
Packit 577717
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Get Real Cycles
Packit 577717
 *
Packit 577717
 * Same for BG/L/P, using native function...
Packit 577717
 */
Packit 577717
long long
Packit 577717
_bgq_get_real_cycles( void )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "_bgq_get_real_cycles\n" );
Packit 577717
#endif
Packit 577717
Packit 577717
	return ( ( long long ) get_cycles(  ) );
Packit 577717
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Get Virtual Micro-seconds
Packit 577717
 *
Packit 577717
 * Same calc as for BG/L/P, returns real usec...
Packit 577717
 */
Packit 577717
long long
Packit 577717
_bgq_get_virt_usec( void )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "_bgq_get_virt_usec\n" );
Packit 577717
#endif
Packit 577717
	
Packit 577717
	return _bgq_get_real_usec(  );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Get Virtual Cycles
Packit 577717
 *
Packit 577717
 * Same calc as for BG/L/P, returns real cycles...
Packit 577717
 */
Packit 577717
long long
Packit 577717
_bgq_get_virt_cycles( void )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "_bgq_get_virt_cycles\n" );
Packit 577717
#endif
Packit 577717
	
Packit 577717
	return _bgq_get_real_cycles(  );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Component setup and shutdown
Packit 577717
 *
Packit 577717
 * Initialize hardware counters, setup the function vector table
Packit 577717
 * and get hardware information, this routine is called when the
Packit 577717
 * PAPI process is initialized (IE PAPI_library_init)
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_init_component( int cidx )
Packit 577717
{	
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf("_bgq_init_substrate\n");
Packit 577717
	//printf("_bgq_init_substrate: 1. BGPM_INITIALIZED = %d \n", BGPM_INITIALIZED);
Packit 577717
#endif
Packit 577717
	int retval;
Packit 577717
	int i;
Packit 577717
		
Packit 577717
	/* allocate the opcode event structure */
Packit 577717
	GenericEvent = calloc( OPCODE_EVENT_CHUNK, sizeof( struct bgq_generic_events_t ) );
Packit 577717
	if ( NULL == GenericEvent ) {
Packit 577717
		return PAPI_ENOMEM;
Packit 577717
	}
Packit 577717
	
Packit 577717
	/* init opcode event stuff */
Packit 577717
	allocated_opcode_events = OPCODE_EVENT_CHUNK;
Packit 577717
	num_opcode_events = 0;
Packit 577717
		
Packit 577717
	_bgq_vectors.cmp_info.CmpIdx = cidx;
Packit 577717
Packit 577717
	/*
Packit 577717
	 * Fill in what we can of the papi_system_info
Packit 577717
	 */
Packit 577717
	SUBDBG( "Before _bgq_get_system_info()...\n" );
Packit 577717
	retval = _bgq_get_system_info( &_papi_hwi_system_info );
Packit 577717
	SUBDBG( "After _bgq_get_system_info(), retval=%d...\n", retval );
Packit 577717
	if ( retval != PAPI_OK )
Packit 577717
		return ( retval );
Packit 577717
Packit 577717
	/*
Packit 577717
	 * Setup memory info
Packit 577717
	 */
Packit 577717
Packit 577717
	SUBDBG( "Before _bgq_get_memory_info...\n" );
Packit 577717
	retval = _bgq_get_memory_info( &_papi_hwi_system_info.hw_info,
Packit 577717
								  ( int ) _papi_hwi_system_info.hw_info.
Packit 577717
								  model );
Packit 577717
	SUBDBG( "After _bgq_get_memory_info, retval=%d...\n", retval );
Packit 577717
	if ( retval )
Packit 577717
		return ( retval );
Packit 577717
#if 1
Packit 577717
	/* Setup Locks */
Packit 577717
	for ( i = 0; i < PAPI_MAX_LOCK; i++ )
Packit 577717
		thdLocks[i] = 0;  // MUTEX_OPEN
Packit 577717
#else
Packit 577717
	for( i = 0; i < PAPI_MAX_LOCK; i++ ) {
Packit 577717
		pthread_mutex_init( &thdLocks[i], NULL );
Packit 577717
	}
Packit 577717
#endif
Packit 577717
	
Packit 577717
	/* Setup presets */
Packit 577717
	retval = _papi_load_preset_table( "BGQ", 0, cidx );
Packit 577717
	if ( retval ) {
Packit 577717
		return retval;
Packit 577717
	}	
Packit 577717
	
Packit 577717
	
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*************************************/
Packit 577717
/* CODE TO SUPPORT OPAQUE NATIVE MAP */
Packit 577717
/*************************************/
Packit 577717
Packit 577717
/*
Packit 577717
 * Event Name to Native Code
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_ntv_name_to_code( const char *name, unsigned int *event_code )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "_bgq_ntv_name_to_code\n" );
Packit 577717
#endif
Packit 577717
	int ret;
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "name = ===%s===\n", name );
Packit 577717
#endif	
Packit 577717
Packit 577717
	/* Treat events differently if BGPM Opcodes are used */
Packit 577717
	/* Opcode group selection values are "OR"ed together to create a desired 
Packit 577717
	 mask of instruction group events to accumulate in the same counter */	
Packit 577717
	if ( 0 == strncmp( name, "PEVT_INST_XU_GRP_MASK", strlen( "PEVT_INST_XU_GRP_MASK" ) ) ||
Packit 577717
		 0 == strncmp( name, "PEVT_INST_QFPU_GRP_MASK", strlen( "PEVT_INST_QFPU_GRP_MASK" ) ) ) {
Packit 577717
Packit 577717
		char *pcolon;
Packit 577717
		pcolon = strchr( name, ':' );
Packit 577717
		
Packit 577717
		// Found colon separator
Packit 577717
		if ( pcolon != NULL ) {
Packit 577717
			int mask_len = pcolon - name;
Packit 577717
			strncpy( GenericEvent[num_opcode_events].mask, name,  mask_len  );
Packit 577717
			strncpy( GenericEvent[num_opcode_events].opcode, pcolon+1, strlen(name) - 1 - mask_len );
Packit 577717
			/* opcode_mask needs to be 'uint64_t',
Packit 577717
			   hence we use strtoull() which returns an 'unsigned long long int' */
Packit 577717
			GenericEvent[num_opcode_events].opcode_mask = strtoull( GenericEvent[num_opcode_events].opcode, (char **)NULL, 16 );
Packit 577717
			GenericEvent[num_opcode_events].idx = OPCODE_BUF + num_opcode_events;
Packit 577717
			/* Return event id matching the generic XU/QFPU event string */
Packit 577717
			GenericEvent[num_opcode_events].eventId = Bgpm_GetEventIdFromLabel( GenericEvent[num_opcode_events].mask );
Packit 577717
			if ( GenericEvent[num_opcode_events].eventId <= 0 ) {
Packit 577717
#ifdef DEBUG_BGPM
Packit 577717
				printf ("Error: ret value is %d for BGPM API function '%s'.\n",
Packit 577717
						ret, "Bgpm_GetEventIdFromLabel" );
Packit 577717
#endif
Packit 577717
				return PAPI_ENOEVNT;
Packit 577717
			}
Packit 577717
			
Packit 577717
			*event_code = GenericEvent[num_opcode_events].idx;
Packit 577717
			
Packit 577717
			num_opcode_events++;
Packit 577717
			
Packit 577717
			/* If there are too many opcode events than allocated, then allocate more room */
Packit 577717
			if( num_opcode_events >= allocated_opcode_events ) {
Packit 577717
				
Packit 577717
				SUBDBG("Allocating more room for BGPM opcode events (%d %ld)\n",
Packit 577717
					   ( allocated_opcode_events + NATIVE_OPCODE_CHUNK ),
Packit 577717
					   ( long )sizeof( struct bgq_generic_events_t ) *
Packit 577717
					   ( allocated_opcode_events + NATIVE_OPCODE_CHUNK ) );
Packit 577717
				
Packit 577717
				GenericEvent = realloc( GenericEvent, sizeof( struct bgq_generic_events_t ) *
Packit 577717
									   ( allocated_opcode_events + OPCODE_EVENT_CHUNK ) );
Packit 577717
				if ( NULL == GenericEvent ) {
Packit 577717
					return PAPI_ENOMEM;
Packit 577717
				}
Packit 577717
				allocated_opcode_events += OPCODE_EVENT_CHUNK;
Packit 577717
			}
Packit 577717
        }
Packit 577717
		else {
Packit 577717
			SUBDBG( "Error: Found a generic BGPM event mask without opcode string\n" );
Packit 577717
			return PAPI_ENOEVNT;
Packit 577717
		}
Packit 577717
		
Packit 577717
		
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
		printf(_AT_ " _bgq_ntv_name_to_code: GenericEvent no. %d: \n", num_opcode_events-1 );
Packit 577717
		printf(	"idx         = %d\n", GenericEvent[num_opcode_events-1].idx);
Packit 577717
		printf(	"eventId     = %d\n", GenericEvent[num_opcode_events-1].eventId);
Packit 577717
		printf(	"mask        = %s\n", GenericEvent[num_opcode_events-1].mask);
Packit 577717
		printf(	"opcode      = %s\n", GenericEvent[num_opcode_events-1].opcode);
Packit 577717
		printf( "opcode_mask = %#lX (%lu)\n", GenericEvent[num_opcode_events-1].opcode_mask,
Packit 577717
			   GenericEvent[num_opcode_events-1].opcode_mask );
Packit 577717
#endif
Packit 577717
	}
Packit 577717
	else {
Packit 577717
		/* Return event id matching a given event label string */
Packit 577717
		ret = Bgpm_GetEventIdFromLabel ( name );
Packit 577717
		
Packit 577717
		if ( ret <= 0 ) {
Packit 577717
#ifdef DEBUG_BGPM
Packit 577717
			printf ("Error: ret value is %d for BGPM API function '%s'.\n",
Packit 577717
					ret, "Bgpm_GetEventIdFromLabel" );
Packit 577717
#endif
Packit 577717
			return PAPI_ENOEVNT;
Packit 577717
		}
Packit 577717
		else if ( ret > BGQ_PUNIT_MAX_EVENTS ) // not a PUnit event
Packit 577717
			return PAPI_ENOEVNT;
Packit 577717
		else
Packit 577717
			*event_code = ( ret - 1 );		
Packit 577717
	}
Packit 577717
	
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Native Code to Event Name
Packit 577717
 *
Packit 577717
 * Given a native event code, returns the short text label
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_ntv_code_to_name( unsigned int EventCode, char *name, int len )
Packit 577717
{	
Packit 577717
#ifdef DEBUG_BGQ	
Packit 577717
	printf( "_bgq_ntv_code_to_name\n" );
Packit 577717
#endif
Packit 577717
	int index = ( EventCode & PAPI_NATIVE_AND_MASK ) + 1;
Packit 577717
	
Packit 577717
	if ( index >= MAX_COUNTERS )
Packit 577717
		return PAPI_ENOEVNT;
Packit 577717
			
Packit 577717
	strncpy( name, Bgpm_GetEventIdLabel( index ), len );
Packit 577717
	
Packit 577717
	if ( name == NULL ) {
Packit 577717
#ifdef DEBUG_BGPM
Packit 577717
		printf ("Error: ret value is NULL for BGPM API function Bgpm_GetEventIdLabel.\n" );
Packit 577717
#endif
Packit 577717
		return PAPI_ENOEVNT;
Packit 577717
	}
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "name = ===%s===\n", name );
Packit 577717
#endif	
Packit 577717
	
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Native Code to Event Description
Packit 577717
 *
Packit 577717
 * Given a native event code, returns the longer native event description
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
Packit 577717
{	
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "_bgq_ntv_code_to_descr\n" );
Packit 577717
#endif
Packit 577717
	int retval;
Packit 577717
	int index = ( EventCode & PAPI_NATIVE_AND_MASK ) + 1;
Packit 577717
Packit 577717
	retval = Bgpm_GetLongDesc( index, name, &len );
Packit 577717
	retval = _check_BGPM_error( retval, "Bgpm_GetLongDesc" );						 
Packit 577717
	if ( retval < 0 ) return retval;
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Native Code to Bit Configuration
Packit 577717
 *
Packit 577717
 * Given a native event code, assigns the native event's
Packit 577717
 * information to a given pointer.
Packit 577717
 * NOTE: The info must be COPIED to location addressed by
Packit 577717
 *       the provided pointer, not just referenced!
Packit 577717
 * NOTE: For BG/Q, the bit configuration is not needed,
Packit 577717
 *       as the native SPI is used to configure events.
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_ntv_code_to_bits( unsigned int EventCode, hwd_register_t * bits )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "_bgq_ntv_code_to_bits\n" );
Packit 577717
#endif
Packit 577717
	
Packit 577717
	( void ) EventCode;
Packit 577717
	( void ) bits;
Packit 577717
	
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Native ENUM Events
Packit 577717
 *
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgq_ntv_enum_events( unsigned int *EventCode, int modifier )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "_bgq_ntv_enum_events\n" );
Packit 577717
#endif
Packit 577717
	
Packit 577717
	switch ( modifier ) {
Packit 577717
		case PAPI_ENUM_FIRST:
Packit 577717
			*EventCode = PAPI_NATIVE_MASK;
Packit 577717
			
Packit 577717
			return ( PAPI_OK );
Packit 577717
			break;
Packit 577717
			
Packit 577717
		case PAPI_ENUM_EVENTS:
Packit 577717
		{
Packit 577717
			int index = ( *EventCode & PAPI_NATIVE_AND_MASK ) + 1;
Packit 577717
			
Packit 577717
			if ( index < BGQ_PUNIT_MAX_EVENTS ) {
Packit 577717
				*EventCode = *EventCode + 1;
Packit 577717
				return ( PAPI_OK );
Packit 577717
			} else
Packit 577717
				return ( PAPI_ENOEVNT );
Packit 577717
			
Packit 577717
			break;
Packit 577717
		}
Packit 577717
		default:
Packit 577717
			return ( PAPI_EINVAL );
Packit 577717
	}
Packit 577717
	
Packit 577717
	return ( PAPI_EINVAL );	
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
int 
Packit 577717
_papi_hwi_init_os(void) {
Packit 577717
	
Packit 577717
	struct utsname uname_buffer;
Packit 577717
	
Packit 577717
	/* Get the kernel info */
Packit 577717
    uname(&uname_buffer);
Packit 577717
	
Packit 577717
    strncpy(_papi_os_info.name,uname_buffer.sysname,PAPI_MAX_STR_LEN);
Packit 577717
	
Packit 577717
    strncpy(_papi_os_info.version,uname_buffer.release,PAPI_MAX_STR_LEN);
Packit 577717
	
Packit 577717
    _papi_os_info.itimer_sig = PAPI_INT_MPX_SIGNAL;
Packit 577717
    _papi_os_info.itimer_num = PAPI_INT_ITIMER;
Packit 577717
    _papi_os_info.itimer_res_ns = 1;
Packit 577717
	
Packit 577717
    return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Vector Table for BG/Q
Packit 577717
 */
Packit 577717
papi_vector_t _bgq_vectors = {
Packit 577717
	.cmp_info = {
Packit 577717
				 /* Default component information (unspecified values are initialized to 0) */
Packit 577717
				 .name = "linux-bgq",
Packit 577717
				 .short_name = "bgq",
Packit 577717
				 .description = "Blue Gene/Q component",
Packit 577717
				 .num_cntrs = BGQ_PUNIT_MAX_COUNTERS,
Packit 577717
				 .num_mpx_cntrs = BGQ_PUNIT_MAX_COUNTERS,
Packit 577717
				 .num_native_events = BGQ_PUNIT_MAX_EVENTS,
Packit 577717
				 .default_domain = PAPI_DOM_USER,
Packit 577717
				 .available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL,
Packit 577717
				 .default_granularity = PAPI_GRN_THR,
Packit 577717
				 .available_granularities = PAPI_GRN_THR,
Packit 577717
				 .hardware_intr_sig = PAPI_INT_SIGNAL,
Packit 577717
				 .hardware_intr = 1,
Packit 577717
				 .kernel_multiplex = 1,
Packit 577717
		
Packit 577717
				 /* component specific cmp_info initializations */
Packit 577717
				 .fast_real_timer = 1,
Packit 577717
				 .fast_virtual_timer = 0,
Packit 577717
				 }
Packit 577717
	,
Packit 577717
Packit 577717
	/* Sizes of framework-opaque component-private structures */
Packit 577717
	.size = {
Packit 577717
			 .context = sizeof ( hwd_context_t ),
Packit 577717
			 .control_state = sizeof ( hwd_control_state_t ),
Packit 577717
			 .reg_value = sizeof ( hwd_register_t ),
Packit 577717
			 .reg_alloc = sizeof ( hwd_reg_alloc_t ),
Packit 577717
			 }
Packit 577717
	,
Packit 577717
	/* Function pointers in this component */
Packit 577717
//   .get_overflow_address =
Packit 577717
	.start = _bgq_start,
Packit 577717
	.stop = _bgq_stop,
Packit 577717
	.read = _bgq_read,
Packit 577717
	.reset = _bgq_reset,
Packit 577717
	.write = _bgq_write,
Packit 577717
	.stop_profiling = _bgq_stop_profiling,
Packit 577717
	.init_component = _bgq_init_component,
Packit 577717
	.init_thread = _bgq_init,
Packit 577717
	.init_control_state = _bgq_init_control_state,
Packit 577717
	.update_control_state = _bgq_update_control_state,
Packit 577717
	.ctl = _bgq_ctl,
Packit 577717
	.set_overflow = _bgq_set_overflow,
Packit 577717
	//.dispatch_timer = _bgq_dispatch_timer,
Packit 577717
	.set_profile = _bgq_set_profile,
Packit 577717
	.set_domain = _bgq_set_domain,
Packit 577717
	.ntv_enum_events = _bgq_ntv_enum_events,
Packit 577717
	.ntv_name_to_code = _bgq_ntv_name_to_code,
Packit 577717
	.ntv_code_to_name = _bgq_ntv_code_to_name,
Packit 577717
	.ntv_code_to_descr = _bgq_ntv_code_to_descr,
Packit 577717
	.ntv_code_to_bits = _bgq_ntv_code_to_bits,
Packit 577717
	.allocate_registers = _bgq_allocate_registers,
Packit 577717
	.cleanup_eventset = _bgq_cleanup_eventset,
Packit 577717
	.shutdown_thread = _bgq_shutdown
Packit 577717
//  .shutdown_global      =
Packit 577717
//  .user                 =
Packit 577717
};
Packit 577717
Packit 577717
papi_os_vector_t _papi_os_vector = {
Packit 577717
	.get_memory_info = _bgq_get_memory_info,
Packit 577717
	.get_dmem_info = _bgq_get_dmem_info,
Packit 577717
	.get_real_cycles = _bgq_get_real_cycles,
Packit 577717
	.get_real_usec = _bgq_get_real_usec,
Packit 577717
	.get_virt_cycles = _bgq_get_virt_cycles,
Packit 577717
	.get_virt_usec = _bgq_get_virt_usec,
Packit 577717
	.get_system_info = _bgq_get_system_info
Packit 577717
};