perfctr-x86.c File Reference

Include dependency graph for perfctr-x86.c:

Go to the source code of this file.

Defines

#define P4_VEC   "SSE"
#define P4_FPU   " X87 SSE_DP"
#define AMD_FPU   "SPECULATIVE"
#define P4_REPLAY_REAL_MASK   0x00000003

Functions

int _perfctr_init_component (int)
int _perfctr_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
void _perfctr_dispatch_timer (int signal, hwd_siginfo_t *si, void *context)
int _perfctr_init_thread (hwd_context_t *ctx)
int _perfctr_shutdown_thread (hwd_context_t *ctx)
static int is_pentium4 (void)
static void print_alloc (X86_reg_alloc_t *a)
void print_control (const struct perfctr_cpu_control *control)
static int _x86_init_control_state (hwd_control_state_t *ptr)
int _x86_set_domain (hwd_control_state_t *cntrl, int domain)
static int _bpt_map_avail (hwd_reg_alloc_t *dst, int ctr)
static void _bpt_map_set (hwd_reg_alloc_t *dst, int ctr)
static int _bpt_map_exclusive (hwd_reg_alloc_t *dst)
static int _bpt_map_shared (hwd_reg_alloc_t *dst, hwd_reg_alloc_t *src)
static void _bpt_map_preempt (hwd_reg_alloc_t *dst, hwd_reg_alloc_t *src)
static void _bpt_map_update (hwd_reg_alloc_t *dst, hwd_reg_alloc_t *src)
static int _x86_allocate_registers (EventSetInfo_t *ESI)
static void clear_cs_events (hwd_control_state_t *this_state)
static int _x86_update_control_state (hwd_control_state_t *this_state, NativeInfo_t *native, int count, hwd_context_t *ctx)
static int _x86_start (hwd_context_t *ctx, hwd_control_state_t *state)
static int _x86_stop (hwd_context_t *ctx, hwd_control_state_t *state)
static int _x86_read (hwd_context_t *ctx, hwd_control_state_t *spc, long long **dp, int flags)
static int _x86_reset (hwd_context_t *ctx, hwd_control_state_t *cntrl)
static void swap_events (EventSetInfo_t *ESI, struct hwd_pmc_control *contr, int cntr1, int cntr2)
static int _x86_set_overflow (EventSetInfo_t *ESI, int EventIndex, int threshold)
static int _x86_stop_profiling (ThreadInfo_t *master, EventSetInfo_t *ESI)
static int _pfm_get_counter_info (unsigned int event, unsigned int *selector, int *code)
int _papi_libpfm_ntv_code_to_bits_perfctr (unsigned int EventCode, hwd_register_t *newbits)

Variables

papi_mdi_t _papi_hwi_system_info
papi_vector_t _perfctr_vector
pentium4_escr_reg_t pentium4_escrs []
pentium4_cccr_reg_t pentium4_cccrs []
pentium4_event_t pentium4_events []
static pentium4_replay_regs_t p4_replay_regs []
static int pfm2intel []

Define Documentation

#define AMD_FPU   "SPECULATIVE"

Definition at line 72 of file perfctr-x86.c.

#define P4_FPU   " X87 SSE_DP"

Definition at line 61 of file perfctr-x86.c.

#define P4_REPLAY_REAL_MASK   0x00000003

Definition at line 903 of file perfctr-x86.c.

#define P4_VEC   "SSE"

Definition at line 51 of file perfctr-x86.c.


Function Documentation

static int _bpt_map_avail ( hwd_reg_alloc_t dst,
int  ctr 
) [static]

Definition at line 266 of file perfctr-x86.c.

00267 {
00268     return ( int ) ( dst->ra_selector & ( 1 << ctr ) );
00269 }

static int _bpt_map_exclusive ( hwd_reg_alloc_t dst  )  [static]

Definition at line 295 of file perfctr-x86.c.

00296 {
00297     return ( dst->ra_rank == 1 );
00298 }

static void _bpt_map_preempt ( hwd_reg_alloc_t dst,
hwd_reg_alloc_t src 
) [static]

Definition at line 343 of file perfctr-x86.c.

00344 {
00345     int i;
00346     unsigned shared;
00347 
00348     if ( is_pentium4() ) {
00349 #ifdef DEBUG
00350         SUBDBG( "src, dst\n" );
00351         print_alloc( src );
00352         print_alloc( dst );
00353 #endif
00354 
00355         /* check for a pebs conflict */
00356         /* pebs enables must both be non-zero */
00357         i = ( ( ( dst->ra_bits.pebs_enable && src->ra_bits.pebs_enable ) &&
00358                 /* and not equal to each other */
00359                 ( dst->ra_bits.pebs_enable != src->ra_bits.pebs_enable ) ) ||
00360               /* same for pebs_matrix_vert */
00361               ( ( dst->ra_bits.pebs_matrix_vert &&
00362                   src->ra_bits.pebs_matrix_vert )
00363                 && ( dst->ra_bits.pebs_matrix_vert !=
00364                      src->ra_bits.pebs_matrix_vert ) ) );
00365         if ( i ) {
00366             SUBDBG( "pebs conflict! clearing selector\n" );
00367             dst->ra_selector = 0;
00368             return;
00369         } else {
00370             /* remove counters referenced by any shared escrs */
00371             if ( ( dst->ra_escr[0] == src->ra_escr[0] ) &&
00372                  ( ( int ) dst->ra_escr[0] != -1 ) ) {
00373                 dst->ra_selector &= ~dst->ra_bits.counter[0];
00374                 dst->ra_escr[0] = -1;
00375             }
00376             if ( ( dst->ra_escr[1] == src->ra_escr[1] ) &&
00377                  ( ( int ) dst->ra_escr[1] != -1 ) ) {
00378                 dst->ra_selector &= ~dst->ra_bits.counter[1];
00379                 dst->ra_escr[1] = -1;
00380             }
00381 
00382             /* remove any remaining shared counters */
00383             shared = ( dst->ra_selector & src->ra_selector );
00384             if ( shared )
00385                 dst->ra_selector ^= shared;
00386         }
00387         /* recompute rank */
00388         for ( i = 0, dst->ra_rank = 0; i < MAX_COUNTERS; i++ )
00389             if ( dst->ra_selector & ( 1 << i ) )
00390                 dst->ra_rank++;
00391 #ifdef DEBUG
00392         SUBDBG( "new dst\n" );
00393         print_alloc( dst );
00394 #endif
00395     } else {
00396         shared = dst->ra_selector & src->ra_selector;
00397         if ( shared )
00398             dst->ra_selector ^= shared;
00399         for ( i = 0, dst->ra_rank = 0; i < MAX_COUNTERS; i++ )
00400             if ( dst->ra_selector & ( 1 << i ) )
00401                 dst->ra_rank++;
00402     }
00403 }

Here is the call graph for this function:

static void _bpt_map_set ( hwd_reg_alloc_t dst,
int  ctr 
) [static]

Definition at line 275 of file perfctr-x86.c.

00276 {
00277     dst->ra_selector = ( unsigned int ) ( 1 << ctr );
00278     dst->ra_rank = 1;
00279 
00280     if ( is_pentium4() ) {
00281         /* Pentium 4 requires that both an escr and a counter are selected.
00282            Find which counter mask contains this counter.
00283            Set the opposite escr to empty (-1) */
00284         if ( dst->ra_bits.counter[0] & dst->ra_selector )
00285             dst->ra_escr[1] = -1;
00286         else
00287             dst->ra_escr[0] = -1;
00288     }
00289 }

Here is the call graph for this function:

static int _bpt_map_shared ( hwd_reg_alloc_t dst,
hwd_reg_alloc_t src 
) [static]

Definition at line 305 of file perfctr-x86.c.

