00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #ifndef _RTAI_ASM_ARM_HAL_H
00049 #define _RTAI_ASM_ARM_HAL_H
00050
00051 #include <linux/version.h>
00052 #include <linux/autoconf.h>
00053
00054 #define RTAI_SYSCALL_MODE
00055
00056 #define LOCKED_LINUX_IN_IRQ_HANDLER
00057 #define DOMAIN_TO_STALL (fusion_domain)
00058
00059 #include <rtai_hal_names.h>
00060 #include <asm/rtai_vectors.h>
00061 #include <rtai_types.h>
00062 #include <asm/div64.h>
00063
00064 #define RTAI_NR_CPUS 1
00065 #define RTAI_NR_IRQS IPIPE_NR_XIRQS
00066
00067 #ifdef CONFIG_ARCH_AT91
00068 #ifndef __LINUX_ARM_ARCH__
00069 #define __LINUX_ARM_ARCH__ 5
00070 #endif
00071 #else
00072 #ifndef __LINUX_ARM_ARCH__
00073 #warning "by default, __LINUX_ARM_ARCH__ is setted to 4 in order to ensure compatibility with all other arm arch."
00074 #define __LINUX_ARM_ARCH__ 4
00075 #endif
00076 #endif
00077
00078 #ifndef _RTAI_FUSION_H
00079
00080 #ifndef __KERNEL__
00081
00082
00083
00084
00085 extern inline unsigned long
00086 ffnz(unsigned long word)
00087 {
00088 int count;
00089
00090
00091 asm( "clz %0, %1" : "=r" (count) : "r" (word) );
00092 return 31-count;
00093 }
00094
00095 #else
00096
00097 extern inline unsigned long
00098 ffnz(unsigned long word)
00099 {
00100 return ffs(word) - 1;
00101 }
00102 #endif
00103
00104 #endif
00105
00106 #ifdef __KERNEL__
00107 #include <asm/system.h>
00108 #else
00109 #define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
00110 #endif
00111
00112 #ifdef __BIG_ENDIAN
00113 #define endianstruct struct { unsigned _h; unsigned _l; } _s
00114 #else
00115 #define endianstruct struct { unsigned _l; unsigned _h; } _s
00116 #endif
00117
00118 #ifndef __rtai_u64tou32
00119 #define __rtai_u64tou32(ull, h, l) ({ \
00120 union { unsigned long long _ull; \
00121 endianstruct; \
00122 } _u; \
00123 _u._ull = (ull); \
00124 (h) = _u._s._h; \
00125 (l) = _u._s._l; \
00126 })
00127 #endif
00128
00129 #ifndef __rtai_u64fromu32
00130 #define __rtai_u64fromu32(h, l) ({ \
00131 union { unsigned long long _ull; \
00132 endianstruct; \
00133 } _u; \
00134 _u._s._h = (h); \
00135 _u._s._l = (l); \
00136 _u._ull; \
00137 })
00138 #endif
00139
00140 #ifndef rtai_ullmul
00141 extern inline unsigned long long
00142 __rtai_generic_ullmul(const unsigned m0,
00143 const unsigned m1)
00144 {
00145 return (unsigned long long) m0 * m1;
00146 }
00147 #define rtai_ullmul(m0,m1) __rtai_generic_ullmul((m0),(m1))
00148 #endif
00149
00150 #ifndef rtai_ulldiv
00151 static inline unsigned long long
00152 __rtai_generic_ulldiv (unsigned long long ull,
00153 const unsigned uld,
00154 unsigned long *const rp)
00155 {
00156 const unsigned r = do_div(ull, uld);
00157
00158 if (rp)
00159 *rp = r;
00160
00161 return ull;
00162 }
00163 #define rtai_ulldiv(ull,uld,rp) __rtai_generic_ulldiv((ull),(uld),(rp))
00164 #endif
00165
00166 #ifndef rtai_uldivrem
00167 #define rtai_uldivrem(ull,ul,rp) ((unsigned) rtai_ulldiv((ull),(ul),(rp)))
00168 #endif
00169
00170 #ifndef rtai_imuldiv
00171 extern inline int
00172 __rtai_generic_imuldiv (int i,
00173 int mult,
00174 int div)
00175 {
00176
00177 const unsigned long long ull = rtai_ullmul(i, mult);
00178 return rtai_uldivrem(ull, div, NULL);
00179 }
00180 #define rtai_imuldiv(i,m,d) __rtai_generic_imuldiv((i),(m),(d))
00181 #endif
00182
00183 #ifndef rtai_llimd
00184
00185
00186
00187 static inline unsigned long long
00188 __rtai_generic_div96by32 (const unsigned long long h,
00189 const unsigned l,
00190 const unsigned d,
00191 unsigned long *const rp)
00192 {
00193 unsigned long rh;
00194 const unsigned qh = rtai_uldivrem(h, d, &rh);
00195 const unsigned long long t = __rtai_u64fromu32(rh, l);
00196 const unsigned ql = rtai_uldivrem(t, d, rp);
00197
00198 return __rtai_u64fromu32(qh, ql);
00199 }
00200
00201 extern inline unsigned long long
00202 __rtai_generic_ullimd (const unsigned long long op,
00203 const unsigned m,
00204 const unsigned d)
00205 {
00206 unsigned oph, opl, tlh, tll;
00207 unsigned long long th, tl;
00208
00209 __rtai_u64tou32(op, oph, opl);
00210 tl = rtai_ullmul(opl, m);
00211 __rtai_u64tou32(tl, tlh, tll);
00212 th = rtai_ullmul(oph, m);
00213 th += tlh;
00214
00215 return __rtai_generic_div96by32(th, tll, d, NULL);
00216 }
00217
00218 extern inline long long
00219 __rtai_generic_llimd (long long op,
00220 unsigned m,
00221 unsigned d)
00222 {
00223
00224 if(op < 0LL)
00225 return -__rtai_generic_ullimd(-op, m, d);
00226 return __rtai_generic_ullimd(op, m, d);
00227 }
00228 #define rtai_llimd(ll,m,d) __rtai_generic_llimd((ll),(m),(d))
00229 #endif
00230
00231 #if defined(__KERNEL__) && !defined(__cplusplus)
00232 #include <linux/sched.h>
00233 #include <linux/interrupt.h>
00234
00235 #include <asm/system.h>
00236 #include <asm/io.h>
00237 #include <asm/rtai_atomic.h>
00238 #include <asm/rtai_fpu.h>
00239
00240 #include <rtai_trace.h>
00241
00242 struct rtai_realtime_irq_s {
00243 int (*handler)(unsigned irq, void *cookie);
00244 void *cookie;
00245 int retmode;
00246 int cpumask;
00247 int (*irq_ack)(unsigned int);
00248 };
00249
00250 #define RTAI_DOMAIN_ID 0x9ac15d93 // nam2num("rtai_d")
00251 #define RTAI_NR_TRAPS HAL_NR_FAULTS
00252 #define RTAI_NR_SRQS 32
00253
00254 #define RTAI_TIME_LIMIT 0x7000000000000000LL
00255
00256 #define RTAI_IFLAG 9
00257
00258 #define rtai_cpuid() hal_processor_id()
00259 #define rtai_tskext(idx) hal_tskext[idx]
00260
00261
00262 #define rtai_hw_cli() hal_hw_cli()
00263 #define rtai_hw_sti() hal_hw_sti()
00264 #define rtai_hw_save_flags_and_cli(x) hal_hw_local_irq_save(x)
00265 #define rtai_hw_restore_flags(x) hal_hw_local_irq_restore(x)
00266 #define rtai_hw_save_flags(x) hal_hw_local_irq_flags(x)
00267
00268
00269 #define rtai_cli() hal_hw_cli()
00270 #define rtai_sti() hal_hw_sti()
00271 #define rtai_save_flags_and_cli(x) hal_hw_local_irq_save(x)
00272 #define rtai_restore_flags(x) hal_hw_local_irq_restore(x)
00273 #define rtai_save_flags(x) hal_hw_local_irq_flags(x)
00274
00275 extern volatile unsigned long hal_pended;
00276
00277 static inline struct hal_domain_struct *get_domain_pointer(int n)
00278 {
00279 struct list_head *p = hal_pipeline.next;
00280 struct hal_domain_struct *d;
00281 unsigned long i = 0;
00282 while (p != &hal_pipeline) {
00283 d = list_entry(p, struct hal_domain_struct, p_link);
00284 if (++i == n) {
00285 return d;
00286 }
00287 p = d->p_link.next;
00288 }
00289 return (struct hal_domain_struct *)i;
00290 }
00291
00292 #define hal_pend_domain_uncond(irq, domain, cpuid) \
00293 do { \
00294 hal_irq_hits_pp(irq, domain, cpuid); \
00295 __set_bit((irq) & IPIPE_IRQ_IMASK, &domain->cpudata[cpuid].irq_pending_lo[(irq) >> IPIPE_IRQ_ISHIFT]); \
00296 __set_bit((irq) >> IPIPE_IRQ_ISHIFT, &domain->cpudata[cpuid].irq_pending_hi); \
00297 test_and_set_bit(cpuid, &hal_pended); \
00298 } while (0)
00299
00300 #define hal_pend_uncond(irq, cpuid) hal_pend_domain_uncond(irq, hal_root_domain, cpuid)
00301
00302 #define hal_fast_flush_pipeline(cpuid) \
00303 do { \
00304 if (hal_root_domain->cpudata[cpuid].irq_pending_hi != 0) { \
00305 rtai_cli(); \
00306 hal_sync_stage(IPIPE_IRQMASK_ANY); \
00307 } \
00308 } while (0)
00309
00310 extern volatile unsigned long *ipipe_root_status[];
00311
00312 #define hal_test_and_fast_flush_pipeline(cpuid) \
00313 do { \
00314 if (!test_bit(IPIPE_STALL_FLAG, ipipe_root_status[cpuid])) { \
00315 hal_fast_flush_pipeline(cpuid); \
00316 rtai_sti(); \
00317 } \
00318 } while (0)
00319
00320 #ifdef CONFIG_PREEMPT
00321 #define rtai_save_and_lock_preempt_count() \
00322 do { int *prcntp, prcnt; prcnt = xchg(prcntp = &preempt_count(), 1);
00323 #define rtai_restore_preempt_count() \
00324 *prcntp = prcnt; } while (0)
00325 #else
00326 #define rtai_save_and_lock_preempt_count();
00327 #define rtai_restore_preempt_count();
00328 #endif
00329
00330 typedef int (*rt_irq_handler_t)(unsigned irq, void *cookie);
00331
00332 #define RTAI_CPU_FREQ (rtai_tunables.cpu_freq)
00333
00334 struct calibration_data {
00335
00336 unsigned long cpu_freq;
00337 unsigned long apic_freq;
00338 int latency;
00339 int setup_time_TIMER_CPUNIT;
00340 int setup_time_TIMER_UNIT;
00341 int timers_tol[RTAI_NR_CPUS];
00342 };
00343
00344 struct apic_timer_setup_data {
00345
00346 int mode;
00347 int count;
00348 };
00349
00350 extern struct rt_times rt_times;
00351 extern struct rt_times rt_smp_times[RTAI_NR_CPUS];
00352 extern struct calibration_data rtai_tunables;
00353 extern volatile unsigned long rtai_cpu_lock;
00354
00355 #define SET_TASKPRI(cpuid)
00356 #define CLR_TASKPRI(cpuid)
00357
00358 extern struct rtai_switch_data {
00359 volatile unsigned long sflags;
00360 volatile unsigned long lflags;
00361 } rtai_linux_context[RTAI_NR_CPUS];
00362
00363 static inline unsigned long rtai_save_flags_irqbit(void)
00364 {
00365 unsigned long flags;
00366 rtai_save_flags(flags);
00367 return flags & (1 << RTAI_IFLAG);
00368 }
00369
00370 static inline unsigned long rtai_save_flags_irqbit_and_cli(void)
00371 {
00372 unsigned long flags;
00373 rtai_save_flags_and_cli(flags);
00374 return flags & (1 << RTAI_IFLAG);
00375 }
00376
00377 #define _send_sched_ipi(dest)
00378
00379 #define rt_spin_lock(lock)
00380 #define rt_spin_unlock(lock)
00381
00382 #define rt_spin_lock_irq(lock) do { rtai_cli(); } while (0)
00383 #define rt_spin_unlock_irq(lock) do { rtai_sti(); } while (0)
00384
00385 static inline unsigned long rt_spin_lock_irqsave(spinlock_t *lock)
00386 {
00387 unsigned long flags;
00388 rtai_save_flags_and_cli(flags);
00389 return flags;
00390 }
00391 #define rt_spin_unlock_irqrestore(flags, lock) do { rtai_restore_flags(flags); } while (0)
00392
00393 #define rt_get_global_lock() do { rtai_cli(); } while (0)
00394 #define rt_release_global_lock()
00395
00396 #define rt_global_cli() do { rtai_cli(); } while (0)
00397 #define rt_global_sti() do { rtai_sti(); } while (0)
00398
00399 static inline unsigned long rt_global_save_flags_and_cli(void)
00400 {
00401 unsigned long flags;
00402 rtai_save_flags_and_cli(flags);
00403 return flags;
00404 }
00405 #define rt_global_restore_flags(flags) do { rtai_restore_flags(flags); } while (0)
00406
00407 #define rt_global_save_flags(flags) do { rtai_save_flags(*flags); } while (0)
00408
00409 asmlinkage int rt_printk(const char *format, ...);
00410 asmlinkage int rt_printk_sync(const char *format, ...);
00411
00412 extern struct hal_domain_struct rtai_domain;
00413 extern struct hal_domain_struct *fusion_domain;
00414
00415 #define _rt_switch_to_real_time(cpuid) \
00416 do { \
00417 rtai_linux_context[cpuid].lflags = xchg(ipipe_root_status[cpuid], (1 << IPIPE_STALL_FLAG)); \
00418 rtai_linux_context[cpuid].sflags = 1; \
00419 hal_current_domain(cpuid) = &rtai_domain; \
00420 } while (0)
00421
00422 #define rt_switch_to_linux(cpuid) \
00423 do { \
00424 if (rtai_linux_context[cpuid].sflags) { \
00425 hal_current_domain(cpuid) = hal_root_domain; \
00426 *ipipe_root_status[cpuid] = rtai_linux_context[cpuid].lflags; \
00427 rtai_linux_context[cpuid].sflags = 0; \
00428 CLR_TASKPRI(cpuid); \
00429 } \
00430 } while (0)
00431
00432 #define rt_switch_to_real_time(cpuid) \
00433 do { \
00434 if (!rtai_linux_context[cpuid].sflags) { \
00435 _rt_switch_to_real_time(cpuid); \
00436 } \
00437 } while (0)
00438
00439 #define rtai_get_intr_handler(v) \
00440 ((idt_table[v].b & 0xFFFF0000) | (idt_table[v].a & 0x0000FFFF))
00441 #define ack_bad_irq hal_ack_system_irq // linux does not export ack_bad_irq
00442
00443 #define rtai_init_taskpri_irqs() \
00444 do { \
00445 int v; \
00446 for (v = SPURIOUS_APIC_VECTOR + 1; v < 256; v++) { \
00447 hal_virtualize_irq(hal_root_domain, v - FIRST_EXTERNAL_VECTOR, (void (*)(unsigned))rtai_get_intr_handler(v), (void *)ack_bad_irq, IPIPE_HANDLE_MASK); \
00448 } \
00449 } while (0)
00450
00451 static inline int rt_save_switch_to_real_time(int cpuid)
00452 {
00453 SET_TASKPRI(cpuid);
00454 if (!rtai_linux_context[cpuid].sflags) {
00455 _rt_switch_to_real_time(cpuid);
00456 return 0;
00457 }
00458 return 1;
00459 }
00460
00461 #define rt_restore_switch_to_linux(sflags, cpuid) \
00462 do { \
00463 if (!sflags) { \
00464 rt_switch_to_linux(cpuid); \
00465 } else if (!rtai_linux_context[cpuid].sflags) { \
00466 SET_TASKPRI(cpuid); \
00467 _rt_switch_to_real_time(cpuid); \
00468 } \
00469 } while (0)
00470
00471 #define in_hrt_mode(cpuid) (rtai_linux_context[cpuid].sflags)
00472
00473
00474
00475 unsigned long rtai_critical_enter(void (*synch)(void));
00476
00477 void rtai_critical_exit(unsigned long flags);
00478
00479 int rtai_calibrate_8254(void);
00480
00481 void rtai_set_linux_task_priority(struct task_struct *task,
00482 int policy,
00483 int prio);
00484
00485 long rtai_catch_event (struct hal_domain_struct *ipd, unsigned long event, int (*handler)(unsigned long, void *));
00486
00487 #endif
00488
00489
00490
00491 #ifdef __KERNEL__
00492
00493 #include <linux/kernel.h>
00494
00495 #define rtai_print_to_screen rt_printk
00496
00497 void *ll2a(long long ll, char *s);
00498
00499 #ifdef __cplusplus
00500 extern "C" {
00501 #endif
00502
00503 int rt_request_irq(unsigned irq,
00504 int (*handler)(unsigned irq, void *cookie),
00505 void *cookie,
00506 int retmode);
00507
00508 int rt_release_irq(unsigned irq);
00509
00510 int rt_set_irq_ack(unsigned int irq, int (*irq_ack)(unsigned int));
00511
00512 static inline int rt_request_irq_wack(unsigned irq, int (*handler)(unsigned irq, void *cookie), void *cookie, int retmode, int (*irq_ack)(unsigned int))
00513 {
00514 int retval;
00515 if ((retval = rt_request_irq(irq, handler, cookie, retmode)) < 0) {
00516 return retval;
00517 }
00518 return rt_set_irq_ack(irq, irq_ack);
00519 }
00520
00521 void rt_set_irq_cookie(unsigned irq, void *cookie);
00522
00523 void rt_set_irq_retmode(unsigned irq, int fastret);
00524
00525
00526
00527
00528
00529 unsigned rt_startup_irq(unsigned irq);
00530
00531 void rt_shutdown_irq(unsigned irq);
00532
00533 void rt_enable_irq(unsigned irq);
00534
00535 void rt_disable_irq(unsigned irq);
00536
00537 void rt_mask_and_ack_irq(unsigned irq);
00538
00539 void rt_unmask_irq(unsigned irq);
00540
00541 void rt_ack_irq(unsigned irq);
00542
00543 void rt_do_irq(unsigned irq);
00544
00545 int rt_request_linux_irq(unsigned irq,
00546 void *handler,
00547 char *name,
00548 void *dev_id);
00549
00550 int rt_free_linux_irq(unsigned irq,
00551 void *dev_id);
00552
00553 void rt_pend_linux_irq(unsigned irq);
00554
00555 RTAI_SYSCALL_MODE void usr_rt_pend_linux_irq(unsigned irq);
00556
00557 void rt_pend_linux_srq(unsigned srq);
00558
00559 int rt_request_srq(unsigned label,
00560 void (*k_handler)(void),
00561 long long (*u_handler)(unsigned long));
00562
00563 int rt_free_srq(unsigned srq);
00564
00565 int rt_assign_irq_to_cpu(int irq,
00566 unsigned long cpus_mask);
00567
00568 int rt_reset_irq_to_sym_mode(int irq);
00569
00570 void rt_request_timer_cpuid(void (*handler)(void),
00571 unsigned tick,
00572 int cpuid);
00573
00574 void rt_request_apic_timers(void (*handler)(void),
00575 struct apic_timer_setup_data *tmdata);
00576
00577 void rt_free_apic_timers(void);
00578
00579 int rt_request_timer(void (*handler)(void), unsigned tick, int use_apic);
00580
00581 void rt_free_timer(void);
00582
00583 RT_TRAP_HANDLER rt_set_trap_handler(RT_TRAP_HANDLER handler);
00584
00585 void rt_release_rtc(void);
00586
00587 void rt_request_rtc(long rtc_freq, void *handler);
00588
00589 #define rt_mount()
00590
00591 #define rt_umount()
00592
00593 void (*rt_set_ihook(void (*hookfn)(int)))(int);
00594
00595
00596
00597 static inline int rt_request_global_irq(unsigned irq, void (*handler)(void))
00598 {
00599 return rt_request_irq(irq, (int (*)(unsigned,void *))handler, 0, 0);
00600 }
00601
00602 static inline int rt_request_global_irq_ext(unsigned irq, void (*handler)(void), unsigned long cookie)
00603 {
00604 return rt_request_irq(irq, (int (*)(unsigned,void *))handler, (void *)cookie, 1);
00605 }
00606
00607 static inline void rt_set_global_irq_ext(unsigned irq, int ext, unsigned long cookie)
00608 {
00609 rt_set_irq_cookie(irq, (void *)cookie);
00610 }
00611
00612 static inline int rt_free_global_irq(unsigned irq)
00613 {
00614 return rt_release_irq(irq);
00615 }
00616
00617 #ifdef __cplusplus
00618 }
00619 #endif
00620
00621
00622
00623
00624
00625
00626
00627 #include <asm-arm/arch/rtai_timer.h>
00628
00629 #endif
00630
00631 #include <asm/rtai_oldnames.h>
00632
00633 #define RTAI_DEFAULT_TICK 100000
00634 #ifdef CONFIG_RTAI_TRACE
00635 #define RTAI_DEFAULT_STACKSZ 8192
00636 #else
00637 #define RTAI_DEFAULT_STACKSZ 1024
00638 #endif
00639
00640
00641
00642 #ifndef _RTAI_HAL_XN_H
00643 #define _RTAI_HAL_XN_H
00644
00645 #define SET_FUSION_TIMER_RUNNING()
00646
00647 #define CLEAR_FUSION_TIMER_RUNNING()
00648
00649 #define IS_FUSION_TIMER_RUNNING() (0)
00650
00651 #define NON_RTAI_SCHEDULE(cpuid) do { schedule(); } while (0)
00652
00653 #endif
00654
00655 #endif