예제 #1
0
int rthal_timer_request(void (*handler) (void), int cpu)
{
    unsigned long flags;

    if (cpu > 0)
        goto out;

    flags = rthal_critical_enter(NULL);

    rthal_irq_release(RTHAL_TIMER_IRQ);

    ipipe_tune_timer(0, IPIPE_GRAB_TIMER);

    if (rthal_irq_request(RTHAL_TIMER_IRQ,
                          (rthal_irq_handler_t) handler, NULL, NULL) < 0) {
        rthal_critical_exit(flags);
        return -EINVAL;
    }

    if (rthal_irq_request(RTHAL_HOST_TIMER_IRQ,
                          &rthal_adjust_before_relay, NULL, NULL) < 0) {
        rthal_critical_exit(flags);
        return -EINVAL;
    }

    rthal_critical_exit(flags);

    rthal_timer_set_irq(RTHAL_TIMER_IRQ);

out:

    return 0;
}
예제 #2
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);
}
예제 #3
0
파일: hal.c 프로젝트: mhaberler/xenomai-2.6
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;
}
예제 #4
0
파일: hal.c 프로젝트: mhaberler/xenomai-2.6
static void rthal_timer_set_periodic(void)
{
	unsigned long flags;

	flags = rthal_critical_enter(rthal_critical_sync);
	rthal_sync_op = RTHAL_SET_PERIODIC;
	restore_normal_hw_mode();
	rthal_critical_exit(flags);
}
예제 #5
0
static void rthal_timer_set_irq(unsigned tick_irq)
{
    unsigned long flags;

    flags = rthal_critical_enter(&rthal_set_itv);
    rthal_tick_irq = tick_irq;
    rthal_set_itv();
    rthal_critical_exit(flags);
}
예제 #6
0
static void rthal_timer_set_periodic(void)
{
	unsigned long flags;

	flags = rthal_critical_enter(&rthal_critical_sync);
	rthal_sync_op = RTHAL_SET_PERIODIC;
	rthal_setup_periodic_dec();
	rthal_disarm_decr(0);
	rthal_critical_exit(flags);
}
예제 #7
0
void rthal_timer_release(int cpu)
{
    unsigned long flags;

    if (cpu > 0)
        return;

    rthal_timer_set_irq(RTHAL_HOST_TIMER_IRQ);
    ipipe_tune_timer(0, IPIPE_RESET_TIMER);
    flags = rthal_critical_enter(NULL);
    rthal_irq_release(RTHAL_TIMER_IRQ);
    rthal_irq_release(RTHAL_HOST_TIMER_IRQ);
    rthal_critical_exit(flags);
}
예제 #8
0
static void rthal_timer_set_oneshot(int rt_mode)
{
	unsigned long flags;

	flags = rthal_critical_enter(rthal_critical_sync);
	if (rt_mode) {
		rthal_sync_op = RTHAL_SET_ONESHOT_XENOMAI;
		rthal_setup_oneshot_dec();
		rthal_disarm_decr(1);
	} else {
		rthal_sync_op = RTHAL_SET_ONESHOT_LINUX;
		rthal_setup_oneshot_dec();
		rthal_disarm_decr(0);
		/* We need to keep the timing cycle alive for the kernel. */
		rthal_trigger_irq(RTHAL_TIMER_IRQ);
	}
	rthal_critical_exit(flags);
}
예제 #9
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);
}