00306 {
00307   if ( is_pentium4() ) {
00308         int retval1, retval2;
00309         /* Pentium 4 needs to check for conflict of both counters and esc registers */
00310         /* selectors must share bits */
00311         retval1 = ( ( dst->ra_selector & src->ra_selector ) ||
00312                     /* or escrs must equal each other and not be set to -1 */
00313                     ( ( dst->ra_escr[0] == src->ra_escr[0] ) &&
00314                       ( ( int ) dst->ra_escr[0] != -1 ) ) ||
00315                     ( ( dst->ra_escr[1] == src->ra_escr[1] ) &&
00316                       ( ( int ) dst->ra_escr[1] != -1 ) ) );
00317         /* Pentium 4 also needs to check for conflict on pebs registers */
00318         /* pebs enables must both be non-zero */
00319         retval2 =
00320             ( ( ( dst->ra_bits.pebs_enable && src->ra_bits.pebs_enable ) &&
00321                 /* and not equal to each other */
00322                 ( dst->ra_bits.pebs_enable != src->ra_bits.pebs_enable ) ) ||
00323               /* same for pebs_matrix_vert */
00324               ( ( dst->ra_bits.pebs_matrix_vert &&
00325                   src->ra_bits.pebs_matrix_vert ) &&
00326                 ( dst->ra_bits.pebs_matrix_vert !=
00327                   src->ra_bits.pebs_matrix_vert ) ) );
00328         if ( retval2 ) {
00329             SUBDBG( "pebs conflict!\n" );
00330         }
00331         return ( retval1 | retval2 );
00332     }
00333 
00334     return ( int ) ( dst->ra_selector & src->ra_selector );
00335 }

Here is the call graph for this function:

static void _bpt_map_update ( hwd_reg_alloc_t dst,
hwd_reg_alloc_t src 
) [static]

Definition at line 406 of file perfctr-x86.c.

00407 {
00408     dst->ra_selector = src->ra_selector;
00409 
00410     if ( is_pentium4() ) {
00411         dst->ra_escr[0] = src->ra_escr[0];
00412         dst->ra_escr[1] = src->ra_escr[1];
00413     }
00414 }

Here is the call graph for this function:

int _papi_libpfm_ntv_code_to_bits_perfctr ( unsigned int  EventCode,
hwd_register_t newbits 
)

Definition at line 1015 of file perfctr-x86.c.

01017 {
01018     unsigned int event, umask;
01019 
01020     X86_register_t *bits = (X86_register_t *)newbits;
01021 
01022     if ( is_pentium4() ) {
01023        pentium4_escr_value_t escr_value;
01024        pentium4_cccr_value_t cccr_value;
01025        unsigned int num_masks, replay_mask, unit_masks[12];
01026        unsigned int event_mask;
01027        unsigned int tag_value, tag_enable;
01028        unsigned int i;
01029        int j, escr, cccr, pmd;
01030 
01031        if ( _pfm_decode_native_event( EventCode, &event, &umask ) != PAPI_OK )
01032       return PAPI_ENOEVNT;
01033 
01034        /* for each allowed escr (1 or 2) find the allowed cccrs.
01035       for each allowed cccr find the pmd index
01036       convert to an intel counter number; or it into bits->counter */
01037        for ( i = 0; i < MAX_ESCRS_PER_EVENT; i++ ) {
01038       bits->counter[i] = 0;
01039       escr = pentium4_events[event].allowed_escrs[i];
01040       if ( escr < 0 ) {
01041          continue;
01042       }
01043 
01044       bits->escr[i] = escr;
01045 
01046       for ( j = 0; j < MAX_CCCRS_PER_ESCR; j++ ) {
01047          cccr = pentium4_escrs[escr].allowed_cccrs[j];
01048          if ( cccr < 0 ) {
01049         continue;
01050          }
01051 
01052          pmd = pentium4_cccrs[cccr].pmd;
01053          bits->counter[i] |= ( 1 << pfm2intel[pmd] );
01054       }
01055        }
01056 
01057        /* if there's only one valid escr, copy the values */
01058        if ( escr < 0 ) {
01059       bits->escr[1] = bits->escr[0];
01060       bits->counter[1] = bits->counter[0];
01061        }
01062 
01063        /* Calculate the event-mask value. Invalid masks
01064     * specified by the caller are ignored. */
01065        tag_value = 0;
01066        tag_enable = 0;
01067        event_mask = _pfm_convert_umask( event, umask );
01068 
01069        if ( event_mask & 0xF0000 ) {
01070       tag_enable = 1;
01071       tag_value = ( ( event_mask & 0xF0000 ) >> EVENT_MASK_BITS );
01072        }
01073 
01074        event_mask &= 0x0FFFF;   /* mask off possible tag bits */
01075 
01076        /* Set up the ESCR and CCCR register values. */
01077        escr_value.val = 0;
01078        escr_value.bits.t1_usr = 0;  /* controlled by kernel */
01079        escr_value.bits.t1_os = 0;   /* controlled by kernel */
01080 //    escr_value.bits.t0_usr       = (plm & PFM_PLM3) ? 1 : 0;
01081 //    escr_value.bits.t0_os        = (plm & PFM_PLM0) ? 1 : 0;
01082        escr_value.bits.tag_enable = tag_enable;
01083        escr_value.bits.tag_value = tag_value;
01084        escr_value.bits.event_mask = event_mask;
01085        escr_value.bits.event_select = pentium4_events[event].event_select;
01086        escr_value.bits.reserved = 0;
01087 
01088        /* initialize the proper bits in the cccr register */
01089        cccr_value.val = 0;
01090        cccr_value.bits.reserved1 = 0;
01091        cccr_value.bits.enable = 1;
01092        cccr_value.bits.escr_select = pentium4_events[event].escr_select;
01093        cccr_value.bits.active_thread = 3;   
01094        /* FIXME: This is set to count when either logical
01095     *        CPU is active. Need a way to distinguish
01096     *        between logical CPUs when HT is enabled.
01097         *        the docs say these bits should always 
01098     *        be set.                                  */
01099        cccr_value.bits.compare = 0; 
01100        /* FIXME: What do we do with "threshold" settings? */
01101        cccr_value.bits.complement = 0;  
01102        /* FIXME: What do we do with "threshold" settings? */
01103        cccr_value.bits.threshold = 0;   
01104        /* FIXME: What do we do with "threshold" settings? */
01105        cccr_value.bits.force_ovf = 0;   
01106        /* FIXME: Do we want to allow "forcing" overflow
01107         *        interrupts on all counter increments? */
01108        cccr_value.bits.ovf_pmi_t0 = 0;
01109        cccr_value.bits.ovf_pmi_t1 = 0;  
01110        /* PMI taken care of by kernel typically */
01111        cccr_value.bits.reserved2 = 0;
01112        cccr_value.bits.cascade = 0; 
01113        /* FIXME: How do we handle "cascading" counters? */
01114        cccr_value.bits.overflow = 0;
01115 
01116        /* these flags are always zero, from what I can tell... */
01117        bits->pebs_enable = 0;   /* flag for PEBS counting */
01118        bits->pebs_matrix_vert = 0;  
01119        /* flag for PEBS_MATRIX_VERT, whatever that is */
01120 
01121        /* ...unless the event is replay_event */
01122        if ( !strcmp( pentium4_events[event].name, "replay_event" ) ) {
01123       escr_value.bits.event_mask = event_mask & P4_REPLAY_REAL_MASK;
01124       num_masks = prepare_umask( umask, unit_masks );
01125       for ( i = 0; i < num_masks; i++ ) {
01126          replay_mask = unit_masks[i];
01127          if ( replay_mask > 1 && replay_mask < 11 ) {
01128             /* process each valid mask we find */
01129         bits->pebs_enable |= p4_replay_regs[replay_mask].enb;
01130         bits->pebs_matrix_vert |= p4_replay_regs[replay_mask].mat_vert;
01131          }
01132       }
01133        }
01134 
01135        /* store the escr and cccr values */
01136        bits->event = escr_value.val;
01137        bits->cccr = cccr_value.val;
01138        bits->ireset = 0;     /* I don't really know what this does */
01139        SUBDBG( "escr: 0x%lx; cccr:  0x%lx\n", escr_value.val, cccr_value.val );
01140     } else {
01141 
01142        int ret, code;
01143 
01144        if ( _pfm_decode_native_event( EventCode, &event, &umask ) != PAPI_OK )
01145       return PAPI_ENOEVNT;
01146 
01147        if ( ( ret = _pfm_get_counter_info( event, &bits->selector,
01148                           &code ) ) != PAPI_OK )
01149       return ret;
01150 
01151        bits->counter_cmd=(int) (code | ((_pfm_convert_umask(event,umask))<< 8) );
01152 
01153        SUBDBG( "selector: %#x\n", bits->selector );
01154        SUBDBG( "event: %#x; umask: %#x; code: %#x; cmd: %#x\n", event,
01155            umask, code, ( ( hwd_register_t * ) bits )->counter_cmd );
01156     }
01157 
01158     return PAPI_OK;
01159 }

