示例#1
0
文件: hipe_perfctr.c 项目: 1153/otp
static int hipe_perfctr_open(unsigned int user)
{
    struct perfctr_info info;

    if (!vperfctr) {
	vperfctr = vperfctr_open();
	if (!vperfctr)
	    return -1;
	if (vperfctr_info(vperfctr, &info) >= 0) {
	    tsc_to_ms = (double)(info.tsc_to_cpu_mult ? : 1) / (double)info.cpu_khz;
	    have_rdtsc = (info.cpu_features & PERFCTR_FEATURE_RDTSC) ? 1 : 0;
	}
示例#2
0
int
_perfctr_init_component( int cidx )
{
	int retval;
	struct perfctr_info info;
	char abiv[PAPI_MIN_STR_LEN];

#if defined(PERFCTR26)
	int fd;
#else
	struct vperfctr *dev;
#endif

#if defined(PERFCTR26)
	/* Get info from the kernel */
	/* Use lower level calls per Mikael to get the perfctr info
	   without actually creating a new kernel-side state.
	   Also, close the fd immediately after retrieving the info.
	   This is much lighter weight and doesn't reserve the counter
	   resources. Also compatible with perfctr 2.6.14.
	 */
	fd = _vperfctr_open( 0 );
	if ( fd < 0 ) {
	   strncpy(_perfctr_vector.cmp_info.disabled_reason,
		  VOPEN_ERROR,PAPI_MAX_STR_LEN);
	   return PAPI_ESYS;
	}
	retval = perfctr_info( fd, &info );
	close( fd );
	if ( retval < 0 ) {
	   strncpy(_perfctr_vector.cmp_info.disabled_reason,
		  VINFO_ERROR,PAPI_MAX_STR_LEN);
	   return PAPI_ESYS;
	}

	/* copy tsc multiplier to local variable        */
	/* this field appears in perfctr 2.6 and higher */
	tb_scale_factor = ( long long ) info.tsc_to_cpu_mult;
#else
	/* Opened once for all threads. */
	if ( ( dev = vperfctr_open(  ) ) == NULL ) {
	   strncpy(_perfctr_vector.cmp_info.disabled_reason,
		  VOPEN_ERROR,PAPI_MAX_STR_LEN);
	   return PAPI_ESYS;
	}
	SUBDBG( "_perfctr_init_component vperfctr_open = %p\n", dev );

	/* Get info from the kernel */
	retval = vperfctr_info( dev, &info );
	if ( retval < 0 ) {
	   strncpy(_perfctr_vector.cmp_info.disabled_reason,
		  VINFO_ERROR,PAPI_MAX_STR_LEN);
		return ( PAPI_ESYS );
	}
	vperfctr_close( dev );
#endif

	/* Fill in what we can of the papi_system_info. */
	retval = _papi_os_vector.get_system_info( &_papi_hwi_system_info );
	if ( retval != PAPI_OK )
		return ( retval );

	/* Setup memory info */
	retval = _papi_os_vector.get_memory_info( &_papi_hwi_system_info.hw_info,
						   ( int ) info.cpu_type );
	if ( retval )
		return ( retval );

	strcpy( _perfctr_vector.cmp_info.name,"perfctr.c" );
	strcpy( _perfctr_vector.cmp_info.version, "$Revision$" );
	sprintf( abiv, "0x%08X", info.abi_version );
	strcpy( _perfctr_vector.cmp_info.support_version, abiv );
	strcpy( _perfctr_vector.cmp_info.kernel_version, info.driver_version );
	_perfctr_vector.cmp_info.CmpIdx = cidx;
	_perfctr_vector.cmp_info.num_cntrs = ( int ) PERFCTR_CPU_NRCTRS( &info );
        _perfctr_vector.cmp_info.num_mpx_cntrs=_perfctr_vector.cmp_info.num_cntrs;
	if ( info.cpu_features & PERFCTR_FEATURE_RDPMC )
		_perfctr_vector.cmp_info.fast_counter_read = 1;
	else
		_perfctr_vector.cmp_info.fast_counter_read = 0;
	_perfctr_vector.cmp_info.fast_real_timer = 1;
	_perfctr_vector.cmp_info.fast_virtual_timer = 1;
	_perfctr_vector.cmp_info.attach = 1;
	_perfctr_vector.cmp_info.attach_must_ptrace = 1;
	_perfctr_vector.cmp_info.default_domain = PAPI_DOM_USER;
#if !defined(PPC64)
	/* AMD and Intel ia386 processors all support unit mask bits */
	_perfctr_vector.cmp_info.cntr_umasks = 1;
#endif
#if defined(PPC64)
	_perfctr_vector.cmp_info.available_domains =
		PAPI_DOM_USER | PAPI_DOM_KERNEL | PAPI_DOM_SUPERVISOR;
#else
	_perfctr_vector.cmp_info.available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL;
#endif
	_perfctr_vector.cmp_info.default_granularity = PAPI_GRN_THR;
	_perfctr_vector.cmp_info.available_granularities = PAPI_GRN_THR;
	if ( info.cpu_features & PERFCTR_FEATURE_PCINT )
		_perfctr_vector.cmp_info.hardware_intr = 1;
	else
		_perfctr_vector.cmp_info.hardware_intr = 0;
	SUBDBG( "Hardware/OS %s support counter generated interrupts\n",
			_perfctr_vector.cmp_info.hardware_intr ? "does" : "does not" );

	strcpy( _papi_hwi_system_info.hw_info.model_string,
			PERFCTR_CPU_NAME( &info ) );
	_papi_hwi_system_info.hw_info.model = ( int ) info.cpu_type;
#if defined(PPC64)
	_papi_hwi_system_info.hw_info.vendor = PAPI_VENDOR_IBM;
	if ( strlen( _papi_hwi_system_info.hw_info.vendor_string ) == 0 )
		strcpy( _papi_hwi_system_info.hw_info.vendor_string, "IBM" );
#else
	_papi_hwi_system_info.hw_info.vendor =
		xlate_cpu_type_to_vendor( info.cpu_type );
#endif

	/* Setup presets last. Some platforms depend on earlier info */
#if !defined(PPC64)
//     retval = setup_p3_vector_table(vtable);
		if ( !retval )
			retval = setup_x86_presets( ( int ) info.cpu_type );
#else
	/* Setup native and preset events */
//  retval = ppc64_setup_vector_table(vtable);
	if ( !retval )
		retval = perfctr_ppc64_setup_native_table(  );
	if ( !retval )
		retval = setup_ppc64_presets( info.cpu_type );
#endif
	if ( retval )
		return ( retval );

	return ( PAPI_OK );
}
示例#3
0
文件: clock.c 项目: bernied/capriccio
static void init_perfctr() {
    unsigned int tsc_on = 1;
    unsigned int nractrs = 1;
    unsigned int pmc_map0 = 0;
    unsigned int evntsel0 = 0;

    self = vperfctr_open();
    clock_perfctr = self;
    if( !self ) {
      char *str = "vperfctr_open() failed!!\n";
      syscall(SYS_write, 2, str, strlen(str));
      exit(1);
    }
    if( vperfctr_info(clock_perfctr, &info) < 0 ) {
      char *str = "vperfctr_info() failed!!\n";
      syscall(SYS_write, 2, str, strlen(str));
      exit(1);
    }

    memset(&control, 0, sizeof control);

    /* Attempt to set up control to count clocks via the TSC
       and retired instructions via PMC0. */
    switch( info.cpu_type ) {
      case PERFCTR_X86_GENERIC:
        nractrs = 0;            /* no PMCs available */
        break;
      case PERFCTR_X86_INTEL_P5:
      case PERFCTR_X86_INTEL_P5MMX:
      case PERFCTR_X86_CYRIX_MII:
        /* event 0x16 (INSTRUCTIONS_EXECUTED), count at CPL 3 */
        evntsel0 = 0x16 | (2 << 6);
        break;
      case PERFCTR_X86_INTEL_P6:
      case PERFCTR_X86_INTEL_PII:
      case PERFCTR_X86_INTEL_PIII:
      case PERFCTR_X86_AMD_K7:
      case PERFCTR_X86_AMD_K8:
        /* event 0xC0 (INST_RETIRED), count at CPL > 0, Enable */
        evntsel0 = 0xC0 | (1 << 16) | (1 << 22);
        break;
      case PERFCTR_X86_WINCHIP_C6:
        tsc_on = 0;             /* no working TSC available */
        evntsel0 = 0x02;        /* X86_INSTRUCTIONS */
        break;
      case PERFCTR_X86_WINCHIP_2:
        tsc_on = 0;             /* no working TSC available */
        evntsel0 = 0x16;        /* INSTRUCTIONS_EXECUTED */
        break;
      case PERFCTR_X86_VIA_C3:
        pmc_map0 = 1;           /* redirect PMC0 to PERFCTR1 */
        evntsel0 = 0xC0;        /* INSTRUCTIONS_EXECUTED */  
        break;
      case PERFCTR_X86_INTEL_P4:
      case PERFCTR_X86_INTEL_P4M2:
        /* PMC0: IQ_COUNTER0 with fast RDPMC */
        pmc_map0 = 0x0C | (1 << 31);
        /* IQ_CCCR0: required flags, ESCR 4 (CRU_ESCR0), Enable */
        evntsel0 = (0x3 << 16) | (4 << 13) | (1 << 12);
        /* CRU_ESCR0: event 2 (instr_retired), NBOGUSNTAG, CPL>0 */
        control.cpu_control.p4.escr[0] = (2 << 25) | (1 << 9) | (1 << 2);
        break;
    default: {
          char *str = "cpu type not supported - perfctr init failed!!\n";
          syscall(SYS_write, 2, str, strlen(str));
          exit(1);
        }
    }
    control.cpu_control.tsc_on = tsc_on;
    control.cpu_control.nractrs = nractrs;
    control.cpu_control.pmc_map[0] = pmc_map0;
    control.cpu_control.evntsel[0] = evntsel0;

    if (!nractrs) {
      //output("error: your CPU (%s) doesn't support PMC timing\n", perfctr_info_cpu_name(&info));
      char *str = "error: your CPU doesn't support PMC timing\n";
      syscall(SYS_write, 2, str, strlen(str));
      exit(1);
    }

    // start the perfctr
    if( vperfctr_control(clock_perfctr, &control) < 0 ) {
      char *str = "vperfctr_control failed!!!\n";
      syscall(SYS_write, 2, str, strlen(str));
      exit(1);
    }
}