rtai-core/include/asm-arm/rtai.h

00001 /* 020222 asm-arm/rtai.h
00002 Copyright (c) 2003, Thomas Gleixner, <tglx@linutronix.de)
00003 COPYRIGHT (C) 2002 Guennadi Liakhovetski, DSA GmbH (gl@dsa-ac.de)
00004 COPYRIGHT (C) 2002 Wolfgang Müller (wolfgang.mueller@dsa-ac.de)
00005 Copyright (c) 2001 Alex Züpke, SYSGO RTS GmbH (azu@sysgo.de)
00006 
00007 This program is free software; you can redistribute it and/or modify
00008 it under the terms of version 2 of the GNU General Public License as
00009 published by the Free Software Foundation.
00010 
00011 This program is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU General Public License for more details.
00015 
00016 You should have received a copy of the GNU General Public License
00017 along with this program; if not, write to the Free Software
00018 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 */
00020 /*
00021 --------------------------------------------------------------------------
00022 Acknowledgements
00023 - Paolo Mantegazza      (mantegazza@aero.polimi.it)
00024         creator of RTAI 
00025 */
00026 
00027 #ifndef _RTAI_ASM_ARM_RTAI_H
00028 #define _RTAI_ASM_ARM_RTAI_H
00029 
00030 #define rt_printk_srq           1
00031 
00032 #define NR_GLOBAL_IRQS          NR_IRQS
00033 #define NR_CPU_OWN_IRQS         NR_GLOBAL_IRQS
00034 
00035 #define RTAI_1_IPI  -1 /* Just to make things compile */
00036 #define RTAI_2_IPI  -1
00037 #define RTAI_3_IPI  -1
00038 #define RTAI_4_IPI  -1
00039 
00040 // Do not be messed up by macros names below, is a trick for keeping i386 code.
00041 #define FREQ_8254       FREQ_SYS_CLK
00042 #define LATENCY_8254    LATENCY_MATCH_REG
00043 #define SETUP_TIME_8254 SETUP_TIME_MATCH_REG
00044 #define FREQ_APIC       FREQ_SYS_CLK
00045 
00046 #define RT_TIME_END 0x7FFFFFFFFFFFFFFFLL
00047 
00048 #define DECLR_8254_TSC_EMULATION
00049 #define TICK_8254_TSC_EMULATION
00050 #define SETUP_8254_TSC_EMULATION
00051 #define CLEAR_8254_TSC_EMULATION
00052 
00053 struct desc_struct { void *fun; };
00054 
00055 /* not all ARM cores support 32bit x 32bit = 64bit native ... */
00056 static inline unsigned long long ullmul(unsigned long m0, unsigned long m1)
00057 {
00058         unsigned long long res;
00059 
00060         res = (unsigned long long)m0 * (unsigned long long)m1;
00061 
00062         return res;
00063 }
00064 
00065 static inline unsigned long long ulldiv(unsigned long long ull, unsigned long uld, unsigned long *r)
00066 {
00067         unsigned long long q = ull/(unsigned long long) uld;
00068 
00069         *r = (unsigned long) (ull - q * (unsigned long long) uld);
00070 
00071         return q;       
00072 }
00073 
00074 static inline int imuldiv(unsigned long i, unsigned long mult, unsigned long div)
00075 {
00076         unsigned long q , r;
00077         unsigned long long m;
00078 
00079         if ( mult == div )
00080                 return i;
00081 
00082         m = ((unsigned long long) i * (unsigned long long) mult);
00083         q = (unsigned long) (m / (unsigned long long) div);
00084         r = (unsigned long) (m - (unsigned long long) q * (unsigned long long) div );
00085 
00086         return (r + r) < div ? q : q + 1;
00087 }
00088 
00089 static inline unsigned long long llimd(unsigned long long ull, unsigned long mult, unsigned long div)
00090 {
00091         unsigned long long low, high, q;
00092         unsigned long r;
00093 
00094         low  = ullmul(((unsigned long *)&ull)[0], mult);
00095         high = ullmul(((unsigned long *)&ull)[1], mult);
00096         q = ulldiv(high,div,&r) << 32;
00097         high = ((unsigned long long) r) << 32;
00098         q += ulldiv( high + low, div , &r);
00099         return (r + r) < div ? q : q + 1;
00100 }
00101 
00102 #ifdef __KERNEL__
00103 
00104 #ifndef __cplusplus
00105 #include <asm/rtai_debug.h> /* Keep it first */
00106 #include <rtai_types.h>
00107 #include <asm/rtai_fpu.h>
00108 #include <asm/rtai_atomic.h>
00109 #include <linux/ptrace.h>
00110 #include <linux/spinlock.h>
00111 #include <asm/io.h>
00112 #include <asm/ptrace.h>
00113 #include <asm/irq.h>
00114 #include <asm/system.h>
00115 #include <asm/bitops.h>
00116 #include <asm/proc/hard_system.h>
00117 #endif /* __cplusplus */
00118 
00119 extern unsigned volatile int *locked_cpus;
00120 
00121 #ifndef CONFIG_SMP
00122 extern unsigned long cpu_present_map;
00123 #define smp_num_cpus 1
00124 #endif
00125 
00126 #ifndef CONFIG_RTAI_FPU_SUPPORT
00127 #define enable_fpu()
00128 #endif
00129 
00130 #define hard_unlock_all(flags) hard_restore_flags((flags))
00131 #define hard_save_flags_and_cli(x) hard_save_flags_cli((x))
00132 #define IRQ_DESC irq_desc
00133 extern struct rt_times rt_times;
00134 
00135 typedef unsigned long long rtai_irq_mask_t;
00136 
00137 extern void send_ipi_shorthand(unsigned int shorthand, unsigned int irq);
00138 extern void send_ipi_logical(unsigned long dest, unsigned int irq);
00139 #define rt_assign_irq_to_cpu(irq, cpu)
00140 #define rt_reset_irq_to_sym_mode(irq)
00141 extern int  rt_request_global_irq_ext(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), void *dev_id);
00142 static inline int rt_request_global_irq(int irq, void (*handler)(void))
00143 {
00144         return rt_request_global_irq_ext(irq, (void (*)(int, void*, struct pt_regs*))handler, NULL);
00145 }
00146 extern int  rt_free_global_irq(unsigned int irq);
00147 extern void rt_ack_irq(unsigned int irq);
00148 extern void rt_mask_and_ack_irq(unsigned int irq);
00149 extern void rt_unmask_irq(unsigned int irq);
00150 extern unsigned int rt_startup_irq(unsigned int irq);
00151 extern void rt_shutdown_irq(unsigned int irq);
00152 extern void rt_enable_irq(unsigned int irq);
00153 extern void rt_disable_irq(unsigned int irq);
00154 extern int rt_request_linux_irq(unsigned int irq,
00155         void (*linux_handler)(int irq, void *dev_id, struct pt_regs *regs),
00156         char *linux_handler_id, void *dev_id);
00157 extern int rt_free_linux_irq(unsigned int irq, void *dev_id);
00158 extern void rt_tick_linux_timer(void);
00159 extern struct desc_struct rt_set_full_intr_vect(unsigned int vector, int type, int dpl, void *handler);
00160 extern void rt_reset_full_intr_vect(unsigned int vector, struct desc_struct idt_element);
00161 #define rt_set_intr_handler(vector, handler) ((void *)0)
00162 #define rt_reset_intr_handler(vector, handler)
00163 extern int rt_request_srq(unsigned int label, void (*rtai_handler)(void), long long (*user_handler)(unsigned int whatever));
00164 extern int rt_free_srq(unsigned int srq);
00165 extern void rt_pend_linux_irq(unsigned int irq);
00166 extern void rt_pend_linux_srq(unsigned int srq);
00167 #define rt_request_cpu_own_irq(irq, handler) rt_request_global_irq((irq), (handler))
00168 #define rt_free_cpu_own_irq(irq) rt_free_global_irq((irq))
00169 extern void rt_request_timer(void (*handler)(void), unsigned int tick, int apic);
00170 extern void rt_request_timer_cpuid(void (*handler)(void), unsigned int tick, int cpuid);
00171 extern void rt_free_timer(void);
00172 struct apic_timer_setup_data { int mode, count; };
00173 //extern void rt_request_apic_timers(void (*handler)(void), struct apic_timer_setup_data *apic_timer_data);
00174 //extern void rt_free_apic_timers(void);
00175 extern void rt_mount_rtai(void);
00176 extern void rt_umount_rtai(void);
00177 extern int rt_printk(const char *format, ...);
00178 extern int rtai_print_to_screen(const char *format, ...);
00179 extern int rt_is_linux(void);
00180 
00181 extern RT_TRAP_HANDLER rt_set_rtai_trap_handler(int trap, RT_TRAP_HANDLER handler);
00182 extern void rt_free_rtai_trap_handler(int trap);
00183 
00184 #define ffnz(ul) (ffs(ul)-1)
00185 
00186 /* Timers are architecture dependent */
00187 #include <asm-arm/arch/rtai_arch.h>
00188 #include <asm-arm/arch/rtai_timer.h>
00189 
00190 extern void asmlinkage up_task_sw(void *, void *, void *);
00191 extern void rt_switch_to_linux(int cpuid);
00192 extern void rt_switch_to_real_time(int cpuid);
00193 
00194 #define rt_spin_lock(whatever)
00195 #define rt_spin_unlock(whatever)
00196 
00197 #define rt_get_global_lock()  hard_cli()
00198 #define rt_release_global_lock()
00199 
00200 #define hard_cpu_id()  0
00201 
00202 #define NR_RT_CPUS  1
00203 
00204 #define RTAI_NR_TRAPS 32
00205 
00206 #define save_cr0_and_clts(x)
00207 
00208 #define restore_cr0(x)
00209 
00210 /* Macro to retrieve the link register */
00211 #define getlr(x)                \
00212         ({                      \
00213         __asm__ __volatile__(   \
00214         "mov    %0, lr"         \
00215           : "=r" (x)            \
00216           :                     \
00217           : "memory");          \
00218         })
00219 
00220 #ifdef CONFIG_RTAI_FPU_SUPPORT
00221 /* someone should implement FPU support if necessary ... */
00222 extern void save_fpenv(long *fpu_reg);
00223 extern void restore_fpenv(long *fpu_reg);
00224 typedef struct arm_fpu_env { unsigned long fpu_reg[1]; } FPU_ENV;
00225 #else
00226 typedef struct arm_fpu_env { unsigned long fpu_reg[1]; } FPU_ENV;
00227 #endif
00228 
00229 static inline unsigned long hard_lock_all(void)
00230 {
00231         unsigned long flags;
00232         hard_save_flags_and_cli(flags);
00233         hard_clf(); /* we should block FIQs too */
00234         return flags;
00235 }
00236 
00237 static inline void rt_spin_lock_irq(volatile spinlock_t *lock)          
00238 {
00239         hard_cli(); 
00240         rt_spin_lock(lock);
00241 }
00242 
00243 static inline void rt_spin_unlock_irq(volatile spinlock_t *lock)
00244 {
00245         rt_spin_unlock(lock);
00246         hard_sti();
00247 }
00248 
00249 // Note that the spinlock calling convention below for irqsave/restore is 
00250 // sligtly different from the one used in Linux. Done on purpose to get an 
00251 // error if you use Linux spinlocks in real time applications as they do not
00252 // guaranty any protection because of the soft irq disable. Be careful and
00253 // sure to call the other spinlocks the right way, as they are compatible
00254 // with Linux.
00255 
00256 static inline unsigned int rt_spin_lock_irqsave(volatile spinlock_t *lock)          
00257 {
00258         unsigned long flags;
00259         hard_save_flags_and_cli(flags);
00260         rt_spin_lock(lock);
00261         return flags;
00262 }
00263 
00264 static inline void rt_spin_unlock_irqrestore(unsigned long flags, volatile spinlock_t *lock)
00265 {
00266         rt_spin_unlock(lock);
00267         hard_restore_flags(flags);
00268 }
00269 
00270 /* Global interrupts and flags control (simplified, and modified, version of */
00271 /* similar global stuff in Linux irq.c).                                     */
00272 
00273 static inline void rt_global_cli(void)
00274 {
00275         rt_get_global_lock();
00276 }
00277 
00278 static inline void rt_global_sti(void)
00279 {
00280         rt_release_global_lock();
00281         hard_sti();
00282 }
00283 
00284 static inline int rt_global_save_flags_and_cli(void)
00285 {
00286         unsigned long flags;
00287 
00288         hard_save_flags_and_cli(flags);
00289         if (!test_and_set_bit(hard_cpu_id(), locked_cpus)) {
00290                 while (test_and_set_bit(31, locked_cpus));
00291                 return ((~flags & I_BIT) | 1);
00292         } else {
00293                 return (~flags & I_BIT);
00294         }
00295 }
00296 
00297 static inline void rt_global_save_flags(unsigned long *flags)
00298 {
00299         unsigned long hflags, rflags;
00300 
00301         hard_save_flags_and_cli(hflags);
00302         hflags = ~hflags & I_BIT;
00303         rflags = hflags | !test_bit(hard_cpu_id(), &locked_cpus);
00304         if (hflags) {
00305                 hard_sti();
00306         }
00307         *flags = rflags;
00308 }
00309 
00310 static inline void rt_global_restore_flags(unsigned long flags)
00311 {
00312         switch (flags) {
00313                 case I_BIT | 1:
00314                         rt_release_global_lock();
00315                         hard_sti();
00316                         break;
00317                 case I_BIT | 0:
00318                         rt_get_global_lock();
00319                         hard_sti();
00320                         break;
00321                 case 0 | 1:
00322                         rt_release_global_lock();
00323                         break;
00324                 case 0 | 0:
00325                         rt_get_global_lock();
00326                         break;
00327         }
00328 }
00329 
00330 struct calibration_data {
00331         unsigned int cpu_freq;
00332         int latency;
00333         int setup_time_TIMER_CPUNIT;
00334         int setup_time_TIMER_UNIT;
00335         int timers_tol[NR_RT_CPUS];
00336 };
00337 
00338 extern struct rt_times rt_smp_times[NR_RT_CPUS];
00339 extern struct calibration_data tuned;
00340 
00341 static inline unsigned long xchg_u32(unsigned long *up, unsigned long val)
00342 {
00343         unsigned long flags, ret;
00344 
00345         hard_save_flags_and_cli(flags);
00346         ret = *up;
00347         *up = val;
00348         hard_restore_flags(flags);
00349         return ret;
00350 }
00351 
00352 extern unsigned long linux_save_flags_and_cli_cpuid(int);
00353 
00354 #endif /* !__KERNEL__ */
00355 
00356 #endif /* !_RTAI_ASM_ARM_RTAI_H */

Generated on Sat Jul 24 19:36:02 2004 for RTAI API by doxygen 1.3.4