Here is the call graph for this function:

int _perfctr_ctl ( hwd_context_t ctx,
int  code,
_papi_int_option_t option 
)

Definition at line 289 of file perfctr.c.

00290 {
00291     ( void ) ctx;            /*unused */
00292     switch ( code ) {
00293     case PAPI_DOMAIN:
00294     case PAPI_DEFDOM:
00295 #if defined(PPC64)
00296         return ( _perfctr_vector.
00297                  set_domain( option->domain.ESI, option->domain.domain ) );
00298 #else
00299         return ( _perfctr_vector.
00300                  set_domain( option->domain.ESI->ctl_state,
00301                              option->domain.domain ) );
00302 #endif
00303     case PAPI_GRANUL:
00304     case PAPI_DEFGRN:
00305         return PAPI_ECMP;
00306     case PAPI_ATTACH:
00307         return ( attach( option->attach.ESI->ctl_state, option->attach.tid ) );
00308     case PAPI_DETACH:
00309         return ( detach( option->attach.ESI->ctl_state ) );
00310     case PAPI_DEF_ITIMER:
00311     {
00312         /* flags are currently ignored, eventually the flags will be able
00313            to specify whether or not we use POSIX itimers (clock_gettimer) */
00314         if ( ( option->itimer.itimer_num == ITIMER_REAL ) &&
00315              ( option->itimer.itimer_sig != SIGALRM ) )
00316             return PAPI_EINVAL;
00317         if ( ( option->itimer.itimer_num == ITIMER_VIRTUAL ) &&
00318              ( option->itimer.itimer_sig != SIGVTALRM ) )
00319             return PAPI_EINVAL;
00320         if ( ( option->itimer.itimer_num == ITIMER_PROF ) &&
00321              ( option->itimer.itimer_sig != SIGPROF ) )
00322             return PAPI_EINVAL;
00323         if ( option->itimer.ns > 0 )
00324             option->itimer.ns = round_requested_ns( option->itimer.ns );
00325         /* At this point, we assume the user knows what he or
00326            she is doing, they maybe doing something arch specific */
00327         return PAPI_OK;
00328     }
00329     case PAPI_DEF_MPX_NS:
00330     {
00331         option->multiplex.ns =
00332             ( unsigned long ) round_requested_ns( ( int ) option->multiplex.
00333                                                   ns );
00334         return ( PAPI_OK );
00335     }
00336     case PAPI_DEF_ITIMER_NS:
00337     {
00338         option->itimer.ns = round_requested_ns( option->itimer.ns );
00339         return ( PAPI_OK );
00340     }
00341     default:
00342         return ( PAPI_ENOSUPP );
00343     }
00344 }

Here is the call graph for this function:

void _perfctr_dispatch_timer ( int  signal,
hwd_siginfo_t si,
void *  context 
)
int _perfctr_init_component ( int   ) 

Definition at line 107 of file perfctr.c.

00108 {
00109     int retval;
00110     struct perfctr_info info;
00111     char abiv[PAPI_MIN_STR_LEN];
00112 
00113 #if defined(PERFCTR26)
00114     int fd;
00115 #else
00116     struct vperfctr *dev;
00117 #endif
00118 
00119 #if defined(PERFCTR26)
00120     /* Get info from the kernel */
00121     /* Use lower level calls per Mikael to get the perfctr info
00122        without actually creating a new kernel-side state.
00123        Also, close the fd immediately after retrieving the info.
00124        This is much lighter weight and doesn't reserve the counter
00125        resources. Also compatible with perfctr 2.6.14.
00126      */
00127     fd = _vperfctr_open( 0 );
00128     if ( fd < 0 ) {
00129        strncpy(_perfctr_vector.cmp_info.disabled_reason,
00130           VOPEN_ERROR,PAPI_MAX_STR_LEN);
00131        return PAPI_ESYS;
00132     }
00133     retval = perfctr_info( fd, &info );
00134     close( fd );
00135     if ( retval < 0 ) {
00136        strncpy(_perfctr_vector.cmp_info.disabled_reason,
00137           VINFO_ERROR,PAPI_MAX_STR_LEN);
00138        return PAPI_ESYS;
00139     }
00140 
00141     /* copy tsc multiplier to local variable        */
00142     /* this field appears in perfctr 2.6 and higher */
00143     tb_scale_factor = ( long long ) info.tsc_to_cpu_mult;
00144 #else
00145     /* Opened once for all threads. */
00146     if ( ( dev = vperfctr_open(  ) ) == NULL ) {
00147        strncpy(_perfctr_vector.cmp_info.disabled_reason,
00148           VOPEN_ERROR,PAPI_MAX_STR_LEN);
00149        return PAPI_ESYS;
00150     }
00151     SUBDBG( "_perfctr_init_component vperfctr_open = %p\n", dev );
00152 
00153     /* Get info from the kernel */
00154     retval = vperfctr_info( dev, &info );
00155     if ( retval < 0 ) {
00156        strncpy(_perfctr_vector.cmp_info.disabled_reason,
00157           VINFO_ERROR,PAPI_MAX_STR_LEN);
00158         return ( PAPI_ESYS );
00159     }
00160     vperfctr_close( dev );
00161 #endif
00162 
00163     /* Fill in what we can of the papi_system_info. */
00164     retval = _papi_os_vector.get_system_info( &_papi_hwi_system_info );
00165     if ( retval != PAPI_OK )
00166         return ( retval );
00167 
00168     /* Setup memory info */
00169     retval = _papi_os_vector.get_memory_info( &_papi_hwi_system_info.hw_info,
00170                            ( int ) info.cpu_type );
00171     if ( retval )
00172         return ( retval );
00173 
00174     strcpy( _perfctr_vector.cmp_info.name,"perfctr.c" );
00175     strcpy( _perfctr_vector.cmp_info.version, "$Revision$" );
00176     sprintf( abiv, "0x%08X", info.abi_version );
00177     strcpy( _perfctr_vector.cmp_info.support_version, abiv );
00178     strcpy( _perfctr_vector.cmp_info.kernel_version, info.driver_version );
00179     _perfctr_vector.cmp_info.CmpIdx = cidx;
00180     _perfctr_vector.cmp_info.num_cntrs = ( int ) PERFCTR_CPU_NRCTRS( &info );
00181         _perfctr_vector.cmp_info.num_mpx_cntrs=_perfctr_vector.cmp_info.num_cntrs;
00182     if ( info.cpu_features & PERFCTR_FEATURE_RDPMC )
00183         _perfctr_vector.cmp_info.fast_counter_read = 1;
00184     else
00185         _perfctr_vector.cmp_info.fast_counter_read = 0;
00186     _perfctr_vector.cmp_info.fast_real_timer = 1;
00187     _perfctr_vector.cmp_info.fast_virtual_timer = 1;
00188     _perfctr_vector.cmp_info.attach = 1;
00189     _perfctr_vector.cmp_info.attach_must_ptrace = 1;
00190     _perfctr_vector.cmp_info.default_domain = PAPI_DOM_USER;
00191 #if !defined(PPC64)
00192     /* AMD and Intel ia386 processors all support unit mask bits */
00193     _perfctr_vector.cmp_info.cntr_umasks = 1;
00194 #endif
00195 #if defined(PPC64)
00196     _perfctr_vector.cmp_info.available_domains =
00197         PAPI_DOM_USER | PAPI_DOM_KERNEL | PAPI_DOM_SUPERVISOR;
00198 #else
00199     _perfctr_vector.cmp_info.available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL;
00200 #endif
00201     _perfctr_vector.cmp_info.default_granularity = PAPI_GRN_THR;
00202     _perfctr_vector.cmp_info.available_granularities = PAPI_GRN_THR;
00203     if ( info.cpu_features & PERFCTR_FEATURE_PCINT )
00204         _perfctr_vector.cmp_info.hardware_intr = 1;
00205     else
00206         _perfctr_vector.cmp_info.hardware_intr = 0;
00207     SUBDBG( "Hardware/OS %s support counter generated interrupts\n",
00208             _perfctr_vector.cmp_info.hardware_intr ? "does" : "does not" );
00209 
00210     strcpy( _papi_hwi_system_info.hw_info.model_string,
00211             PERFCTR_CPU_NAME( &info ) );
00212     _papi_hwi_system_info.hw_info.model = ( int ) info.cpu_type;
00213 #if defined(PPC64)
00214     _papi_hwi_system_info.hw_info.vendor = PAPI_VENDOR_IBM;
00215     if ( strlen( _papi_hwi_system_info.hw_info.vendor_string ) == 0 )
00216         strcpy( _papi_hwi_system_info.hw_info.vendor_string, "IBM" );
00217 #else
00218     _papi_hwi_system_info.hw_info.vendor =
00219         xlate_cpu_type_to_vendor( info.cpu_type );
00220 #endif
00221 
00222     /* Setup presets last. Some platforms depend on earlier info */
00223 #if !defined(PPC64)
00224 //     retval = setup_p3_vector_table(vtable);
00225         if ( !retval )
00226                 retval = _papi_libpfm_init(&_perfctr_vector, cidx ); 
00227 #else
00228     /* Setup native and preset events */
00229 //  retval = ppc64_setup_vector_table(vtable);
00230     if ( !retval )
00231         retval = perfctr_ppc64_setup_native_table(  );
00232     if ( !retval )
00233       retval = setup_ppc64_presets( info.cpu_type, cidx );
00234 #endif
00235     if ( retval )
00236         return ( retval );
00237 
00238     return ( PAPI_OK );
00239 }

