FreeBSD/sys/x86/x86/cpu_machdep.c
/* Get current clock frequency for the given cpu id. */
Get current clock frequency for the given cpu id.
Get current clock frequency for the given cpu id .
int
cpu_est_clockrate(int cpu_id, uint64_t *rate)
{
	uint64_t tsc1, tsc2;
	uint64_t acnt, mcnt, perf;
	register_t reg;
	if (pcpu_find(cpu_id) == NULL || rate == NULL)
		return (EINVAL);
#ifdef __i386__
	if ((cpu_feature & CPUID_TSC) == 0)
		return (EOPNOTSUPP);
#endif
	if (tsc_is_invariant && !tsc_perf_stat)
		return (EOPNOTSUPP);
#ifdef SMP
	if (smp_cpus > 1) {
		thread_lock(curthread);
		sched_bind(curthread, cpu_id);
		thread_unlock(curthread);
	}
#endif
	reg = intr_disable();
	if (tsc_is_invariant) {
		wrmsr(MSR_MPERF, 0);
		wrmsr(MSR_APERF, 0);
		tsc1 = rdtsc();
		DELAY(1000);
		mcnt = rdmsr(MSR_MPERF);
		acnt = rdmsr(MSR_APERF);
		tsc2 = rdtsc();
		intr_restore(reg);
		perf = 1000 * acnt / mcnt;
		*rate = (tsc2 - tsc1) * perf;
	} else {
		tsc1 = rdtsc();
		DELAY(1000);
		tsc2 = rdtsc();
		intr_restore(reg);
		*rate = (tsc2 - tsc1) * 1000;
	}
#ifdef SMP
	if (smp_cpus > 1) {
		thread_lock(curthread);
		sched_unbind(curthread);
		thread_unlock(curthread);
	}
#endif
	return (0);
}
int cpu_est_clockrate ( int cpu_id , uint64_t * rate ) { uint64_t tsc1 , tsc2 ; uint64_t acnt , mcnt , perf ; register_t reg ; if ( pcpu_find ( cpu_id ) == NULL || rate == NULL ) return ( EINVAL ) ; #ifdef __i386__ if ( ( cpu_feature & CPUID_TSC ) == 0 ) return ( EOPNOTSUPP ) ; #endif if ( tsc_is_invariant && ! tsc_perf_stat ) return ( EOPNOTSUPP ) ; #ifdef SMP if ( smp_cpus > 1 ) { thread_lock ( curthread ) ; sched_bind ( curthread , cpu_id ) ; thread_unlock ( curthread ) ; } #endif reg = intr_disable ( ) ; if ( tsc_is_invariant ) { wrmsr ( MSR_MPERF , 0 ) ; wrmsr ( MSR_APERF , 0 ) ; tsc1 = rdtsc ( ) ; DELAY ( 1000 ) ; mcnt = rdmsr ( MSR_MPERF ) ; acnt = rdmsr ( MSR_APERF ) ; tsc2 = rdtsc ( ) ; intr_restore ( reg ) ; perf = 1000 * acnt / mcnt ; * rate = ( tsc2 - tsc1 ) * perf ; } else { tsc1 = rdtsc ( ) ; DELAY ( 1000 ) ; tsc2 = rdtsc ( ) ; intr_restore ( reg ) ; * rate = ( tsc2 - tsc1 ) * 1000 ; } #ifdef SMP if ( smp_cpus > 1 ) { thread_lock ( curthread ) ; sched_unbind ( curthread ) ; thread_unlock ( curthread ) ; } #endif return ( 0 ) ; }
Get current clock frequency for the given cpu id.
Get current clock frequency for the given cpu id .
/*
	 * If TSC is P-state invariant and APERF/MPERF MSRs do not exist,
	 * DELAY(9) based logic fails.
	 */ /* Schedule ourselves on the indicated cpu. */ /* Calibrate by measuring a short delay. */