Module: xenomai-gch Branch: for-forge Commit: 33fca0d8c2be0dbf3047065cb36f874461fcc000 URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=33fca0d8c2be0dbf3047065cb36f874461fcc000
Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org> Date: Sun Mar 18 22:42:24 2012 +0100 hal/arm: adapt to refactored ipipe core timers --- include/asm-arm/hal.h | 17 +++++ include/asm-arm/wrappers.h | 4 + kernel/cobalt/arch/arm/hal.c | 141 +++++++++++++++++++++++++---------------- 3 files changed, 107 insertions(+), 55 deletions(-) diff --git a/include/asm-arm/hal.h b/include/asm-arm/hal.h index f4fef47..f053cf2 100644 --- a/include/asm-arm/hal.h +++ b/include/asm-arm/hal.h @@ -38,6 +38,8 @@ #include <asm/vfp.h> #endif /* CONFIG_VFP */ +#ifndef CONFIG_IPIPE_CORE + #if defined(CONFIG_ARCH_AT91) #include <linux/stringify.h> #define RTHAL_TIMER_DEVICE "at91_tc" __stringify(CONFIG_IPIPE_AT91_TC) @@ -90,6 +92,13 @@ #error "Unsupported ARM machine" #endif /* CONFIG_ARCH_SA1100 */ +#else /* I-ipipe core */ + +#define RTHAL_TIMER_DEVICE (ipipe_timer_name()) +#define RTHAL_CLOCK_DEVICE "ipipe_tsc" + +#endif /* I-ipipe core */ + #define RTHAL_HOST_TICK_IRQ RTHAL_TIMER_IRQ typedef unsigned long long rthal_time_t; @@ -152,7 +161,11 @@ static inline __attribute_const__ unsigned long ffnz(unsigned long ul) #define RTHAL_TIMER_IPI IPIPE_HRTIMER_IPI #endif /* RTHAL_TIMER_IPI */ +#ifdef CONFIG_IPIPE_CORE #define RTHAL_TSC_INFO(p) ((p)->arch.tsc) +#else /* !CONFIG_IPIPE_CORE */ +#define RTHAL_TSC_INFO(p) ((p)->arch_tsc) +#endif /* !CONFIG_IPIPE_CORE */ #define RTHAL_SHARED_HEAP_FLAGS (cache_is_vivt() ? XNHEAP_GFP_NONCACHED : 0) @@ -173,10 +186,14 @@ static inline struct task_struct *rthal_current_host_task(int cpuid) static inline void rthal_timer_program_shot(unsigned long delay) { +#ifndef CONFIG_IPIPE_CORE if (delay == 0) ipipe_post_irq_head(RTHAL_TIMER_IRQ); else __ipipe_mach_set_dec(delay); +#else /* I-pipe core */ + ipipe_timer_set(delay); +#endif /* I-pipe core */ } /* Private interface -- Internal use only */ diff --git a/include/asm-arm/wrappers.h b/include/asm-arm/wrappers.h index 8e5405f..0a89a03 100644 --- a/include/asm-arm/wrappers.h +++ b/include/asm-arm/wrappers.h @@ -33,6 +33,10 @@ #define __put_user_inatomic __put_user #define __get_user_inatomic __get_user +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) +#define vfp_current_hw_state last_VFP_context +#endif /* Linux < 3.1 */ + #ifdef CONFIG_XENO_LEGACY_IPIPE #if !defined(CONFIG_GENERIC_HARDIRQS) \ diff --git a/kernel/cobalt/arch/arm/hal.c b/kernel/cobalt/arch/arm/hal.c index 8ed802c..1609957 100644 --- a/kernel/cobalt/arch/arm/hal.c +++ b/kernel/cobalt/arch/arm/hal.c @@ -52,6 +52,8 @@ rthal_u32frac_t rthal_tsc_to_timer; enum rthal_ktimer_mode rthal_ktimer_saved_mode; +#ifndef CONFIG_IPIPE_CORE + #define RTHAL_SET_ONESHOT_XENOMAI 1 #define RTHAL_SET_ONESHOT_LINUX 2 #define RTHAL_SET_PERIODIC 3 @@ -87,61 +89,6 @@ static inline void restore_normal_hw_mode(void) __ipipe_mach_release_timer(); } -unsigned long rthal_timer_calibrate(void) -{ - unsigned long long start, end, sum = 0, sum_sq = 0; - volatile unsigned const_delay = 0xffffffff; - unsigned long result, flags, tsc_lat; - unsigned int delay = const_delay; - long long diff; - int i, j; - - flags = ipipe_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(); - - ipipe_read_tsc(start); - barrier(); - ipipe_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++) { - ipipe_read_tsc(start); - barrier(); - rthal_timer_program_shot( - rthal_nodiv_imuldiv_ceil(delay, rthal_tsc_to_timer)); - barrier(); - ipipe_read_tsc(end); - diff = end - start - tsc_lat; - if (diff > 0) { - sum += diff; - sum_sq += diff * diff; - } - } - } - - restore_normal_hw_mode(); - - ipipe_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; -} - #ifdef CONFIG_SMP static void critical_sync(void) { @@ -197,8 +144,71 @@ static void rthal_timer_set_periodic(void) ipipe_critical_exit(flags); } +#else /* I-pipe core */ +#define steal_timer(stolen) do { } while (0) +#define force_oneshot_hw_mode() do { } while (0) +#define restore_normal_hw_mode() do { } while (0) +#define rthal_timer_set_oneshot(rt_mode) do { } while (0) +#define rthal_timer_set_periodic() do { } while (0) +#endif /* I-pipe core */ + static int cpu_timers_requested; +unsigned long rthal_timer_calibrate(void) +{ + unsigned long long start, end, sum = 0, sum_sq = 0; + volatile unsigned const_delay = 0xffffffff; + unsigned long result, flags, tsc_lat; + unsigned int delay = const_delay; + long long diff; + int i, j; + + flags = ipipe_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(); + + ipipe_read_tsc(start); + barrier(); + ipipe_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++) { + ipipe_read_tsc(start); + barrier(); + rthal_timer_program_shot( + rthal_nodiv_imuldiv_ceil(delay, rthal_tsc_to_timer)); + barrier(); + ipipe_read_tsc(end); + diff = end - start - tsc_lat; + if (diff > 0) { + sum += diff; + sum_sq += diff * diff; + } + } + } + + restore_normal_hw_mode(); + + ipipe_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; +} + int rthal_timer_request( void (*tick_handler)(void), void (*mode_emul)(enum clock_event_mode mode, @@ -213,8 +223,12 @@ int rthal_timer_request( if (rthal_timerfreq_arg == 0) tmfreq = &rthal_archdata.timer_freq; +#ifndef CONFIG_IPIPE_CORE ret = ipipe_request_tickdev(RTHAL_TIMER_DEVICE, mode_emul, tick_emul, cpu, tmfreq); +#else /* I-ipipe timers */ + ret = ipipe_timer_start(tick_handler, mode_emul, tick_emul, cpu, tmfreq); +#endif /* I-ipipe timers */ switch (ret) { case CLOCK_EVT_MODE_PERIODIC: /* oneshot tick emulation callback won't be used, ask @@ -249,12 +263,14 @@ int rthal_timer_request( if (cpu_timers_requested++ > 0) goto out; +#ifndef CONFIG_IPIPE_CORE ret = ipipe_request_irq(&rthal_archdata.domain, RTHAL_TIMER_IRQ, (ipipe_irq_handler_t)tick_handler, NULL, NULL); if (ret) return ret; +#endif /* !I-ipipe timers */ #ifdef CONFIG_SMP ret = ipipe_request_irq(&rthal_archdata.domain, @@ -272,12 +288,18 @@ out: void rthal_timer_release(int cpu) { +#ifndef CONFIG_IPIPE_CORE ipipe_release_tickdev(cpu); +#else /* I-pipe core */ + ipipe_timer_stop(cpu); +#endif /* I-pipe core */ if (--cpu_timers_requested > 0) return; +#ifndef CONFIG_IPIPE_CORE ipipe_free_irq(&rthal_archdata.domain, RTHAL_TIMER_IRQ); +#endif /* !I-pipe core */ #ifdef CONFIG_SMP ipipe_free_irq(&rthal_archdata.domain, RTHAL_TIMER_IPI); #endif /* CONFIG_SMP */ @@ -316,6 +338,12 @@ void __rthal_arm_fault_range(struct vm_area_struct *vma) int rthal_arch_init(void) { +#ifdef CONFIG_IPIPE_CORE + int rc = ipipe_timers_request(); + if (rc < 0) + return rc; +#endif /* CONFIG_IPIPE_CORE */ + if (rthal_timerfreq_arg == 0) rthal_timerfreq_arg = rthal_get_timerfreq(); @@ -330,6 +358,9 @@ int rthal_arch_init(void) void rthal_arch_cleanup(void) { +#ifdef CONFIG_IPIPE_CORE + ipipe_timers_release(); +#endif /* CONFIG_IPIPE_CORE */ /* Nothing to cleanup so far. */ printk(KERN_INFO "Xenomai: hal/arm stopped.\n"); } _______________________________________________ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git