Here is the call graph for this function:

int _perfctr_init_thread ( hwd_context_t ctx  ) 

Definition at line 380 of file perfctr.c.

00381 {
00382     struct vperfctr_control tmp;
00383     int error;
00384 
00385     /* Initialize our thread/process pointer. */
00386     if ( ( ctx->perfctr = vperfctr_open(  ) ) == NULL ) {
00387 #ifdef VPERFCTR_OPEN_CREAT_EXCL
00388         /* New versions of perfctr have this, which allows us to
00389            get a previously created context, i.e. one created after
00390            a fork and now we're inside a new process that has been exec'd */
00391         if ( errno ) {
00392             if ( ( ctx->perfctr = vperfctr_open_mode( 0 ) ) == NULL ) {
00393                return PAPI_ESYS;
00394             }
00395         } else {
00396             return PAPI_ESYS;
00397         }
00398 #else
00399         return PAPI_ESYS;
00400 #endif
00401     }
00402     SUBDBG( "_papi_hwd_init vperfctr_open() = %p\n", ctx->perfctr );
00403 
00404     /* Initialize the per thread/process virtualized TSC */
00405     memset( &tmp, 0x0, sizeof ( tmp ) );
00406     tmp.cpu_control.tsc_on = 1;
00407 
00408 #ifdef VPERFCTR_CONTROL_CLOEXEC
00409     tmp.flags = VPERFCTR_CONTROL_CLOEXEC;
00410     SUBDBG( "close on exec\t\t\t%u\n", tmp.flags );
00411 #endif
00412 
00413     /* Start the per thread/process virtualized TSC */
00414     error = vperfctr_control( ctx->perfctr, &tmp );
00415     if ( error < 0 ) {
00416         SUBDBG( "starting virtualized TSC; vperfctr_control returns %d\n",
00417                 error );
00418         return PAPI_ESYS;
00419     }
00420 
00421     return PAPI_OK;
00422 }

int _perfctr_shutdown_thread ( hwd_context_t ctx  ) 

Definition at line 428 of file perfctr.c.

00429 {
00430 #ifdef DEBUG
00431     int retval = vperfctr_unlink( ctx->perfctr );
00432     SUBDBG( "_papi_hwd_shutdown vperfctr_unlink(%p) = %d\n", ctx->perfctr,
00433             retval );
00434 #else
00435     vperfctr_unlink( ctx->perfctr );
00436 #endif
00437     vperfctr_close( ctx->perfctr );
00438     SUBDBG( "_perfctr_shutdown vperfctr_close(%p)\n", ctx->perfctr );
00439     memset( ctx, 0x0, sizeof ( hwd_context_t ) );
00440     return ( PAPI_OK );
00441 }

static int _pfm_get_counter_info ( unsigned int  event,
unsigned int *  selector,
int *  code 
) [static]

Definition at line 970 of file perfctr-x86.c.

