|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* File: papi_libpfm3_events.c
|
|
Packit |
577717 |
* Author: Dan Terpstra: blantantly extracted from Phil's perfmon.c
|
|
Packit |
577717 |
* mucci@cs.utk.edu
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include <ctype.h>
|
|
Packit |
577717 |
#include <string.h>
|
|
Packit |
577717 |
#include <errno.h>
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "papi.h"
|
|
Packit |
577717 |
#include "papi_internal.h"
|
|
Packit |
577717 |
#include "papi_vector.h"
|
|
Packit |
577717 |
#include "papi_memory.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "perfmon/perfmon.h"
|
|
Packit |
577717 |
#include "perfmon/pfmlib.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "papi_libpfm_events.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Native events consist of a flag field, an event field, and a unit mask field.
|
|
Packit |
577717 |
* These variables define the characteristics of the event and unit mask fields.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
unsigned int PAPI_NATIVE_EVENT_AND_MASK = 0x000003ff;
|
|
Packit |
577717 |
unsigned int PAPI_NATIVE_EVENT_SHIFT = 0;
|
|
Packit |
577717 |
unsigned int PAPI_NATIVE_UMASK_AND_MASK = 0x03fffc00;
|
|
Packit |
577717 |
unsigned int PAPI_NATIVE_UMASK_MAX = 16;
|
|
Packit |
577717 |
unsigned int PAPI_NATIVE_UMASK_SHIFT = 10;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Globals */
|
|
Packit |
577717 |
int num_native_events=0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* NOTE: PAPI stores umask info in a variable sized (16 bit?) bitfield.
|
|
Packit |
577717 |
Perfmon2 stores umask info in a large (48 element?) array of values.
|
|
Packit |
577717 |
Native event encodings for perfmon2 contain array indices
|
|
Packit |
577717 |
encoded as bits in this bitfield. These indices must be converted
|
|
Packit |
577717 |
into a umask value before programming the counters. For Perfmon,
|
|
Packit |
577717 |
this is done by converting back to an array of values; for
|
|
Packit |
577717 |
perfctr, it must be done by looking up the values.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* This routine is used to step through all possible combinations of umask
|
|
Packit |
577717 |
values. It assumes that mask contains a valid combination of array indices
|
|
Packit |
577717 |
for this event. */
|
|
Packit |
577717 |
static inline int
|
|
Packit |
577717 |
encode_native_event_raw( unsigned int event, unsigned int mask )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
unsigned int tmp = event << PAPI_NATIVE_EVENT_SHIFT;
|
|
Packit |
577717 |
SUBDBG( "Old native index was %#08x with %#08x mask\n", tmp, mask );
|
|
Packit |
577717 |
tmp = tmp | ( mask << PAPI_NATIVE_UMASK_SHIFT );
|
|
Packit |
577717 |
SUBDBG( "New encoding is %#08x\n", tmp | PAPI_NATIVE_MASK );
|
|
Packit |
577717 |
return ( int ) ( tmp | PAPI_NATIVE_MASK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* This routine converts array indices contained in the mask_values array
|
|
Packit |
577717 |
into bits in the umask field that is OR'd into the native event code.
|
|
Packit |
577717 |
These bits are NOT the mask values themselves, but indices into an array
|
|
Packit |
577717 |
of mask values contained in the native event table. */
|
|
Packit |
577717 |
static inline int
|
|
Packit |
577717 |
encode_native_event( unsigned int event, unsigned int num_mask,
|
|
Packit |
577717 |
unsigned int *mask_values )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
unsigned int i;
|
|
Packit |
577717 |
unsigned int tmp = event << PAPI_NATIVE_EVENT_SHIFT;
|
|
Packit |
577717 |
SUBDBG( "Native base event is %#08x with %d masks\n", tmp, num_mask );
|
|
Packit |
577717 |
for ( i = 0; i < num_mask; i++ ) {
|
|
Packit |
577717 |
SUBDBG( "Mask index is %#08x\n", mask_values[i] );
|
|
Packit |
577717 |
tmp = tmp | ( ( 1 << mask_values[i] ) << PAPI_NATIVE_UMASK_SHIFT );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
SUBDBG( "Full native encoding is 0x%08x\n", tmp | PAPI_NATIVE_MASK );
|
|
Packit |
577717 |
return ( int ) ( tmp | PAPI_NATIVE_MASK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Break a PAPI native event code into its composite event code and pfm mask bits */
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_pfm_decode_native_event( unsigned int EventCode, unsigned int *event,
|
|
Packit |
577717 |
unsigned int *umask )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
unsigned int tevent, major, minor;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
tevent = EventCode & PAPI_NATIVE_AND_MASK;
|
|
Packit |
577717 |
major = ( tevent & PAPI_NATIVE_EVENT_AND_MASK ) >> PAPI_NATIVE_EVENT_SHIFT;
|
|
Packit |
577717 |
if ( ( int ) major >= num_native_events )
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
minor = ( tevent & PAPI_NATIVE_UMASK_AND_MASK ) >> PAPI_NATIVE_UMASK_SHIFT;
|
|
Packit |
577717 |
*event = major;
|
|
Packit |
577717 |
*umask = minor;
|
|
Packit |
577717 |
SUBDBG( "EventCode %#08x is event %d, umask %#x\n", EventCode, major,
|
|
Packit |
577717 |
minor );
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* convert a collection of pfm mask bits into an array of pfm mask indices */
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
prepare_umask( unsigned int foo, unsigned int *values )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
unsigned int tmp = foo, i;
|
|
Packit |
577717 |
int j = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
SUBDBG( "umask %#x\n", tmp );
|
|
Packit |
577717 |
while ( ( i = ( unsigned int ) ffs( ( int ) tmp ) ) ) {
|
|
Packit |
577717 |
tmp = tmp ^ ( 1 << ( i - 1 ) );
|
|
Packit |
577717 |
values[j] = i - 1;
|
|
Packit |
577717 |
SUBDBG( "umask %d is %d\n", j, values[j] );
|
|
Packit |
577717 |
j++;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return ( j );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* convert the mask values in a pfm event structure into a PAPI unit mask */
|
|
Packit |
577717 |
static inline unsigned int
|
|
Packit |
577717 |
convert_pfm_masks( pfmlib_event_t * gete )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int ret;
|
|
Packit |
577717 |
unsigned int i, code, tmp = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for ( i = 0; i < gete->num_masks; i++ ) {
|
|
Packit |
577717 |
if ( ( ret =
|
|
Packit |
577717 |
pfm_get_event_mask_code( gete->event, gete->unit_masks[i],
|
|
Packit |
577717 |
&code ) ) == PFMLIB_SUCCESS ) {
|
|
Packit |
577717 |
SUBDBG( "Mask value is %#08x\n", code );
|
|
Packit |
577717 |
tmp |= code;
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
PAPIERROR( "pfm_get_event_mask_code(%#x,%d,%p): %s", gete->event,
|
|
Packit |
577717 |
i, &code, pfm_strerror( ret ) );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return ( tmp );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* convert an event code and pfm unit mask into a PAPI unit mask */
|
|
Packit |
577717 |
unsigned int
|
|
Packit |
577717 |
_pfm_convert_umask( unsigned int event, unsigned int umask )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
pfmlib_event_t gete;
|
|
Packit |
577717 |
memset( &gete, 0, sizeof ( gete ) );
|
|
Packit |
577717 |
gete.event = event;
|
|
Packit |
577717 |
gete.num_masks = ( unsigned int ) prepare_umask( umask, gete.unit_masks );
|
|
Packit |
577717 |
return ( convert_pfm_masks( &gete ) );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* convert libpfm error codes to PAPI error codes for
|
|
Packit |
577717 |
more informative error reporting */
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_libpfm_error( int pfm_error )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
switch ( pfm_error ) {
|
|
Packit |
577717 |
case PFMLIB_SUCCESS: return PAPI_OK; /* success */
|
|
Packit |
577717 |
case PFMLIB_ERR_NOTSUPP: return PAPI_ENOSUPP; /* function not supported */
|
|
Packit |
577717 |
case PFMLIB_ERR_INVAL: return PAPI_EINVAL; /* invalid parameters */
|
|
Packit |
577717 |
case PFMLIB_ERR_NOINIT: return PAPI_ENOINIT; /* library was not initialized */
|
|
Packit |
577717 |
case PFMLIB_ERR_NOTFOUND: return PAPI_ENOEVNT; /* event not found */
|
|
Packit |
577717 |
case PFMLIB_ERR_NOASSIGN: return PAPI_ECNFLCT; /* cannot assign events to counters */
|
|
Packit |
577717 |
case PFMLIB_ERR_FULL: return PAPI_EBUF; /* buffer is full or too small */
|
|
Packit |
577717 |
case PFMLIB_ERR_EVTMANY: return PAPI_EMISC; /* event used more than once */
|
|
Packit |
577717 |
case PFMLIB_ERR_MAGIC: return PAPI_EBUG; /* invalid library magic number */
|
|
Packit |
577717 |
case PFMLIB_ERR_FEATCOMB: return PAPI_ECOMBO; /* invalid combination of features */
|
|
Packit |
577717 |
case PFMLIB_ERR_EVTSET: return PAPI_ENOEVST; /* incompatible event sets */
|
|
Packit |
577717 |
case PFMLIB_ERR_EVTINCOMP: return PAPI_ECNFLCT; /* incompatible event combination */
|
|
Packit |
577717 |
case PFMLIB_ERR_TOOMANY: return PAPI_ECOUNT; /* too many events or unit masks */
|
|
Packit |
577717 |
case PFMLIB_ERR_BADHOST: return PAPI_ESYS; /* not supported by host CPU */
|
|
Packit |
577717 |
case PFMLIB_ERR_UMASK: return PAPI_EATTR; /* invalid or missing unit mask */
|
|
Packit |
577717 |
case PFMLIB_ERR_NOMEM: return PAPI_ENOMEM; /* out of memory */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Itanium only */
|
|
Packit |
577717 |
case PFMLIB_ERR_IRRTOOBIG: /* code range too big */
|
|
Packit |
577717 |
case PFMLIB_ERR_IRREMPTY: /* empty code range */
|
|
Packit |
577717 |
case PFMLIB_ERR_IRRINVAL: /* invalid code range */
|
|
Packit |
577717 |
case PFMLIB_ERR_IRRTOOMANY: /* too many code ranges */
|
|
Packit |
577717 |
case PFMLIB_ERR_DRRINVAL: /* invalid data range */
|
|
Packit |
577717 |
case PFMLIB_ERR_DRRTOOMANY: /* too many data ranges */
|
|
Packit |
577717 |
case PFMLIB_ERR_IRRALIGN: /* bad alignment for code range */
|
|
Packit |
577717 |
case PFMLIB_ERR_IRRFLAGS: /* code range missing flags */
|
|
Packit |
577717 |
default:
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_libpfm_ntv_name_to_code( const char *name, unsigned int *event_code )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
pfmlib_event_t event;
|
|
Packit |
577717 |
unsigned int i;
|
|
Packit |
577717 |
int ret;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
SUBDBG( "pfm_find_full_event(%s,%p)\n", name, &event );
|
|
Packit |
577717 |
ret = pfm_find_full_event( name, &event );
|
|
Packit |
577717 |
if ( ret == PFMLIB_SUCCESS ) {
|
|
Packit |
577717 |
SUBDBG( "Full event name found\n" );
|
|
Packit |
577717 |
/* we can only capture PAPI_NATIVE_UMASK_MAX or fewer masks */
|
|
Packit |
577717 |
if ( event.num_masks > PAPI_NATIVE_UMASK_MAX ) {
|
|
Packit |
577717 |
SUBDBG( "num_masks (%d) > max masks (%d)\n", event.num_masks,
|
|
Packit |
577717 |
PAPI_NATIVE_UMASK_MAX );
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
/* no mask index can exceed PAPI_NATIVE_UMASK_MAX */
|
|
Packit |
577717 |
for ( i = 0; i < event.num_masks; i++ ) {
|
|
Packit |
577717 |
if ( event.unit_masks[i] > PAPI_NATIVE_UMASK_MAX ) {
|
|
Packit |
577717 |
SUBDBG( "mask index (%d) > max masks (%d)\n",
|
|
Packit |
577717 |
event.unit_masks[i], PAPI_NATIVE_UMASK_MAX );
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
*event_code =
|
|
Packit |
577717 |
encode_native_event( event.event, event.num_masks,
|
|
Packit |
577717 |
event.unit_masks );
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
} else if ( ret == PFMLIB_ERR_UMASK ) {
|
|
Packit |
577717 |
SUBDBG( "UMASK error, looking for base event only\n" );
|
|
Packit |
577717 |
ret = pfm_find_event( name, &event.event );
|
|
Packit |
577717 |
if ( ret == PFMLIB_SUCCESS ) {
|
|
Packit |
577717 |
*event_code = encode_native_event( event.event, 0, 0 );
|
|
Packit |
577717 |
return PAPI_EATTR;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_libpfm_ntv_code_to_name( unsigned int EventCode, char *ntv_name, int len )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int ret;
|
|
Packit |
577717 |
unsigned int event, umask;
|
|
Packit |
577717 |
pfmlib_event_t gete;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
memset( &gete, 0, sizeof ( gete ) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( _pfm_decode_native_event( EventCode, &event, &umask ) != PAPI_OK )
|
|
Packit |
577717 |
return ( PAPI_ENOEVNT );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
gete.event = event;
|
|
Packit |
577717 |
gete.num_masks = ( unsigned int ) prepare_umask( umask, gete.unit_masks );
|
|
Packit |
577717 |
if ( gete.num_masks == 0 )
|
|
Packit |
577717 |
ret = pfm_get_event_name( gete.event, ntv_name, ( size_t ) len );
|
|
Packit |
577717 |
else
|
|
Packit |
577717 |
ret = pfm_get_full_event_name( &gete, ntv_name, ( size_t ) len );
|
|
Packit |
577717 |
if ( ret != PFMLIB_SUCCESS ) {
|
|
Packit |
577717 |
char tmp[PAPI_2MAX_STR_LEN];
|
|
Packit |
577717 |
pfm_get_event_name( gete.event, tmp, sizeof ( tmp ) );
|
|
Packit |
577717 |
/* Skip error message if event is not supported by host cpu;
|
|
Packit |
577717 |
* we don't need to give this info away for papi_native_avail util */
|
|
Packit |
577717 |
if ( ret != PFMLIB_ERR_BADHOST )
|
|
Packit |
577717 |
PAPIERROR
|
|
Packit |
577717 |
( "pfm_get_full_event_name(%p(event %d,%s,%d masks),%p,%d): %d -- %s",
|
|
Packit |
577717 |
&gete, gete.event, tmp, gete.num_masks, ntv_name, len, ret,
|
|
Packit |
577717 |
pfm_strerror( ret ) );
|
|
Packit |
577717 |
if ( ret == PFMLIB_ERR_FULL ) {
|
|
Packit |
577717 |
return PAPI_EBUF;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_EMISC;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_libpfm_ntv_code_to_descr( unsigned int EventCode, char *ntv_descr, int len )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
unsigned int event, umask;
|
|
Packit |
577717 |
char *eventd, **maskd, *tmp;
|
|
Packit |
577717 |
int i, ret;
|
|
Packit |
577717 |
pfmlib_event_t gete;
|
|
Packit |
577717 |
size_t total_len = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
memset( &gete, 0, sizeof ( gete ) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( _pfm_decode_native_event( EventCode, &event, &umask ) != PAPI_OK )
|
|
Packit |
577717 |
return ( PAPI_ENOEVNT );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ret = pfm_get_event_description( event, &eventd );
|
|
Packit |
577717 |
if ( ret != PFMLIB_SUCCESS ) {
|
|
Packit |
577717 |
PAPIERROR( "pfm_get_event_description(%d,%p): %s",
|
|
Packit |
577717 |
event, &eventd, pfm_strerror( ret ) );
|
|
Packit |
577717 |
return ( PAPI_ENOEVNT );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( gete.num_masks =
|
|
Packit |
577717 |
( unsigned int ) prepare_umask( umask, gete.unit_masks ) ) ) {
|
|
Packit |
577717 |
maskd = ( char ** ) malloc( gete.num_masks * sizeof ( char * ) );
|
|
Packit |
577717 |
if ( maskd == NULL ) {
|
|
Packit |
577717 |
free( eventd );
|
|
Packit |
577717 |
return ( PAPI_ENOMEM );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
for ( i = 0; i < ( int ) gete.num_masks; i++ ) {
|
|
Packit |
577717 |
ret =
|
|
Packit |
577717 |
pfm_get_event_mask_description( event, gete.unit_masks[i],
|
|
Packit |
577717 |
&maskd[i] );
|
|
Packit |
577717 |
if ( ret != PFMLIB_SUCCESS ) {
|
|
Packit |
577717 |
PAPIERROR( "pfm_get_event_mask_description(%d,%d,%p): %s",
|
|
Packit |
577717 |
event, umask, &maskd, pfm_strerror( ret ) );
|
|
Packit |
577717 |
free( eventd );
|
|
Packit |
577717 |
for ( ; i >= 0; i-- )
|
|
Packit |
577717 |
free( maskd[i] );
|
|
Packit |
577717 |
free( maskd );
|
|
Packit |
577717 |
return ( PAPI_EINVAL );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
total_len += strlen( maskd[i] );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
tmp =
|
|
Packit |
577717 |
( char * ) malloc( strlen( eventd ) + strlen( ", masks:" ) +
|
|
Packit |
577717 |
total_len + gete.num_masks + 1 );
|
|
Packit |
577717 |
if ( tmp == NULL ) {
|
|
Packit |
577717 |
for ( i = ( int ) gete.num_masks - 1; i >= 0; i-- )
|
|
Packit |
577717 |
free( maskd[i] );
|
|
Packit |
577717 |
free( maskd );
|
|
Packit |
577717 |
free( eventd );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
tmp[0] = '\0';
|
|
Packit |
577717 |
strcat( tmp, eventd );
|
|
Packit |
577717 |
strcat( tmp, ", masks:" );
|
|
Packit |
577717 |
for ( i = 0; i < ( int ) gete.num_masks; i++ ) {
|
|
Packit |
577717 |
if ( i != 0 )
|
|
Packit |
577717 |
strcat( tmp, "," );
|
|
Packit |
577717 |
strcat( tmp, maskd[i] );
|
|
Packit |
577717 |
free( maskd[i] );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
free( maskd );
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
tmp = ( char * ) malloc( strlen( eventd ) + 1 );
|
|
Packit |
577717 |
if ( tmp == NULL ) {
|
|
Packit |
577717 |
free( eventd );
|
|
Packit |
577717 |
return ( PAPI_ENOMEM );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
tmp[0] = '\0';
|
|
Packit |
577717 |
strcat( tmp, eventd );
|
|
Packit |
577717 |
free( eventd );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
strncpy( ntv_descr, tmp, ( size_t ) len );
|
|
Packit |
577717 |
if ( ( int ) strlen( tmp ) > len - 1 )
|
|
Packit |
577717 |
ret = PAPI_EBUF;
|
|
Packit |
577717 |
else
|
|
Packit |
577717 |
ret = PAPI_OK;
|
|
Packit |
577717 |
free( tmp );
|
|
Packit |
577717 |
return ( ret );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_libpfm_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
|
|
Packit |
577717 |
SUBDBG("ENTER %#x\n",EventCode);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_papi_libpfm_ntv_code_to_name(EventCode,info->symbol,
|
|
Packit |
577717 |
sizeof(info->symbol));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_papi_libpfm_ntv_code_to_descr(EventCode,info->long_descr,
|
|
Packit |
577717 |
sizeof(info->long_descr));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_libpfm_ntv_enum_events( unsigned int *EventCode, int modifier )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
unsigned int event, umask, num_masks;
|
|
Packit |
577717 |
int ret;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( modifier == PAPI_ENUM_FIRST ) {
|
|
Packit |
577717 |
*EventCode = PAPI_NATIVE_MASK; /* assumes first native event is always 0x4000000 */
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( _pfm_decode_native_event( *EventCode, &event, &umask ) != PAPI_OK )
|
|
Packit |
577717 |
return ( PAPI_ENOEVNT );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ret = pfm_get_num_event_masks( event, &num_masks );
|
|
Packit |
577717 |
if ( ret != PFMLIB_SUCCESS ) {
|
|
Packit |
577717 |
PAPIERROR( "pfm_get_num_event_masks(%d,%p): %s", event, &num_masks,
|
|
Packit |
577717 |
pfm_strerror( ret ) );
|
|
Packit |
577717 |
return ( PAPI_ENOEVNT );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if ( num_masks > PAPI_NATIVE_UMASK_MAX )
|
|
Packit |
577717 |
num_masks = PAPI_NATIVE_UMASK_MAX;
|
|
Packit |
577717 |
SUBDBG( "This is umask %d of %d\n", umask, num_masks );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( modifier == PAPI_ENUM_EVENTS ) {
|
|
Packit |
577717 |
if ( event < ( unsigned int ) num_native_events - 1 ) {
|
|
Packit |
577717 |
*EventCode =
|
|
Packit |
577717 |
( unsigned int ) encode_native_event_raw( event + 1, 0 );
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return ( PAPI_ENOEVNT );
|
|
Packit |
577717 |
} else if ( modifier == PAPI_NTV_ENUM_UMASK_COMBOS ) {
|
|
Packit |
577717 |
if ( umask + 1 < ( unsigned int ) ( 1 << num_masks ) ) {
|
|
Packit |
577717 |
*EventCode =
|
|
Packit |
577717 |
( unsigned int ) encode_native_event_raw( event, umask + 1 );
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return ( PAPI_ENOEVNT );
|
|
Packit |
577717 |
} else if ( modifier == PAPI_NTV_ENUM_UMASKS ) {
|
|
Packit |
577717 |
int thisbit = ffs( ( int ) umask );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
SUBDBG( "First bit is %d in %08x\b\n", thisbit - 1, umask );
|
|
Packit |
577717 |
thisbit = 1 << thisbit;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( thisbit & ( ( 1 << num_masks ) - 1 ) ) {
|
|
Packit |
577717 |
*EventCode =
|
|
Packit |
577717 |
( unsigned int ) encode_native_event_raw( event,
|
|
Packit |
577717 |
( unsigned int )
|
|
Packit |
577717 |
thisbit );
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return ( PAPI_ENOEVNT );
|
|
Packit |
577717 |
} else
|
|
Packit |
577717 |
return ( PAPI_EINVAL );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_libpfm_ntv_code_to_bits( unsigned int EventCode, hwd_register_t * bits )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
unsigned int event, umask;
|
|
Packit |
577717 |
pfmlib_event_t gete;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* For PFM & Perfmon, native info is just an index into PFM event table. */
|
|
Packit |
577717 |
if ( _pfm_decode_native_event( EventCode, &event, &umask ) != PAPI_OK )
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
memset( &gete, 0x0, sizeof ( pfmlib_event_t ) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
gete.event = event;
|
|
Packit |
577717 |
gete.num_masks = prepare_umask( umask, gete.unit_masks );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
memcpy( bits, &gete, sizeof ( pfmlib_event_t ) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* used by linux-timer.c for ia64 */
|
|
Packit |
577717 |
int _perfmon2_pfm_pmu_type = -1;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_libpfm_init(papi_vector_t *my_vector, int cidx) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
unsigned int ncnt;
|
|
Packit |
577717 |
unsigned int version;
|
|
Packit |
577717 |
char pmu_name[PAPI_MIN_STR_LEN];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* The following checks the version of the PFM library
|
|
Packit |
577717 |
against the version PAPI linked to... */
|
|
Packit |
577717 |
SUBDBG( "pfm_initialize()\n" );
|
|
Packit |
577717 |
if ( ( retval = pfm_initialize( ) ) != PFMLIB_SUCCESS ) {
|
|
Packit |
577717 |
PAPIERROR( "pfm_initialize(): %s", pfm_strerror( retval ) );
|
|
Packit |
577717 |
return PAPI_ESYS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Get the libpfm3 version */
|
|
Packit |
577717 |
SUBDBG( "pfm_get_version(%p)\n", &version );
|
|
Packit |
577717 |
if ( pfm_get_version( &version ) != PFMLIB_SUCCESS ) {
|
|
Packit |
577717 |
PAPIERROR( "pfm_get_version(%p): %s", version, pfm_strerror( retval ) );
|
|
Packit |
577717 |
return PAPI_ESYS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Set the version */
|
|
Packit |
577717 |
sprintf( my_vector->cmp_info.support_version, "%d.%d",
|
|
Packit |
577717 |
PFM_VERSION_MAJOR( version ), PFM_VERSION_MINOR( version ) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Complain if the compiled-against version doesn't match current version */
|
|
Packit |
577717 |
if ( PFM_VERSION_MAJOR( version ) != PFM_VERSION_MAJOR( PFMLIB_VERSION ) ) {
|
|
Packit |
577717 |
PAPIERROR( "Version mismatch of libpfm: compiled %#x vs. installed %#x\n",
|
|
Packit |
577717 |
PFM_VERSION_MAJOR( PFMLIB_VERSION ),
|
|
Packit |
577717 |
PFM_VERSION_MAJOR( version ) );
|
|
Packit |
577717 |
return PAPI_ESYS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Always initialize globals dynamically to handle forks properly. */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_perfmon2_pfm_pmu_type = -1;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Opened once for all threads. */
|
|
Packit |
577717 |
SUBDBG( "pfm_get_pmu_type(%p)\n", &_perfmon2_pfm_pmu_type );
|
|
Packit |
577717 |
if ( pfm_get_pmu_type( &_perfmon2_pfm_pmu_type ) != PFMLIB_SUCCESS ) {
|
|
Packit |
577717 |
PAPIERROR( "pfm_get_pmu_type(%p): %s", _perfmon2_pfm_pmu_type,
|
|
Packit |
577717 |
pfm_strerror( retval ) );
|
|
Packit |
577717 |
return PAPI_ESYS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
pmu_name[0] = '\0';
|
|
Packit |
577717 |
if ( pfm_get_pmu_name( pmu_name, PAPI_MIN_STR_LEN ) != PFMLIB_SUCCESS ) {
|
|
Packit |
577717 |
PAPIERROR( "pfm_get_pmu_name(%p,%d): %s", pmu_name, PAPI_MIN_STR_LEN,
|
|
Packit |
577717 |
pfm_strerror( retval ) );
|
|
Packit |
577717 |
return PAPI_ESYS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
SUBDBG( "PMU is a %s, type %d\n", pmu_name, _perfmon2_pfm_pmu_type );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Setup presets */
|
|
Packit |
577717 |
retval = _papi_load_preset_table( pmu_name, _perfmon2_pfm_pmu_type, cidx );
|
|
Packit |
577717 |
if ( retval )
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Fill in cmp_info */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
SUBDBG( "pfm_get_num_events(%p)\n", &ncnt );
|
|
Packit |
577717 |
if ( ( retval = pfm_get_num_events( &ncnt ) ) != PFMLIB_SUCCESS ) {
|
|
Packit |
577717 |
PAPIERROR( "pfm_get_num_events(%p): %s\n", &ncnt,
|
|
Packit |
577717 |
pfm_strerror( retval ) );
|
|
Packit |
577717 |
return PAPI_ESYS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
SUBDBG( "pfm_get_num_events: %d\n", ncnt );
|
|
Packit |
577717 |
my_vector->cmp_info.num_native_events = ncnt;
|
|
Packit |
577717 |
num_native_events = ncnt;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
pfm_get_num_counters( ( unsigned int * ) &my_vector->cmp_info.num_cntrs );
|
|
Packit |
577717 |
SUBDBG( "pfm_get_num_counters: %d\n", my_vector->cmp_info.num_cntrs );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( _papi_hwi_system_info.hw_info.vendor == PAPI_VENDOR_INTEL ) {
|
|
Packit |
577717 |
/* Pentium4 */
|
|
Packit |
577717 |
if ( _papi_hwi_system_info.hw_info.cpuid_family == 15 ) {
|
|
Packit |
577717 |
PAPI_NATIVE_EVENT_AND_MASK = 0x000000ff;
|
|
Packit |
577717 |
PAPI_NATIVE_UMASK_AND_MASK = 0x0fffff00;
|
|
Packit |
577717 |
PAPI_NATIVE_UMASK_SHIFT = 8;
|
|
Packit |
577717 |
/* Itanium2 */
|
|
Packit |
577717 |
} else if ( _papi_hwi_system_info.hw_info.cpuid_family == 31 ||
|
|
Packit |
577717 |
_papi_hwi_system_info.hw_info.cpuid_family == 32 ) {
|
|
Packit |
577717 |
PAPI_NATIVE_EVENT_AND_MASK = 0x00000fff;
|
|
Packit |
577717 |
PAPI_NATIVE_UMASK_AND_MASK = 0x0ffff000;
|
|
Packit |
577717 |
PAPI_NATIVE_UMASK_SHIFT = 12;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
long long generate_p4_event(long long escr,
|
|
Packit |
577717 |
long long cccr,
|
|
Packit |
577717 |
long long escr_addr) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* RAW events specification
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Bits Meaning
|
|
Packit |
577717 |
* ----- -------
|
|
Packit |
577717 |
* 0-6 Metric value from enum P4_PEBS_METRIC (if needed)
|
|
Packit |
577717 |
* 7-11 Reserved, set to 0
|
|
Packit |
577717 |
* 12-31 Bits 12-31 of CCCR register (Intel SDM Vol 3)
|
|
Packit |
577717 |
* 32-56 Bits 0-24 of ESCR register (Intel SDM Vol 3)
|
|
Packit |
577717 |
* 57-62 Event key from enum P4_EVENTS
|
|
Packit |
577717 |
* 63 Reserved, set to 0
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
enum P4_EVENTS {
|
|
Packit |
577717 |
P4_EVENT_TC_DELIVER_MODE,
|
|
Packit |
577717 |
P4_EVENT_BPU_FETCH_REQUEST,
|
|
Packit |
577717 |
P4_EVENT_ITLB_REFERENCE,
|
|
Packit |
577717 |
P4_EVENT_MEMORY_CANCEL,
|
|
Packit |
577717 |
P4_EVENT_MEMORY_COMPLETE,
|
|
Packit |
577717 |
P4_EVENT_LOAD_PORT_REPLAY,
|
|
Packit |
577717 |
P4_EVENT_STORE_PORT_REPLAY,
|
|
Packit |
577717 |
P4_EVENT_MOB_LOAD_REPLAY,
|
|
Packit |
577717 |
P4_EVENT_PAGE_WALK_TYPE,
|
|
Packit |
577717 |
P4_EVENT_BSQ_CACHE_REFERENCE,
|
|
Packit |
577717 |
P4_EVENT_IOQ_ALLOCATION,
|
|
Packit |
577717 |
P4_EVENT_IOQ_ACTIVE_ENTRIES,
|
|
Packit |
577717 |
P4_EVENT_FSB_DATA_ACTIVITY,
|
|
Packit |
577717 |
P4_EVENT_BSQ_ALLOCATION,
|
|
Packit |
577717 |
P4_EVENT_BSQ_ACTIVE_ENTRIES,
|
|
Packit |
577717 |
P4_EVENT_SSE_INPUT_ASSIST,
|
|
Packit |
577717 |
P4_EVENT_PACKED_SP_UOP,
|
|
Packit |
577717 |
P4_EVENT_PACKED_DP_UOP,
|
|
Packit |
577717 |
P4_EVENT_SCALAR_SP_UOP,
|
|
Packit |
577717 |
P4_EVENT_SCALAR_DP_UOP,
|
|
Packit |
577717 |
P4_EVENT_64BIT_MMX_UOP,
|
|
Packit |
577717 |
P4_EVENT_128BIT_MMX_UOP,
|
|
Packit |
577717 |
P4_EVENT_X87_FP_UOP,
|
|
Packit |
577717 |
P4_EVENT_TC_MISC,
|
|
Packit |
577717 |
P4_EVENT_GLOBAL_POWER_EVENTS,
|
|
Packit |
577717 |
P4_EVENT_TC_MS_XFER,
|
|
Packit |
577717 |
P4_EVENT_UOP_QUEUE_WRITES,
|
|
Packit |
577717 |
P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE,
|
|
Packit |
577717 |
P4_EVENT_RETIRED_BRANCH_TYPE,
|
|
Packit |
577717 |
P4_EVENT_RESOURCE_STALL,
|
|
Packit |
577717 |
P4_EVENT_WC_BUFFER,
|
|
Packit |
577717 |
P4_EVENT_B2B_CYCLES,
|
|
Packit |
577717 |
P4_EVENT_BNR,
|
|
Packit |
577717 |
P4_EVENT_SNOOP,
|
|
Packit |
577717 |
P4_EVENT_RESPONSE,
|
|
Packit |
577717 |
P4_EVENT_FRONT_END_EVENT,
|
|
Packit |
577717 |
P4_EVENT_EXECUTION_EVENT,
|
|
Packit |
577717 |
P4_EVENT_REPLAY_EVENT,
|
|
Packit |
577717 |
P4_EVENT_INSTR_RETIRED,
|
|
Packit |
577717 |
P4_EVENT_UOPS_RETIRED,
|
|
Packit |
577717 |
P4_EVENT_UOP_TYPE,
|
|
Packit |
577717 |
P4_EVENT_BRANCH_RETIRED,
|
|
Packit |
577717 |
P4_EVENT_MISPRED_BRANCH_RETIRED,
|
|
Packit |
577717 |
P4_EVENT_X87_ASSIST,
|
|
Packit |
577717 |
P4_EVENT_MACHINE_CLEAR,
|
|
Packit |
577717 |
P4_EVENT_INSTR_COMPLETED,
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int eventsel=(escr>>25)&0x3f;
|
|
Packit |
577717 |
int cccrsel=(cccr>>13)&0x7;
|
|
Packit |
577717 |
int event_key=-1;
|
|
Packit |
577717 |
long long pe_event;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
switch(eventsel) {
|
|
Packit |
577717 |
case 0x1: if (cccrsel==1) {
|
|
Packit |
577717 |
if (escr_addr>0x3c8) {
|
|
Packit |
577717 |
// tc_escr0,1 0x3c4
|
|
Packit |
577717 |
event_key=P4_EVENT_TC_DELIVER_MODE;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else {
|
|
Packit |
577717 |
// alf_escr0, 0x3ca
|
|
Packit |
577717 |
event_key=P4_EVENT_RESOURCE_STALL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==4) {
|
|
Packit |
577717 |
if (escr_addr<0x3af) {
|
|
Packit |
577717 |
// pmh_escr0,1 0x3ac
|
|
Packit |
577717 |
event_key=P4_EVENT_PAGE_WALK_TYPE;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else {
|
|
Packit |
577717 |
// cru_escr0, 3b8 cccr=04
|
|
Packit |
577717 |
event_key=P4_EVENT_UOPS_RETIRED;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case 0x2: if (cccrsel==5) {
|
|
Packit |
577717 |
if (escr_addr<0x3a8) {
|
|
Packit |
577717 |
// MSR_DAC_ESCR0 / MSR_DAC_ESCR1
|
|
Packit |
577717 |
event_key=P4_EVENT_MEMORY_CANCEL;
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
//MSR_CRU_ESCR2, MSR_CRU_ESCR3
|
|
Packit |
577717 |
event_key=P4_EVENT_MACHINE_CLEAR;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
} else if (cccrsel==1) {
|
|
Packit |
577717 |
event_key=P4_EVENT_64BIT_MMX_UOP;
|
|
Packit |
577717 |
} else if (cccrsel==4) {
|
|
Packit |
577717 |
event_key=P4_EVENT_INSTR_RETIRED;
|
|
Packit |
577717 |
} else if (cccrsel==2) {
|
|
Packit |
577717 |
event_key=P4_EVENT_UOP_TYPE;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case 0x3: if (cccrsel==0) {
|
|
Packit |
577717 |
event_key=P4_EVENT_BPU_FETCH_REQUEST;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==2) {
|
|
Packit |
577717 |
event_key=P4_EVENT_MOB_LOAD_REPLAY;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==6) {
|
|
Packit |
577717 |
event_key=P4_EVENT_IOQ_ALLOCATION;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==4) {
|
|
Packit |
577717 |
event_key=P4_EVENT_MISPRED_BRANCH_RETIRED;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==5) {
|
|
Packit |
577717 |
event_key=P4_EVENT_X87_ASSIST;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case 0x4: if (cccrsel==2) {
|
|
Packit |
577717 |
if (escr_addr<0x3b0) {
|
|
Packit |
577717 |
// saat, 0x3ae
|
|
Packit |
577717 |
event_key=P4_EVENT_LOAD_PORT_REPLAY;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else {
|
|
Packit |
577717 |
// tbpu 0x3c2
|
|
Packit |
577717 |
event_key=P4_EVENT_RETIRED_BRANCH_TYPE;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==1) {
|
|
Packit |
577717 |
event_key=P4_EVENT_X87_FP_UOP;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==3) {
|
|
Packit |
577717 |
event_key=P4_EVENT_RESPONSE;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case 0x5: if (cccrsel==2) {
|
|
Packit |
577717 |
if (escr_addr<0x3b0) {
|
|
Packit |
577717 |
// saat, 0x3ae
|
|
Packit |
577717 |
event_key=P4_EVENT_STORE_PORT_REPLAY;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else {
|
|
Packit |
577717 |
// tbpu, 0x3c2
|
|
Packit |
577717 |
event_key=P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==7) {
|
|
Packit |
577717 |
event_key=P4_EVENT_BSQ_ALLOCATION;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==0) {
|
|
Packit |
577717 |
event_key=P4_EVENT_TC_MS_XFER;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==5) {
|
|
Packit |
577717 |
event_key=P4_EVENT_WC_BUFFER;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case 0x6: if (cccrsel==7) {
|
|
Packit |
577717 |
event_key=P4_EVENT_BSQ_ACTIVE_ENTRIES;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==1) {
|
|
Packit |
577717 |
event_key=P4_EVENT_TC_MISC;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==3) {
|
|
Packit |
577717 |
event_key=P4_EVENT_SNOOP;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==5) {
|
|
Packit |
577717 |
event_key=P4_EVENT_BRANCH_RETIRED;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case 0x7: event_key=P4_EVENT_INSTR_COMPLETED; break;
|
|
Packit |
577717 |
case 0x8: if (cccrsel==2) {
|
|
Packit |
577717 |
event_key=P4_EVENT_MEMORY_COMPLETE;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==1) {
|
|
Packit |
577717 |
event_key=P4_EVENT_PACKED_SP_UOP;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==3) {
|
|
Packit |
577717 |
event_key=P4_EVENT_BNR;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==5) {
|
|
Packit |
577717 |
event_key=P4_EVENT_FRONT_END_EVENT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case 0x9: if (cccrsel==0) {
|
|
Packit |
577717 |
event_key=P4_EVENT_UOP_QUEUE_WRITES;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==5) {
|
|
Packit |
577717 |
event_key=P4_EVENT_REPLAY_EVENT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case 0xa: event_key=P4_EVENT_SCALAR_SP_UOP; break;
|
|
Packit |
577717 |
case 0xc: if (cccrsel==7) {
|
|
Packit |
577717 |
event_key=P4_EVENT_BSQ_CACHE_REFERENCE;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==1) {
|
|
Packit |
577717 |
event_key=P4_EVENT_PACKED_DP_UOP;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==5) {
|
|
Packit |
577717 |
event_key=P4_EVENT_EXECUTION_EVENT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case 0xe: event_key=P4_EVENT_SCALAR_DP_UOP; break;
|
|
Packit |
577717 |
case 0x13: event_key=P4_EVENT_GLOBAL_POWER_EVENTS; break;
|
|
Packit |
577717 |
case 0x16: event_key=P4_EVENT_B2B_CYCLES; break;
|
|
Packit |
577717 |
case 0x17: event_key=P4_EVENT_FSB_DATA_ACTIVITY; break;
|
|
Packit |
577717 |
case 0x18: event_key=P4_EVENT_ITLB_REFERENCE; break;
|
|
Packit |
577717 |
case 0x1a: if (cccrsel==6) {
|
|
Packit |
577717 |
event_key=P4_EVENT_IOQ_ACTIVE_ENTRIES;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (cccrsel==1) {
|
|
Packit |
577717 |
event_key=P4_EVENT_128BIT_MMX_UOP;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case 0x34: event_key= P4_EVENT_SSE_INPUT_ASSIST; break;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
pe_event=(escr&0x1ffffff)<<32;
|
|
Packit |
577717 |
pe_event|=(cccr&0xfffff000);
|
|
Packit |
577717 |
pe_event|=(((long long)(event_key))<<57);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return pe_event;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
typedef pfmlib_event_t pfm_register_t;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_libpfm_setup_counters( struct perf_event_attr *attr,
|
|
Packit |
577717 |
hwd_register_t *ni_bits ) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int ret,pe_event;
|
|
Packit |
577717 |
(void)ni_bits;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* We need an event code that is common across all counters.
|
|
Packit |
577717 |
* The implementation is required to know how to translate the supplied
|
|
Packit |
577717 |
* code to whichever counter it ends up on.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#if defined(__powerpc__)
|
|
Packit |
577717 |
int code;
|
|
Packit |
577717 |
ret = pfm_get_event_code_counter( ( ( pfm_register_t * ) ni_bits )->event, 0, &code );
|
|
Packit |
577717 |
if ( ret ) {
|
|
Packit |
577717 |
/* Unrecognized code, but should never happen */
|
|
Packit |
577717 |
return PAPI_EBUG;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
pe_event = code;
|
|
Packit |
577717 |
SUBDBG( "Stuffing native event index (code %#x, raw code %#x) into events array.\n",
|
|
Packit |
577717 |
( ( pfm_register_t * ) ni_bits )->event, code );
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
|
|
Packit |
577717 |
pfmlib_input_param_t inp;
|
|
Packit |
577717 |
pfmlib_output_param_t outp;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
memset( &inp, 0, sizeof ( inp ) );
|
|
Packit |
577717 |
memset( &outp, 0, sizeof ( outp ) );
|
|
Packit |
577717 |
inp.pfp_event_count = 1;
|
|
Packit |
577717 |
inp.pfp_dfl_plm = PAPI_DOM_USER;
|
|
Packit |
577717 |
pfm_regmask_set( &inp.pfp_unavail_pmcs, 16 ); // mark fixed counters as unavailable
|
|
Packit |
577717 |
|
|
Packit |
577717 |
inp.pfp_events[0] = *( ( pfm_register_t * ) ni_bits );
|
|
Packit |
577717 |
ret = pfm_dispatch_events( &inp, NULL, &outp, NULL );
|
|
Packit |
577717 |
if (ret != PFMLIB_SUCCESS) {
|
|
Packit |
577717 |
SUBDBG( "Error: pfm_dispatch_events returned: %d\n", ret);
|
|
Packit |
577717 |
return PAPI_ESYS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Special case p4 */
|
|
Packit |
577717 |
if (( _papi_hwi_system_info.hw_info.vendor == PAPI_VENDOR_INTEL ) &&
|
|
Packit |
577717 |
( _papi_hwi_system_info.hw_info.cpuid_family == 15)) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
pe_event=generate_p4_event( outp.pfp_pmcs[0].reg_value, /* escr */
|
|
Packit |
577717 |
outp.pfp_pmcs[1].reg_value, /* cccr */
|
|
Packit |
577717 |
outp.pfp_pmcs[0].reg_addr); /* escr_addr */
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else {
|
|
Packit |
577717 |
pe_event = outp.pfp_pmcs[0].reg_value;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
SUBDBG( "pe_event: %#llx\n", outp.pfp_pmcs[0].reg_value );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
attr->config=pe_event;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* for libpfm3 we currently only handle RAW type */
|
|
Packit |
577717 |
attr->type=PERF_TYPE_RAW;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_libpfm_shutdown(void) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
SUBDBG("shutdown\n");
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|