Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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);
}