00971 {
00972     pfmlib_regmask_t cnt, impl;
00973     unsigned int num;
00974     unsigned int i, first = 1;
00975     int ret;
00976 
00977     if ( ( ret = pfm_get_event_counters( event, &cnt ) ) != PFMLIB_SUCCESS ) {
00978         PAPIERROR( "pfm_get_event_counters(%d,%p): %s", event, &cnt,
00979                    pfm_strerror( ret ) );
00980         return PAPI_ESYS;
00981     }
00982     if ( ( ret = pfm_get_num_counters( &num ) ) != PFMLIB_SUCCESS ) {
00983         PAPIERROR( "pfm_get_num_counters(%p): %s", num, pfm_strerror( ret ) );
00984         return PAPI_ESYS;
00985     }
00986     if ( ( ret = pfm_get_impl_counters( &impl ) ) != PFMLIB_SUCCESS ) {
00987         PAPIERROR( "pfm_get_impl_counters(%p): %s", &impl,
00988                    pfm_strerror( ret ) );
00989         return PAPI_ESYS;
00990     }
00991 
00992     *selector = 0;
00993     for ( i = 0; num; i++ ) {
00994         if ( pfm_regmask_isset( &impl, i ) )
00995             num--;
00996         if ( pfm_regmask_isset( &cnt, i ) ) {
00997             if ( first ) {
00998                 if ( ( ret =
00999                        pfm_get_event_code_counter( event, i,
01000                                                    code ) ) !=
01001                      PFMLIB_SUCCESS ) {
01002                     PAPIERROR( "pfm_get_event_code_counter(%d, %d, %p): %s",
01003                            event, i, code, pfm_strerror( ret ) );
01004                     return PAPI_ESYS;
01005                 }
01006                 first = 0;
01007             }
01008             *selector |= 1 << i;
01009         }
01010     }
01011     return PAPI_OK;
01012 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int _x86_allocate_registers ( EventSetInfo_t ESI  )  [static]

Definition at line 418 of file perfctr-x86.c.

00419 {
00420     int i, j, natNum;
00421     hwd_reg_alloc_t event_list[MAX_COUNTERS];
00422     hwd_register_t *ptr;
00423 
00424     /* Initialize the local structure needed
00425        for counter allocation and optimization. */
00426     natNum = ESI->NativeCount;
00427 
00428     if ( is_pentium4() ) {
00429         SUBDBG( "native event count: %d\n", natNum );
00430     }
00431 
00432     for ( i = 0; i < natNum; i++ ) {
00433         /* retrieve the mapping information about this native event */
00434         _papi_libpfm_ntv_code_to_bits( ( unsigned int ) ESI->NativeInfoArray[i].
00435                                ni_event, &event_list[i].ra_bits );
00436 
00437         if ( is_pentium4() ) {
00438             /* combine counter bit masks for both esc registers into selector */
00439             event_list[i].ra_selector =
00440                 event_list[i].ra_bits.counter[0] | event_list[i].ra_bits.
00441                 counter[1];
00442         } else {
00443             /* make sure register allocator only looks at legal registers */
00444             event_list[i].ra_selector =
00445                 event_list[i].ra_bits.selector & ALLCNTRS;
00446 #ifdef PERFCTR_X86_INTEL_CORE2
00447             if ( _papi_hwi_system_info.hw_info.model ==
00448                  PERFCTR_X86_INTEL_CORE2 )
00449                 event_list[i].ra_selector |=
00450                     ( ( event_list[i].ra_bits.
00451                         selector >> 16 ) << 2 ) & ALLCNTRS;
00452 #endif
00453         }
00454         /* calculate native event rank, which is no. of counters it can live on */
00455         event_list[i].ra_rank = 0;
00456         for ( j = 0; j < MAX_COUNTERS; j++ ) {
00457             if ( event_list[i].ra_selector & ( 1 << j ) ) {
00458                 event_list[i].ra_rank++;
00459             }
00460         }
00461 
00462         if ( is_pentium4() ) {
00463             event_list[i].ra_escr[0] = event_list[i].ra_bits.escr[0];
00464             event_list[i].ra_escr[1] = event_list[i].ra_bits.escr[1];
00465 #ifdef DEBUG
00466             SUBDBG( "i: %d\n", i );
00467             print_alloc( &event_list[i] );
00468 #endif
00469         }
00470     }
00471     if ( _papi_bipartite_alloc( event_list, natNum, ESI->CmpIdx ) ) {   /* successfully mapped */
00472         for ( i = 0; i < natNum; i++ ) {
00473 #ifdef PERFCTR_X86_INTEL_CORE2
00474             if ( _papi_hwi_system_info.hw_info.model ==
00475                  PERFCTR_X86_INTEL_CORE2 )
00476                 event_list[i].ra_bits.selector = event_list[i].ra_selector;
00477 #endif
00478 #ifdef DEBUG
00479             if ( is_pentium4() ) {
00480                 SUBDBG( "i: %d\n", i );
00481                 print_alloc( &event_list[i] );
00482             }
00483 #endif
00484             /* Copy all info about this native event to the NativeInfo struct */
00485             ptr = ESI->NativeInfoArray[i].ni_bits;
00486             *ptr = event_list[i].ra_bits;
00487 
00488             if ( is_pentium4() ) {
00489                 /* The selector contains the counter bit position. Turn it into a number
00490                    and store it in the first counter value, zeroing the second. */
00491                 ptr->counter[0] = ffs( event_list[i].ra_selector ) - 1;
00492                 ptr->counter[1] = 0;
00493             }
00494 
00495             /* Array order on perfctr is event ADD order, not counter #... */
00496             ESI->NativeInfoArray[i].ni_position = i;
00497         }
00498         return PAPI_OK;
00499     } else
00500         return PAPI_ECNFLCT;
00501 }

Here is the call graph for this function:

static int _x86_init_control_state ( hwd_control_state_t ptr  )  [static]

Definition at line 119 of file perfctr-x86.c.

00120 {
00121     int i, def_mode = 0;
00122 
00123     if ( is_pentium4() ) {
00124         if ( _perfctr_vector.cmp_info.default_domain & PAPI_DOM_USER )
00125             def_mode |= ESCR_T0_USR;
00126         if ( _perfctr_vector.cmp_info.default_domain & PAPI_DOM_KERNEL )
00127             def_mode |= ESCR_T0_OS;
00128 
00129         for ( i = 0; i < _perfctr_vector.cmp_info.num_cntrs; i++ ) {
00130             ptr->control.cpu_control.evntsel_aux[i] |= def_mode;
00131         }
00132         ptr->control.cpu_control.tsc_on = 1;
00133         ptr->control.cpu_control.nractrs = 0;
00134         ptr->control.cpu_control.nrictrs = 0;
00135 
00136 #ifdef VPERFCTR_CONTROL_CLOEXEC
00137         ptr->control.flags = VPERFCTR_CONTROL_CLOEXEC;
00138         SUBDBG( "close on exec\t\t\t%u\n", ptr->control.flags );
00139 #endif
00140     } else {
00141 
00142         if ( _perfctr_vector.cmp_info.default_domain & PAPI_DOM_USER )
00143             def_mode |= PERF_USR;
00144         if ( _perfctr_vector.cmp_info.default_domain & PAPI_DOM_KERNEL )
00145             def_mode |= PERF_OS;
00146 
00147         ptr->allocated_registers.selector = 0;
00148         switch ( _papi_hwi_system_info.hw_info.model ) {
00149         case PERFCTR_X86_GENERIC:
00150         case PERFCTR_X86_WINCHIP_C6:
00151         case PERFCTR_X86_WINCHIP_2:
00152         case PERFCTR_X86_VIA_C3:
00153         case PERFCTR_X86_INTEL_P5:
00154         case PERFCTR_X86_INTEL_P5MMX:
00155         case PERFCTR_X86_INTEL_PII:
00156         case PERFCTR_X86_INTEL_P6:
00157         case PERFCTR_X86_INTEL_PIII:
00158 #ifdef PERFCTR_X86_INTEL_CORE
00159         case PERFCTR_X86_INTEL_CORE:
00160 #endif
00161 #ifdef PERFCTR_X86_INTEL_PENTM
00162         case PERFCTR_X86_INTEL_PENTM:
00163 #endif
00164             ptr->control.cpu_control.evntsel[0] |= PERF_ENABLE;
00165             for ( i = 0; i < _perfctr_vector.cmp_info.num_cntrs; i++ ) {
00166                 ptr->control.cpu_control.evntsel[i] |= def_mode;
00167                 ptr->control.cpu_control.pmc_map[i] = ( unsigned int ) i;
00168             }
00169             break;
00170 #ifdef PERFCTR_X86_INTEL_CORE2
00171         case PERFCTR_X86_INTEL_CORE2:
00172 #endif
00173 #ifdef PERFCTR_X86_INTEL_ATOM
00174         case PERFCTR_X86_INTEL_ATOM:
00175 #endif
00176 #ifdef PERFCTR_X86_INTEL_NHLM
00177         case PERFCTR_X86_INTEL_NHLM:
00178 #endif
00179 #ifdef PERFCTR_X86_INTEL_WSTMR
00180         case PERFCTR_X86_INTEL_WSTMR:
00181 #endif
00182 #ifdef PERFCTR_X86_AMD_K8
00183         case PERFCTR_X86_AMD_K8:
00184 #endif
00185 #ifdef PERFCTR_X86_AMD_K8C
00186         case PERFCTR_X86_AMD_K8C:
00187 #endif
00188 #ifdef PERFCTR_X86_AMD_FAM10H   /* this is defined in perfctr 2.6.29 */
00189         case PERFCTR_X86_AMD_FAM10H:
00190 #endif
00191         case PERFCTR_X86_AMD_K7:
00192             for ( i = 0; i < _perfctr_vector.cmp_info.num_cntrs; i++ ) {
00193                 ptr->control.cpu_control.evntsel[i] |= PERF_ENABLE | def_mode;
00194                 ptr->control.cpu_control.pmc_map[i] = ( unsigned int ) i;
00195             }
00196             break;
00197         }
00198 #ifdef VPERFCTR_CONTROL_CLOEXEC
00199         ptr->control.flags = VPERFCTR_CONTROL_CLOEXEC;
00200         SUBDBG( "close on exec\t\t\t%u\n", ptr->control.flags );
00201 #endif
00202 
00203         /* Make sure the TSC is always on */
00204         ptr->control.cpu_control.tsc_on = 1;
00205     }
00206     return ( PAPI_OK );
00207 }

Here is the call graph for this function:

static int _x86_read ( hwd_context_t ctx,
hwd_control_state_t spc,
long long **  dp,
int  flags 
) [static]

Definition at line 701 of file perfctr-x86.c.

00703 {
00704     if ( flags & PAPI_PAUSED ) {
00705         vperfctr_read_state( ctx->perfctr, &spc->state, NULL );
00706         if ( !is_pentium4() ) {
00707             unsigned int i = 0;
00708             for ( i = 0;
00709                   i <
00710                   spc->control.cpu_control.nractrs +
00711                   spc->control.cpu_control.nrictrs; i++ ) {
00712                 SUBDBG( "vperfctr_read_state: counter %d =  %lld\n", i,
00713                         spc->state.pmc[i] );
00714             }
00715         }
00716     } else {
00717         SUBDBG( "vperfctr_read_ctrs\n" );
00718         if ( spc->rvperfctr != NULL ) {
00719             rvperfctr_read_ctrs( spc->rvperfctr, &spc->state );
00720         } else {
00721             vperfctr_read_ctrs( ctx->perfctr, &spc->state );
00722         }
00723     }
00724     *dp = ( long long * ) spc->state.pmc;
00725 #ifdef DEBUG
00726     {
00727         if ( ISLEVEL( DEBUG_SUBSTRATE ) ) {
00728             unsigned int i;
00729             if ( is_pentium4() ) {
00730                 for ( i = 0; i < spc->control.cpu_control.nractrs; i++ ) {
00731                     SUBDBG( "raw val hardware index %d is %lld\n", i,
00732                             ( long long ) spc->state.pmc[i] );
00733                 }
00734             } else {
00735                 for ( i = 0;
00736                       i <
00737                       spc->control.cpu_control.nractrs +
00738                       spc->control.cpu_control.nrictrs; i++ ) {
00739                     SUBDBG( "raw val hardware index %d is %lld\n", i,
00740                             ( long long ) spc->state.pmc[i] );
00741                 }
00742             }
00743         }
00744     }
00745 #endif
00746     return ( PAPI_OK );
00747 }

Here is the call graph for this function:

static int _x86_reset ( hwd_context_t ctx,
hwd_control_state_t cntrl 
) [static]

Definition at line 750 of file perfctr-x86.c.

00751 {
00752     return ( _x86_start( ctx, cntrl ) );
00753 }

Here is the call graph for this function:

int _x86_set_domain ( hwd_control_state_t cntrl,
int  domain 
)

Definition at line 210 of file perfctr-x86.c.

00211 {
00212     int i, did = 0;
00213     int num_cntrs = _perfctr_vector.cmp_info.num_cntrs;
00214 
00215     /* Clear the current domain set for this event set */
00216     /* We don't touch the Enable bit in this code */
00217     if ( is_pentium4() ) {
00218         for ( i = 0; i < _perfctr_vector.cmp_info.num_cntrs; i++ ) {
00219             cntrl->control.cpu_control.evntsel_aux[i] &=
00220                 ~( ESCR_T0_OS | ESCR_T0_USR );
00221         }
00222 
00223         if ( domain & PAPI_DOM_USER ) {
00224             did = 1;
00225             for ( i = 0; i < _perfctr_vector.cmp_info.num_cntrs; i++ ) {
00226                 cntrl->control.cpu_control.evntsel_aux[i] |= ESCR_T0_USR;
00227             }
00228         }
00229 
00230         if ( domain & PAPI_DOM_KERNEL ) {
00231             did = 1;
00232             for ( i = 0; i < _perfctr_vector.cmp_info.num_cntrs; i++ ) {
00233                 cntrl->control.cpu_control.evntsel_aux[i] |= ESCR_T0_OS;
00234             }
00235         }
00236     } else {
00237         for ( i = 0; i < num_cntrs; i++ ) {
00238             cntrl->control.cpu_control.evntsel[i] &= ~( PERF_OS | PERF_USR );
00239         }
00240 
00241         if ( domain & PAPI_DOM_USER ) {
00242             did = 1;
00243             for ( i = 0; i < num_cntrs; i++ ) {
00244                 cntrl->control.cpu_control.evntsel[i] |= PERF_USR;
00245             }
00246         }
00247 
00248         if ( domain & PAPI_DOM_KERNEL ) {
00249             did = 1;
00250             for ( i = 0; i < num_cntrs; i++ ) {
00251                 cntrl->control.cpu_control.evntsel[i] |= PERF_OS;
00252             }
00253         }
00254     }
00255 
00256     if ( !did )
00257         return ( PAPI_EINVAL );
00258     else
00259         return ( PAPI_OK );
00260 }

Here is the call graph for this function:

static int _x86_set_overflow ( EventSetInfo_t ESI,
int  EventIndex,
int  threshold 
) [static]

Definition at line 805 of file perfctr-x86.c.

00806 {
00807        hwd_control_state_t *ctl = ( hwd_control_state_t * ) ( ESI->ctl_state );
00808        struct hwd_pmc_control *contr = &(ctl->control);
00809     int i, ncntrs, nricntrs = 0, nracntrs = 0, retval = 0;
00810     OVFDBG( "EventIndex=%d\n", EventIndex );
00811 
00812 #ifdef DEBUG
00813     if ( is_pentium4() )
00814       print_control( &(contr->cpu_control) );
00815 #endif
00816 
00817     /* The correct event to overflow is EventIndex */
00818     ncntrs = _perfctr_vector.cmp_info.num_cntrs;
00819     i = ESI->EventInfoArray[EventIndex].pos[0];
00820 
00821     if ( i >= ncntrs ) {
00822         PAPIERROR( "Selector id %d is larger than ncntrs %d", i, ncntrs );
00823         return PAPI_EINVAL;
00824     }
00825 
00826     if ( threshold != 0 ) {  /* Set an overflow threshold */
00827         retval = _papi_hwi_start_signal( _perfctr_vector.cmp_info.hardware_intr_sig,
00828                                          NEED_CONTEXT,
00829                                          _perfctr_vector.cmp_info.CmpIdx );
00830         if ( retval != PAPI_OK )
00831             return ( retval );
00832 
00833         /* overflow interrupt occurs on the NEXT event after overflow occurs
00834            thus we subtract 1 from the threshold. */
00835         contr->cpu_control.ireset[i] = ( -threshold + 1 );
00836 
00837         if ( is_pentium4() )
00838             contr->cpu_control.evntsel[i] |= CCCR_OVF_PMI_T0;
00839         else
00840             contr->cpu_control.evntsel[i] |= PERF_INT_ENABLE;
00841 
00842         contr->cpu_control.nrictrs++;
00843         contr->cpu_control.nractrs--;
00844         nricntrs = ( int ) contr->cpu_control.nrictrs;
00845         nracntrs = ( int ) contr->cpu_control.nractrs;
00846         contr->si_signo = _perfctr_vector.cmp_info.hardware_intr_sig;
00847 
00848         /* move this event to the bottom part of the list if needed */
00849         if ( i < nracntrs )
00850             swap_events( ESI, contr, i, nracntrs );
00851         OVFDBG( "Modified event set\n" );
00852     } else {
00853       if ( is_pentium4() && contr->cpu_control.evntsel[i] & CCCR_OVF_PMI_T0 ) {
00854             contr->cpu_control.ireset[i] = 0;
00855             contr->cpu_control.evntsel[i] &= ( ~CCCR_OVF_PMI_T0 );
00856             contr->cpu_control.nrictrs--;
00857             contr->cpu_control.nractrs++;
00858       } else if ( !is_pentium4() &&
00859                     contr->cpu_control.evntsel[i] & PERF_INT_ENABLE ) {
00860             contr->cpu_control.ireset[i] = 0;
00861             contr->cpu_control.evntsel[i] &= ( ~PERF_INT_ENABLE );
00862             contr->cpu_control.nrictrs--;
00863             contr->cpu_control.nractrs++;
00864         }
00865 
00866         nricntrs = ( int ) contr->cpu_control.nrictrs;
00867         nracntrs = ( int ) contr->cpu_control.nractrs;
00868 
00869         /* move this event to the top part of the list if needed */
00870         if ( i >= nracntrs )
00871             swap_events( ESI, contr, i, nracntrs - 1 );
00872 
00873         if ( !nricntrs )
00874             contr->si_signo = 0;
00875 
00876         OVFDBG( "Modified event set\n" );
00877 
00878         retval = _papi_hwi_stop_signal( _perfctr_vector.cmp_info.hardware_intr_sig );
00879     }
00880 
00881 #ifdef DEBUG
00882     if ( is_pentium4() )
00883       print_control( &(contr->cpu_control) );
00884 #endif
00885     OVFDBG( "End of call. Exit code: %d\n", retval );
00886     return ( retval );
00887 }

Here is the call graph for this function:

static int _x86_start ( hwd_context_t ctx,
hwd_control_state_t state 
) [static]

Definition at line 653 of file perfctr-x86.c.

00654 {
00655     int error;
00656 #ifdef DEBUG
00657     print_control( &state->control.cpu_control );
00658 #endif
00659 
00660     if ( state->rvperfctr != NULL ) {
00661         if ( ( error =
00662                rvperfctr_control( state->rvperfctr, &state->control ) ) < 0 ) {
00663             SUBDBG( "rvperfctr_control returns: %d\n", error );
00664             PAPIERROR( RCNTRL_ERROR );
00665             return ( PAPI_ESYS );
00666         }
00667         return ( PAPI_OK );
00668     }
00669 
00670     if ( ( error = vperfctr_control( ctx->perfctr, &state->control ) ) < 0 ) {
00671         SUBDBG( "vperfctr_control returns: %d\n", error );
00672         PAPIERROR( VCNTRL_ERROR );
00673         return ( PAPI_ESYS );
00674     }
00675     return ( PAPI_OK );
00676 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int _x86_stop ( hwd_context_t ctx,
hwd_control_state_t state 
) [static]

Definition at line 679 of file perfctr-x86.c.

00680 {
00681     int error;
00682 
00683     if ( state->rvperfctr != NULL ) {
00684         if ( rvperfctr_stop( ( struct rvperfctr * ) ctx->perfctr ) < 0 ) {
00685             PAPIERROR( RCNTRL_ERROR );
00686             return ( PAPI_ESYS );
00687         }
00688         return ( PAPI_OK );
00689     }
00690 
00691     error = vperfctr_stop( ctx->perfctr );
00692     if ( error < 0 ) {
00693         SUBDBG( "vperfctr_stop returns: %d\n", error );
00694         PAPIERROR( VCNTRL_ERROR );
00695         return ( PAPI_ESYS );
00696     }
00697     return ( PAPI_OK );
00698 }

Here is the call graph for this function:

static int _x86_stop_profiling ( ThreadInfo_t master,
EventSetInfo_t ESI 
) [static]

Definition at line 890 of file perfctr-x86.c.

00891 {
00892     ( void ) master;         /*unused */
00893     ( void ) ESI;            /*unused */
00894     return ( PAPI_OK );
00895 }

static int _x86_update_control_state ( hwd_control_state_t this_state,
NativeInfo_t native,
int  count,
hwd_context_t ctx 
) [static]

Definition at line 550 of file perfctr-x86.c.

00553 {
00554     ( void ) ctx;            /*unused */
00555     unsigned int i, k, retval = PAPI_OK;
00556     hwd_register_t *bits,*bits2;
00557     struct perfctr_cpu_control *cpu_control = &this_state->control.cpu_control;
00558 
00559     /* clear out the events from the control state */
00560     clear_cs_events( this_state );
00561 
00562     if ( is_pentium4() ) {
00563         /* fill the counters we're using */
00564         for ( i = 0; i < ( unsigned int ) count; i++ ) {
00565             /* dereference the mapping information about this native event */
00566             bits = native[i].ni_bits;
00567 
00568             /* Add counter control command values to eventset */
00569             cpu_control->pmc_map[i] = bits->counter[0];
00570             cpu_control->evntsel[i] = bits->cccr;
00571             cpu_control->ireset[i] = bits->ireset;
00572             cpu_control->pmc_map[i] |= FAST_RDPMC;
00573             cpu_control->evntsel_aux[i] |= bits->event;
00574 
00575             /* pebs_enable and pebs_matrix_vert are shared registers used for replay_events.
00576                Replay_events count L1 and L2 cache events. There is only one of each for 
00577                the entire eventset. Therefore, there can be only one unique replay_event 
00578                per eventset. This means L1 and L2 can't be counted together. Which stinks.
00579                This conflict should be trapped in the allocation scheme, but we'll test for it
00580                here too, just in case. */
00581             if ( bits->pebs_enable ) {
00582                 /* if pebs_enable isn't set, just copy */
00583                 if ( cpu_control->p4.pebs_enable == 0 ) {
00584                     cpu_control->p4.pebs_enable = bits->pebs_enable;
00585                     /* if pebs_enable conflicts, flag an error */
00586                 } else if ( cpu_control->p4.pebs_enable != bits->pebs_enable ) {
00587                     SUBDBG
00588                         ( "WARNING: P4_update_control_state -- pebs_enable conflict!" );
00589                     retval = PAPI_ECNFLCT;
00590                 }
00591                 /* if pebs_enable == bits->pebs_enable, do nothing */
00592             }
00593             if ( bits->pebs_matrix_vert ) {
00594                 /* if pebs_matrix_vert isn't set, just copy */
00595                 if ( cpu_control->p4.pebs_matrix_vert == 0 ) {
00596                     cpu_control->p4.pebs_matrix_vert = bits->pebs_matrix_vert;
00597                     /* if pebs_matrix_vert conflicts, flag an error */
00598                 } else if ( cpu_control->p4.pebs_matrix_vert !=
00599                             bits->pebs_matrix_vert ) {
00600                     SUBDBG
00601                         ( "WARNING: P4_update_control_state -- pebs_matrix_vert conflict!" );
00602                     retval = PAPI_ECNFLCT;
00603                 }
00604                 /* if pebs_matrix_vert == bits->pebs_matrix_vert, do nothing */
00605             }
00606         }
00607         this_state->control.cpu_control.nractrs = count;
00608 
00609         /* Make sure the TSC is always on */
00610         this_state->control.cpu_control.tsc_on = 1;
00611 
00612 #ifdef DEBUG
00613         print_control( &this_state->control.cpu_control );
00614 #endif
00615     } else {
00616         switch ( _papi_hwi_system_info.hw_info.model ) {
00617 #ifdef PERFCTR_X86_INTEL_CORE2
00618         case PERFCTR_X86_INTEL_CORE2:
00619             /* fill the counters we're using */
00620             for ( i = 0; i < ( unsigned int ) count; i++ ) {
00621                 bits2 = native[i].ni_bits;
00622                 for ( k = 0; k < MAX_COUNTERS; k++ )
00623                     if ( bits2->selector & ( 1 << k ) ) {
00624                         break;
00625                     }
00626                 if ( k > 1 )
00627                     this_state->control.cpu_control.pmc_map[i] =
00628                         ( k - 2 ) | 0x40000000;
00629                 else
00630                     this_state->control.cpu_control.pmc_map[i] = k;
00631 
00632                 /* Add counter control command values to eventset */
00633                 this_state->control.cpu_control.evntsel[i] |=
00634                     bits2->counter_cmd;
00635             }
00636             break;
00637 #endif
00638         default:
00639             /* fill the counters we're using */
00640             for ( i = 0; i < ( unsigned int ) count; i++ ) {
00641                 /* Add counter control command values to eventset */
00642                  bits2 = native[i].ni_bits;
00643                 this_state->control.cpu_control.evntsel[i] |=
00644                     bits2->counter_cmd;
00645             }
00646         }
00647         this_state->control.cpu_control.nractrs = ( unsigned int ) count;
00648     }
00649     return retval;
00650 }

Here is the call graph for this function:

static void clear_cs_events ( hwd_control_state_t this_state  )  [static]

Definition at line 504 of file perfctr-x86.c.

00505 {
00506     unsigned int i, j;
00507 
00508     /* total counters is sum of accumulating (nractrs) and interrupting (nrictrs) */
00509     j = this_state->control.cpu_control.nractrs +
00510         this_state->control.cpu_control.nrictrs;
00511 
00512     /* Remove all counter control command values from eventset. */
00513     for ( i = 0; i < j; i++ ) {
00514         SUBDBG( "Clearing pmc event entry %d\n", i );
00515         if ( is_pentium4() ) {
00516             this_state->control.cpu_control.pmc_map[i] = 0;
00517             this_state->control.cpu_control.evntsel[i] = 0;
00518             this_state->control.cpu_control.evntsel_aux[i] =
00519                 this_state->control.cpu_control.
00520                 evntsel_aux[i] & ( ESCR_T0_OS | ESCR_T0_USR );
00521         } else {
00522             this_state->control.cpu_control.pmc_map[i] = i;
00523             this_state->control.cpu_control.evntsel[i]
00524                 = this_state->control.cpu_control.
00525                 evntsel[i] & ( PERF_ENABLE | PERF_OS | PERF_USR );
00526         }
00527         this_state->control.cpu_control.ireset[i] = 0;
00528     }
00529 
00530     if ( is_pentium4() ) {
00531         /* Clear pebs stuff */
00532         this_state->control.cpu_control.p4.pebs_enable = 0;
00533         this_state->control.cpu_control.p4.pebs_matrix_vert = 0;
00534     }
00535 
00536     /* clear both a and i counter counts */
00537     this_state->control.cpu_control.nractrs = 0;
00538     this_state->control.cpu_control.nrictrs = 0;
00539 
00540 #ifdef DEBUG
00541     if ( is_pentium4() )
00542         print_control( &this_state->control.cpu_control );
00543 #endif
00544 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int is_pentium4 ( void   )  [inline, static]

Definition at line 75 of file perfctr-x86.c.

00075                                     {
00076   if ( ( _papi_hwi_system_info.hw_info.vendor == PAPI_VENDOR_INTEL ) &&
00077        ( _papi_hwi_system_info.hw_info.cpuid_family == 15 )) {
00078     return 1;
00079   }
00080 
00081   return 0;
00082 
00083 }

Here is the caller graph for this function:

static void print_alloc ( X86_reg_alloc_t a  )  [static]

Definition at line 87 of file perfctr-x86.c.

00088 {
00089     SUBDBG( "X86_reg_alloc:\n" );
00090     SUBDBG( "  selector: %#x\n", a->ra_selector );
00091     SUBDBG( "  rank: %#x\n", a->ra_rank );
00092     SUBDBG( "  escr: %#x %#x\n", a->ra_escr[0], a->ra_escr[1] );
00093 }

Here is the caller graph for this function:

void print_control ( const struct perfctr_cpu_control *  control  ) 

Definition at line 96 of file perfctr-x86.c.

00097 {
00098     unsigned int i;
00099     SUBDBG( "Control used:\n" );
00100     SUBDBG( "tsc_on\t\t\t%u\n", control->tsc_on );
00101     SUBDBG( "nractrs\t\t\t%u\n", control->nractrs );
00102     SUBDBG( "nrictrs\t\t\t%u\n", control->nrictrs );
00103 
00104     for ( i = 0; i < ( control->nractrs + control->nrictrs ); ++i ) {
00105         if ( control->pmc_map[i] >= 18 ) {
00106             SUBDBG( "pmc_map[%u]\t\t0x%08X\n", i, control->pmc_map[i] );
00107         } else {
00108             SUBDBG( "pmc_map[%u]\t\t%u\n", i, control->pmc_map[i] );
00109         }
00110         SUBDBG( "evntsel[%u]\t\t0x%08X\n", i, control->evntsel[i] );
00111         if ( control->ireset[i] ) {
00112             SUBDBG( "ireset[%u]\t%d\n", i, control->ireset[i] );
00113         }
00114     }
00115 }

Here is the caller graph for this function:

static void swap_events ( EventSetInfo_t ESI,
struct hwd_pmc_control *  contr,
int  cntr1,
int  cntr2 
) [static]

Definition at line 762 of file perfctr-x86.c.

00764 {
00765     unsigned int ui;
00766     int si, i, j;
00767 
00768     for ( i = 0; i < ESI->NativeCount; i++ ) {
00769         if ( ESI->NativeInfoArray[i].ni_position == cntr1 )
00770             ESI->NativeInfoArray[i].ni_position = cntr2;
00771         else if ( ESI->NativeInfoArray[i].ni_position == cntr2 )
00772             ESI->NativeInfoArray[i].ni_position = cntr1;
00773     }
00774 
00775     for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
00776         for ( j = 0; ESI->EventInfoArray[i].pos[j] >= 0; j++ ) {
00777             if ( ESI->EventInfoArray[i].pos[j] == cntr1 )
00778                 ESI->EventInfoArray[i].pos[j] = cntr2;
00779             else if ( ESI->EventInfoArray[i].pos[j] == cntr2 )
00780                 ESI->EventInfoArray[i].pos[j] = cntr1;
00781         }
00782     }
00783 
00784     ui = contr->cpu_control.pmc_map[cntr1];
00785     contr->cpu_control.pmc_map[cntr1] = contr->cpu_control.pmc_map[cntr2];
00786     contr->cpu_control.pmc_map[cntr2] = ui;
00787 
00788     ui = contr->cpu_control.evntsel[cntr1];
00789     contr->cpu_control.evntsel[cntr1] = contr->cpu_control.evntsel[cntr2];
00790     contr->cpu_control.evntsel[cntr2] = ui;
00791 
00792     if ( is_pentium4() ) {
00793         ui = contr->cpu_control.evntsel_aux[cntr1];
00794         contr->cpu_control.evntsel_aux[cntr1] =
00795             contr->cpu_control.evntsel_aux[cntr2];
00796         contr->cpu_control.evntsel_aux[cntr2] = ui;
00797     }
00798 
00799     si = contr->cpu_control.ireset[cntr1];
00800     contr->cpu_control.ireset[cntr1] = contr->cpu_control.ireset[cntr2];
00801     contr->cpu_control.ireset[cntr2] = si;
00802 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 55 of file papi_internal.c.

Definition at line 1163 of file perfctr-x86.c.

pentium4_replay_regs_t p4_replay_regs[] [static]

Definition at line 910 of file perfctr-x86.c.

pentium4_cccr_reg_t pentium4_cccrs[]
pentium4_escr_reg_t pentium4_escrs[]
pentium4_event_t pentium4_events[]
int pfm2intel[] [static]
Initial value:
    { 0, 1, 4, 5, 8, 9, 12, 13, 16, 2, 3, 6, 7, 10, 11, 14, 15, 17 }

Definition at line 958 of file perfctr-x86.c.


Generated on 26 Jan 2016 for PAPI by  doxygen 1.6.1