unsigned long rthal_timer_calibrate(void) { unsigned long v, flags; rthal_time_t t, dt; int i; v = RTHAL_COMPAT_TIMERFREQ / HZ; flags = rthal_critical_enter(NULL); rthal_timer_program_shot(v); t = rthal_rdtsc(); for (i = 0; i < 100; i++) rthal_timer_program_shot(v); dt = (rthal_rdtsc() - t); rthal_critical_exit(flags); #ifdef CONFIG_IPIPE_TRACE_IRQSOFF /* Reset the max trace, since it contains the calibration time now. */ rthal_trace_max_reset(); #endif /* CONFIG_IPIPE_TRACE_IRQSOFF */ return rthal_ulldiv(dt, i + 5, NULL); }
unsigned long rthal_timer_calibrate(void) { unsigned long long start, end, sum = 0, sum_sq = 0; volatile unsigned const_delay = rthal_clockfreq_arg / HZ; unsigned long result, flags, tsc_lat; unsigned int delay = const_delay; long long diff; int i, j; flags = rthal_critical_enter(NULL); /* * Hw interrupts off, other CPUs quiesced, no migration * possible. We can now fiddle with the timer chip (per-cpu * local or global, rthal_timer_program_shot() will handle * this transparently via the I-pipe). */ steal_timer(1); force_oneshot_hw_mode(); rthal_read_tsc(start); barrier(); rthal_read_tsc(end); tsc_lat = end - start; barrier(); for (i = 0; i < RTHAL_CALIBRATE_LOOPS; i++) { flush_cache_all(); for (j = 0; j < RTHAL_CALIBRATE_LOOPS; j++) { rthal_read_tsc(start); barrier(); #if IPIPE_CORE_APIREV < 2 rthal_timer_program_shot( rthal_nodiv_imuldiv_ceil(delay, rthal_tsc_to_timer)); #else rthal_timer_program_shot(delay); #endif barrier(); rthal_read_tsc(end); diff = end - start - tsc_lat; if (diff > 0) { sum += diff; sum_sq += diff * diff; } } } restore_normal_hw_mode(); rthal_critical_exit(flags); /* Use average + standard deviation as timer programming latency. */ do_div(sum, RTHAL_CALIBRATE_LOOPS * RTHAL_CALIBRATE_LOOPS); do_div(sum_sq, RTHAL_CALIBRATE_LOOPS * RTHAL_CALIBRATE_LOOPS); result = sum + int_sqrt(sum_sq - sum * sum) + 1; return result; }
unsigned long rthal_timer_calibrate(void) { unsigned long flags, delay; rthal_time_t t, dt; int i; delay = RTHAL_CPU_FREQ; /* 1s */ flags = rthal_critical_enter(NULL); t = rthal_rdtsc(); for (i = 0; i < 10000; i++) rthal_timer_program_shot(delay); dt = rthal_rdtsc() - t; rthal_critical_exit(flags); return rthal_imuldiv(dt, 100000, RTHAL_CPU_FREQ); }