base/arch/arm/hal/hal.c

Go to the documentation of this file.
00001 /*
00002  * ARM RTAI over Adeos -- based on ARTI for x86 and RTHAL for ARM.
00003  *
00004  * Original RTAI/x86 layer implementation:
00005  *   Copyright (c) 2000 Paolo Mantegazza (mantegazza@aero.polimi.it)
00006  *   Copyright (c) 2000 Steve Papacharalambous (stevep@zentropix.com)
00007  *   Copyright (c) 2000 Stuart Hughes
00008  *   and others.
00009  *
00010  * RTAI/x86 rewrite over Adeos:
00011  *   Copyright (c) 2002 Philippe Gerum (rpm@xenomai.org)
00012  *
00013  * Original RTAI/ARM RTHAL implementation:
00014  *   Copyright (c) 2000 Pierre Cloutier (pcloutier@poseidoncontrols.com)
00015  *   Copyright (c) 2001 Alex Züpke, SYSGO RTS GmbH (azu@sysgo.de)
00016  *   Copyright (c) 2002 Guennadi Liakhovetski DSA GmbH (gl@dsa-ac.de)
00017  *   Copyright (c) 2002 Steve Papacharalambous (stevep@zentropix.com)
00018  *   Copyright (c) 2002 Wolfgang Müller (wolfgang.mueller@dsa-ac.de)
00019  *   Copyright (c) 2003 Bernard Haible, Marconi Communications
00020  *   Copyright (c) 2003 Thomas Gleixner (tglx@linutronix.de)
00021  *   Copyright (c) 2003 Philippe Gerum (rpm@xenomai.org)
00022  *
00023  * RTAI/ARM over Adeos rewrite:
00024  *   Copyright (c) 2004-2005 Michael Neuhauser, Firmix Software GmbH (mike@firmix.at)
00025  *
00026  * RTAI/ARM over Adeos rewrite for PXA255_2.6.7:
00027  *   Copyright (c) 2005 Stefano Gafforelli (stefano.gafforelli@tiscali.it)
00028  *   Copyright (c) 2005 Luca Pizzi (lucapizzi@hotmail.com)
00029  *
00030  * RTAI/ARM over Adeos : 
00031  *   Copyright (C) 2007 Adeneo
00032  *
00033  * This program is free software; you can redistribute it and/or modify it under
00034  * the terms of the GNU General Public License as published by the Free Software
00035  * Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, USA; either version 2 of
00036  * the License, or (at your option) any later version.
00037  *
00038  * This program is distributed in the hope that it will be useful, but WITHOUT
00039  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00040  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00041  * details.
00042  *
00043  * You should have received a copy of the GNU General Public License along with
00044  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00045  * Place - Suite 330, Boston, MA 02111-1307, USA.
00046  */
00047 #include <linux/version.h>
00048 #include <linux/autoconf.h>
00049 #include <linux/module.h>
00050 #include <linux/init.h>
00051 #include <linux/stddef.h>
00052 #include <linux/sched.h>
00053 #include <linux/timer.h>
00054 #include <linux/interrupt.h>
00055 #include <asm/mach/irq.h>
00056 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
00057 #   include <asm/proc/ptrace.h>
00058 #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */
00059 #   include <asm/ptrace.h>
00060 #   include <asm/uaccess.h>
00061 #   include <asm/unistd.h>
00062 #   include <stdarg.h>
00063 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) */
00064 #define __RTAI_HAL__
00065 #include <asm/rtai_hal.h>
00066 #include <asm/rtai_lxrt.h>
00067 #include <asm/rtai_usi.h>
00068 #ifdef CONFIG_PROC_FS
00069 #include <linux/proc_fs.h>
00070 #include <rtai_proc_fs.h>
00071 #endif /* CONFIG_PROC_FS */
00072 #include <rtai_version.h>
00073 
00074 #include <asm/rtai_usi.h>
00075 #include <asm/unistd.h>
00076 
00077 MODULE_LICENSE("GPL");
00078 
00079 static unsigned long rtai_cpufreq_arg = RTAI_CALIBRATED_CPU_FREQ;
00080 RTAI_MODULE_PARM(rtai_cpufreq_arg, ulong);
00081 
00082 static unsigned long IsolCpusMask = 0;
00083 RTAI_MODULE_PARM(IsolCpusMask, ulong);
00084 
00085 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,31) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
00086 
00087 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
00088 #define rtai_irq_desc(irq) (irq_desc[irq].handler)
00089 #else
00090 #define rtai_irq_desc(irq) (irq_desc[irq].chip)
00091 #endif
00092 
00093 #define BEGIN_PIC()
00094 #define END_PIC()
00095 #undef hal_lock_irq
00096 #undef hal_unlock_irq
00097 #define hal_lock_irq(x, y, z)
00098 #define hal_unlock_irq(x, y)
00099 
00100 #else
00101 
00102 extern struct hw_interrupt_type hal_std_irq_dtype[];
00103 #define rtai_irq_desc(irq) (&hal_std_irq_dtype[irq])
00104 
00105 #define BEGIN_PIC() \
00106 do { \
00107         unsigned long flags, pflags, cpuid; \
00108     rtai_save_flags_and_cli(flags); \
00109     cpuid = rtai_cpuid(); \
00110     pflags = xchg(ipipe_root_status[cpuid], 1 << IPIPE_STALL_FLAG); \
00111     rtai_save_and_lock_preempt_count()
00112 
00113 #define END_PIC() \
00114     rtai_restore_preempt_count(); \
00115     *ipipe_root_status[cpuid] = pflags; \
00116     rtai_restore_flags(flags); \
00117 } while (0)
00118 
00119 #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,31) && LINUX_VERSION_ ... */
00120 
00121 /* global */
00122 
00123 struct rtai_realtime_irq_s rtai_realtime_irq[RTAI_NR_IRQS];
00124 struct hal_domain_struct rtai_domain;
00125 struct rt_times     rt_times;
00126 struct rt_times     rt_smp_times[RTAI_NR_CPUS] = { { 0 } };
00127 struct rtai_switch_data rtai_linux_context[RTAI_NR_CPUS];
00128 volatile unsigned long *ipipe_root_status[RTAI_NR_CPUS];
00129 struct calibration_data rtai_tunables;
00130 volatile unsigned long  rtai_cpu_realtime;
00131 volatile unsigned long  rtai_cpu_lock;
00132 long long       (*rtai_lxrt_invoke_entry)(unsigned long, void *); /* hook for lxrt calls */
00133 struct { volatile int locked, rqsted; } rt_scheduling[RTAI_NR_CPUS];
00134 #ifdef CONFIG_PROC_FS
00135 struct proc_dir_entry   *rtai_proc_root = NULL;
00136 #endif
00137 
00138 #ifdef CONFIG_RTAI_SCHED_ISR_LOCK
00139 static void (*rtai_isr_hook)(int cpuid);
00140 #endif 
00141 
00142 #define CHECK_KERCTX()
00143 
00144 /* local */
00145 
00146 static struct {
00147     unsigned long flags;
00148     int count;
00149 }           rtai_linux_irq[NR_IRQS];
00150 static struct {
00151     void (*k_handler)(void);
00152     long long (*u_handler)(unsigned long);
00153     unsigned long label;
00154 }           rtai_sysreq_table[RTAI_NR_SRQS];
00155 static unsigned     rtai_sysreq_virq;
00156 static unsigned long    rtai_sysreq_map = 3; /* srqs #[0-1] are reserved */
00157 static unsigned long    rtai_sysreq_pending;
00158 static unsigned long    rtai_sysreq_running;
00159 static spinlock_t   rtai_lsrq_lock = SPIN_LOCK_UNLOCKED;
00160 static volatile int rtai_sync_level;
00161 static atomic_t     rtai_sync_count = ATOMIC_INIT(1);
00162 static RT_TRAP_HANDLER  rtai_trap_handler;
00163 volatile unsigned long  hal_pended;
00164 
00165 unsigned long
00166 rtai_critical_enter(void (*synch)(void))
00167 {
00168     unsigned long flags = hal_critical_enter(synch);
00169 
00170     if (atomic_dec_and_test(&rtai_sync_count))
00171     rtai_sync_level = 0;
00172     else if (synch != NULL)
00173     printk(KERN_INFO "RTAI[hal]: warning: nested sync will fail.\n");
00174 
00175     return flags;
00176 }
00177 
00178 void
00179 rtai_critical_exit(unsigned long flags)
00180 {
00181     atomic_inc(&rtai_sync_count);
00182     hal_critical_exit(flags);
00183 }
00184 
00185 int
00186 rt_request_irq(unsigned irq, int (*handler)(unsigned irq, void *cookie), void *cookie, int retmode)
00187 {
00188     unsigned long flags;
00189 
00190     if (handler == NULL || irq >= RTAI_NR_IRQS)
00191     return -EINVAL;
00192 
00193     if (rtai_realtime_irq[irq].handler != NULL)
00194     return -EBUSY;
00195 
00196     flags = rtai_critical_enter(NULL);
00197     rtai_realtime_irq[irq].handler = (void *)handler;
00198     rtai_realtime_irq[irq].irq_ack = hal_root_domain->irqs[irq].acknowledge;
00199     rtai_realtime_irq[irq].cookie = cookie;
00200     rtai_critical_exit(flags);
00201     return 0;
00202 }
00203 
00204 int
00205 rt_release_irq(unsigned irq)
00206 {
00207     unsigned long flags;
00208     if (irq >= RTAI_NR_IRQS || !rtai_realtime_irq[irq].handler) {
00209     return -EINVAL;
00210     }
00211     flags = rtai_critical_enter(NULL);
00212     rtai_realtime_irq[irq].handler = NULL;
00213     rtai_realtime_irq[irq].irq_ack = hal_root_domain->irqs[irq].acknowledge;
00214     rtai_critical_exit(flags);
00215     return 0;
00216 }
00217 
00218 int rt_set_irq_ack(unsigned irq, int (*irq_ack)(unsigned int))
00219 {
00220     if (irq >= RTAI_NR_IRQS) {
00221         return -EINVAL;
00222     }
00223     rtai_realtime_irq[irq].irq_ack = irq_ack ? irq_ack : hal_root_domain->irqs[irq].acknowledge;
00224     return 0;
00225 }
00226 
00227 void
00228 rt_set_irq_cookie(unsigned irq, void *cookie)
00229 {
00230     if (irq < NR_IRQS)
00231     rtai_realtime_irq[irq].cookie = cookie;
00232 }
00233 
00234 /*
00235  * Upgrade this function for SMP systems
00236  */
00237 
00238 void rt_request_apic_timers (void (*handler)(void), struct apic_timer_setup_data *tmdata) { return; }
00239 void rt_free_apic_timers(void) { rt_free_timer(); }
00240 int rt_assign_irq_to_cpu (int irq, unsigned long cpus_mask) { return 0; }
00241 int rt_reset_irq_to_sym_mode (int irq) { return 0; }
00242 
00243 void rt_request_rtc(long rtc_freq, void *handler)
00244 {
00245     rt_printk("*** RTC NOT IMPLEMENTED YET ON THIS ARCH ***\n");
00246 }
00247 
00248 void rt_release_rtc(void)
00249 {
00250     rt_printk("*** RTC NOT IMPLEMENTED YET ON THIS ARCH ***\n");
00251 }
00252 
00253 /*
00254  * The function below allow you to manipulate the PIC at hand, but you must
00255  * know what you are doing. Such a duty does not pertain to this manual and
00256  * you should refer to your PIC datasheet.
00257  *
00258  * Note that Linux has the same functions, but they must be used only for its
00259  * interrupts. Only the ones below can be safely used in real time handlers.
00260  *
00261  * It must also be remarked that when you install a real time interrupt handler,
00262  * RTAI already calls either rt_mask_and_ack_irq(), for level triggered
00263  * interrupts, or rt_ack_irq(), for edge triggered interrupts, before passing
00264  * control to your interrupt handler. Thus, generally you should just call
00265  * rt_unmask_irq() at due time, for level triggered interrupts, while nothing
00266  * should be done for edge triggered ones. Recall that in the latter case you
00267  * allow also any new interrupts on the same request as soon as you enable
00268  * interrupts at the CPU level.
00269  * 
00270  * Often some of the functions below do equivalent things. Once more there is no
00271  * way of doing it right except by knowing the hardware you are manipulating.
00272  * Furthermore you must also remember that when you install a hard real time
00273  * handler the related interrupt is usually disabled, unless you are overtaking
00274  * one already owned by Linux which has been enabled by it.   Recall that if
00275  * have done it right, and interrupts do not show up, it is likely you have just
00276  * to rt_enable_irq() your irq.
00277  *
00278  * Note: Adeos already does all the magic that allows to call the
00279  * interrupt controller routines safely.
00280  */
00281 
00282 unsigned
00283 rt_startup_irq(unsigned irq)
00284 {
00285         int retval;
00286 
00287     BEGIN_PIC();
00288     hal_unlock_irq(hal_root_domain, irq);
00289     rtai_irq_desc(irq)->unmask(irq);
00290     retval = rtai_irq_desc(irq)->startup(irq);
00291     END_PIC();
00292         return retval;
00293 }
00294 
00295 void
00296 rt_shutdown_irq(unsigned irq)
00297 {
00298     BEGIN_PIC();
00299     rtai_irq_desc(irq)->shutdown(irq);
00300     hal_clear_irq(hal_root_domain, irq);
00301     END_PIC();
00302 }
00303 
00304 void
00305 rt_enable_irq(unsigned irq)
00306 {
00307     BEGIN_PIC();
00308     hal_unlock_irq(hal_root_domain, irq);
00309     rtai_irq_desc(irq)->enable(irq);
00310     END_PIC();
00311 }
00312 
00313 void
00314 rt_disable_irq(unsigned irq)
00315 {
00316     BEGIN_PIC();
00317     rtai_irq_desc(irq)->disable(irq);
00318     hal_lock_irq(hal_root_domain, cpuid, irq);
00319     END_PIC();
00320 }
00321 
00322 void
00323 rt_mask_and_ack_irq(unsigned irq)
00324 {
00325     BEGIN_PIC();
00326     rtai_irq_desc(irq)->mask(irq);
00327     END_PIC();
00328 }
00329 
00330 static inline void _rt_end_irq (unsigned irq)
00331 {
00332     BEGIN_PIC();
00333     if (
00334         !(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
00335         hal_unlock_irq(hal_root_domain, irq);
00336     }
00337     rtai_irq_desc(irq)->end(irq);
00338     END_PIC();
00339 }
00340 
00341 void
00342 rt_unmask_irq(unsigned irq)
00343 {
00344     BEGIN_PIC();
00345     rtai_irq_desc(irq)->unmask(irq);
00346     END_PIC();
00347 }
00348 
00349 void
00350 rt_ack_irq(unsigned irq)
00351 {
00352     BEGIN_PIC();
00353     hal_unlock_irq(hal_root_domain, irq);
00354     rtai_irq_desc(irq)->enable(irq);
00355     END_PIC();
00356 }
00357 
00358 void rt_end_irq (unsigned irq)
00359 {
00360     _rt_end_irq(irq);
00361 }
00362 
00363 /**
00364  * Install shared Linux interrupt handler.
00365  *
00366  * rt_request_linux_irq installs function @a handler as a standard Linux
00367  * interrupt service routine for IRQ level @a irq forcing Linux to share the IRQ
00368  * with other interrupt handlers, even if it does not want. The handler is
00369  * appended to any already existing Linux handler for the same irq and is run by
00370  * Linux irq as any of its handler. In this way a real time application can
00371  * monitor Linux interrupts handling at its will. The handler appears in
00372  * /proc/interrupts.
00373  *
00374  * @param handler pointer on the interrupt service routine to be installed.
00375  *
00376  * @param name is a name for /proc/interrupts.
00377  *
00378  * @param dev_id is to pass to the interrupt handler, in the same way as the
00379  * standard Linux irq request call.
00380  *
00381  * The interrupt service routine can be uninstalled with rt_free_linux_irq().
00382  *
00383  * @retval 0 on success.
00384  * @retval EINVAL if @a irq is not a valid IRQ number or handler is @c NULL.
00385  * @retval EBUSY if there is already a handler of interrupt @a irq.
00386  */
00387 
00388 int
00389 rt_request_linux_irq (unsigned irq, void *handler, char *name, void *dev_id)
00390 {
00391     unsigned long flags;
00392 
00393     if (irq >= RTAI_NR_IRQS || !handler) {
00394     return -EINVAL;
00395     }
00396 
00397     rtai_save_flags_and_cli(flags);
00398     spin_lock(&irq_desc[irq].lock);
00399     if (rtai_linux_irq[irq].count++ == 0 && irq_desc[irq].action) {
00400     rtai_linux_irq[irq].flags = irq_desc[irq].action->flags;
00401     irq_desc[irq].action->flags |= SA_SHIRQ;
00402     }
00403     spin_unlock(&irq_desc[irq].lock);
00404     rtai_restore_flags(flags);
00405 
00406     request_irq(irq, handler, SA_SHIRQ, name, dev_id);
00407 
00408     return 0;
00409 }
00410 
00411 /**
00412  * Uninstall shared Linux interrupt handler.
00413  *
00414  * @param dev_id is to pass to the interrupt handler, in the same way as the
00415  * standard Linux irq request call.
00416  *
00417  * @param irq is the IRQ level of the interrupt handler to be freed.
00418  *
00419  * @retval 0 on success.
00420  * @retval EINVAL if @a irq is not a valid IRQ number.
00421  */
00422 int
00423 rt_free_linux_irq(unsigned irq, void *dev_id)
00424 {
00425     unsigned long flags;
00426 
00427     if (irq >= RTAI_NR_IRQS || rtai_linux_irq[irq].count == 0) {
00428     return -EINVAL;
00429     }
00430 
00431     rtai_save_flags_and_cli(flags);
00432     free_irq(irq, dev_id);
00433 
00434     spin_lock(&irq_desc[irq].lock);
00435     if (--rtai_linux_irq[irq].count == 0 && irq_desc[irq].action) {
00436     irq_desc[irq].action->flags = rtai_linux_irq[irq].flags;
00437     }
00438     spin_unlock(&irq_desc[irq].lock);
00439 
00440     rtai_restore_flags(flags);
00441 
00442     return 0;
00443 }
00444 
00445 /**
00446  * Pend an IRQ to Linux.
00447  *
00448  * rt_pend_linux_irq appends a Linux interrupt irq for processing in Linux IRQ
00449  * mode, i.e. with hardware interrupts fully enabled.
00450  *
00451  * @note rt_pend_linux_irq does not perform any check on @a irq.
00452  */
00453 void
00454 rt_pend_linux_irq(unsigned irq)
00455 {
00456     unsigned long flags;
00457     rtai_save_flags_and_cli(flags);
00458     hal_pend_uncond(irq, rtai_cpuid());
00459     rtai_restore_flags(flags);
00460 }
00461 
00462 RTAI_SYSCALL_MODE void usr_rt_pend_linux_irq (unsigned irq)
00463 {
00464     unsigned long flags;
00465     rtai_save_flags_and_cli(flags);
00466     hal_pend_uncond(irq, rtai_cpuid());
00467     rtai_restore_flags(flags);
00468 }
00469 
00470 /**
00471  * Install a system request handler
00472  *
00473  * rt_request_srq installs a two way RTAI system request (srq) by assigning
00474  * @a u_handler, a function to be used when a user calls srq from user space,
00475  * and @a k_handler, the function to be called in kernel space following its
00476  * activation by a call to rt_pend_linux_srq(). @a k_handler is in practice
00477  * used to request a service from the kernel. In fact Linux system requests
00478  * cannot be used safely from RTAI so you can setup a handler that receives real
00479  * time requests and safely executes them when Linux is running.
00480  *
00481  * @param u_handler can be used to effectively enter kernel space without the
00482  * overhead and clumsiness of standard Unix/Linux protocols.   This is very
00483  * flexible service that allows you to personalize your use of  RTAI.
00484  *
00485  * @return the number of the assigned system request on success.
00486  * @retval EINVAL if @a k_handler is @c NULL.
00487  * @retval EBUSY if no free srq slot is available.
00488  */
00489 int
00490 rt_request_srq(unsigned label, void (*k_handler)(void), long long (*u_handler)(unsigned long))
00491 {
00492     unsigned long flags;
00493     int srq;
00494 
00495     if (k_handler == NULL)
00496     return -EINVAL;
00497 
00498     rtai_save_flags_and_cli(flags);
00499 
00500     if (rtai_sysreq_map != ~0) {
00501     srq = ffz(rtai_sysreq_map);
00502     set_bit(srq, &rtai_sysreq_map);
00503     rtai_sysreq_table[srq].k_handler = k_handler;
00504     rtai_sysreq_table[srq].u_handler = u_handler;
00505     rtai_sysreq_table[srq].label = label;
00506     } else
00507     srq = -EBUSY;
00508 
00509     rtai_restore_flags(flags);
00510 
00511     return srq;
00512 }
00513 
00514 /**
00515  * Uninstall a system request handler
00516  *
00517  * rt_free_srq uninstalls the specified system call @a srq, returned by
00518  * installing the related handler with a previous call to rt_request_srq().
00519  *
00520  * @retval EINVAL if @a srq is invalid.
00521  */
00522 int
00523 rt_free_srq(unsigned srq)
00524 {
00525     return (srq < 2 || srq >= RTAI_NR_SRQS || !test_and_clear_bit(srq, &rtai_sysreq_map))
00526     ? -EINVAL
00527     : 0;
00528 }
00529 
00530 /**
00531  * Append a Linux IRQ.
00532  *
00533  * rt_pend_linux_srq appends a system call request srq to be used as a service
00534  * request to the Linux kernel.
00535  *
00536  * @param srq is the value returned by rt_request_srq.
00537  *
00538  * @note rt_pend_linux_srq does not perform any check on irq.
00539  */
00540 void
00541 rt_pend_linux_srq(unsigned srq)
00542 {
00543     if (srq > 0 && srq < RTAI_NR_SRQS) {
00544         unsigned long flags;
00545     set_bit(srq, &rtai_sysreq_pending);
00546         rtai_save_flags_and_cli(flags);
00547         hal_pend_uncond(rtai_sysreq_virq, rtai_cpuid());
00548         rtai_restore_flags(flags);
00549     }
00550 }
00551 
00552 #ifdef CONFIG_RTAI_SCHED_ISR_LOCK
00553 static void (*rtai_isr_hook)(int cpuid);
00554 #define RTAI_SCHED_ISR_LOCK() \
00555     do { \
00556         if (!rt_scheduling[cpuid = rtai_cpuid()].locked++) { \
00557             rt_scheduling[cpuid].rqsted = 0; \
00558     } \
00559     } while (0)
00560 #define RTAI_SCHED_ISR_UNLOCK() \
00561     do { \
00562     if (rt_scheduling[cpuid].locked && !(--rt_scheduling[cpuid].locked)) { \
00563         if (rt_scheduling[cpuid].rqsted > 0 && rtai_isr_hook) { \
00564                 rtai_isr_hook(cpuid); \
00565         } \
00566     } \
00567     } while (0)
00568 #else  /* !CONFIG_RTAI_SCHED_ISR_LOCK */
00569 #define RTAI_SCHED_ISR_LOCK() \
00570     do { cpuid = rtai_cpuid(); } while (0)
00571 #define RTAI_SCHED_ISR_UNLOCK() \
00572     do {                       } while (0)
00573 #endif /* CONFIG_RTAI_SCHED_ISR_LOCK */
00574 
00575 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,31) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
00576 #define HAL_TICK_REGS hal_tick_regs[cpuid]
00577 #else
00578 #define HAL_TICK_REGS hal_tick_regs
00579 #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,31) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9) */
00580 
00581 #ifdef LOCKED_LINUX_IN_IRQ_HANDLER
00582 #define HAL_LOCK_LINUX()  do { sflags = rt_save_switch_to_real_time(cpuid); } while (0)
00583 #define HAL_UNLOCK_LINUX()  do { rtai_cli(); rt_restore_switch_to_linux(sflags, cpuid); } while (0)
00584 #else
00585 #define HAL_LOCK_LINUX()  do { sflags = xchg(ipipe_root_status[cpuid], (1 << IPIPE_STALL_FLAG)); } while (0)
00586 #define HAL_UNLOCK_LINUX()  do { rtai_cli(); *ipipe_root_status[cpuid] = sflags; } while (0)
00587 #endif /* LOCKED_LINUX_IN_IRQ_HANDLER */
00588 
00589 /* this can be a prototype for a handler pending something for Linux */
00590 int rtai_timer_handler(struct pt_regs *regs)
00591 {
00592         unsigned long cpuid=rtai_cpuid();
00593     unsigned long sflags;
00594 
00595         RTAI_SCHED_ISR_LOCK();
00596         HAL_LOCK_LINUX();
00597     rtai_realtime_irq[RTAI_TIMER_IRQ].irq_ack(RTAI_TIMER_IRQ);
00598     ((void (*)(void))rtai_realtime_irq[RTAI_TIMER_IRQ].handler)();
00599         HAL_UNLOCK_LINUX();
00600         RTAI_SCHED_ISR_UNLOCK();
00601 
00602         if (test_and_clear_bit(cpuid, &hal_pended) && !test_bit(IPIPE_STALL_FLAG, ipipe_root_status[cpuid])) {
00603                 rtai_sti();
00604                 hal_fast_flush_pipeline(cpuid);
00605                 return 1;
00606         }
00607         return 0;
00608 }
00609 
00610 /* rt_request_timer(): install a timer interrupt handler and set hardware-timer
00611  * to requested period. This is arch-specific (stopping/reprogramming/...
00612  * timer). Hence, the function is contained in mach-ARCH/ARCH-timer.c
00613  */
00614 
00615 /* rt_free_timer(): uninstall a timer handler previously set by
00616  * rt_request_timer() and reset hardware-timer to Linux HZ-tick.
00617  * This is arch-specific (stopping/reprogramming/... timer).
00618  * Hence, the function is contained in mach-ARCH/ARCH-timer.c
00619  */
00620 
00621 /*
00622  * rtai_hirq_dispatcher
00623  */
00624 
00625 static void rtai_hirq_dispatcher(int irq, struct pt_regs *regs)
00626 {
00627     unsigned long cpuid;
00628     if (rtai_realtime_irq[irq].handler) {
00629                 unsigned long sflags;
00630 
00631     RTAI_SCHED_ISR_LOCK();
00632                 HAL_LOCK_LINUX();
00633                 rtai_realtime_irq[irq].irq_ack(irq); mb();
00634     rtai_realtime_irq[irq].handler(irq, rtai_realtime_irq[irq].cookie);
00635                 HAL_UNLOCK_LINUX();
00636     RTAI_SCHED_ISR_UNLOCK();
00637                 if (rtai_realtime_irq[irq].retmode || !test_and_clear_bit(cpuid, &hal_pended) || test_bit(IPIPE_STALL_FLAG, ipipe_root_status[cpuid])) {
00638                         return;
00639     }
00640         } else {
00641                 unsigned long lflags;
00642 
00643                 lflags = xchg(ipipe_root_status[cpuid = rtai_cpuid()], (1 << IPIPE_STALL_FLAG));
00644                 rtai_realtime_irq[irq].irq_ack(irq); mb();
00645                 hal_pend_uncond(irq, cpuid);
00646                 *ipipe_root_status[cpuid] = lflags;
00647                 if (test_bit(IPIPE_STALL_FLAG, &lflags)) {
00648                         return;
00649     }
00650     }
00651         rtai_sti();
00652         hal_fast_flush_pipeline(cpuid);
00653         return;
00654 }
00655 
00656 RT_TRAP_HANDLER
00657 rt_set_trap_handler(RT_TRAP_HANDLER handler)
00658 {
00659     return (RT_TRAP_HANDLER)xchg(&rtai_trap_handler, handler);
00660 }
00661 
00662 static int rtai_trap_fault (unsigned event, void *evdata)
00663 {
00664     static const int trap2sig[] = {
00665         SIGSEGV,    // 0 - Data or instruction access exception
00666         SIGBUS,     // 1 - Alignment exception
00667         SIGFPE,     // 2 - Altivec unavailable
00668         SIGFPE,     // 3 - Program check exception
00669         SIGFPE,     // 4 - Machine check exception
00670         SIGFPE,     // 5 - Unknown exception
00671         SIGTRAP,    // 6 - Instruction breakpoint
00672         SIGFPE,     // 7 - Run mode exception
00673         SIGTRAP,    // 8 - Single-step exception
00674         SIGSEGV,    // 9 - Non-recoverable exception
00675         SIGILL,     // 10 - Software emulation
00676         SIGTRAP,    // 11 - Debug exception
00677         SIGSEGV,    // 12 - SPE exception
00678         SIGFPE,     // 13 - Altivec assist exception
00679         0,      // 14
00680         0, 0, 0, 0, 0,
00681         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00682         0, 0
00683     }; 
00684 
00685     TRACE_RTAI_TRAP_ENTRY(evdata->event, 0);
00686 
00687     if (!in_hrt_mode(rtai_cpuid())) {
00688     goto propagate;
00689     }
00690 
00691     /* We don't treat SIGILL as "FPU usage" as there is no FPU support in RTAI for ARM.
00692      * *FIXME* The whole FPU kernel emulation issue has to be sorted out (is it
00693      * reentrentant, do we need to save the emulated registers, can it be used
00694      * in kernel space, etc.). */
00695 
00696     // if a trap handler is set call it
00697     if (rtai_trap_handler && rtai_trap_handler(event, trap2sig[event], (struct pt_regs *)evdata, NULL)) {
00698     goto endtrap;
00699     }
00700 
00701 propagate:
00702     return 0;
00703 
00704 endtrap:
00705     TRACE_RTAI_TRAP_EXIT();
00706     return 1;
00707 }
00708 
00709 /*
00710  * rtai_lsrq_dispatcher
00711  */
00712 
00713 static void rtai_lsrq_dispatcher (unsigned virq)
00714 {
00715     unsigned long pending, srq;
00716 
00717     spin_lock(&rtai_lsrq_lock);
00718     while ((pending = rtai_sysreq_pending & ~rtai_sysreq_running)) {
00719         set_bit(srq = ffnz(pending), &rtai_sysreq_running);
00720     clear_bit(srq, &rtai_sysreq_pending);
00721         spin_unlock(&rtai_lsrq_lock);
00722 
00723         if (test_bit(srq, &rtai_sysreq_map)) {
00724         rtai_sysreq_table[srq].k_handler();
00725         }
00726 
00727     clear_bit(srq, &rtai_sysreq_running);
00728         spin_lock(&rtai_lsrq_lock);
00729     }
00730     spin_unlock(&rtai_lsrq_lock);
00731 }
00732 
00733 
00734 /*
00735  * rtai_usrq_dispatcher
00736  */
00737 
00738 static inline long long rtai_usrq_dispatcher (unsigned long srq, unsigned long label)
00739 {
00740     TRACE_RTAI_SRQ_ENTRY(srq);
00741 
00742     if (srq > 1 && srq < RTAI_NR_SRQS && test_bit(srq, &rtai_sysreq_map) && rtai_sysreq_table[srq].u_handler) {
00743         return rtai_sysreq_table[srq].u_handler(label);
00744     }
00745     else {
00746         for (srq = 2; srq < RTAI_NR_SRQS; srq++) {
00747             if (test_bit(srq, &rtai_sysreq_map) && rtai_sysreq_table[srq].label == label) {
00748                 return (long long)srq;
00749             }
00750         }
00751     }
00752 
00753     TRACE_RTAI_SRQ_EXIT();
00754 
00755     return 0LL;
00756 }
00757 
00758 long long (*rtai_lxrt_dispatcher)(unsigned long, unsigned long, void *);
00759 
00760 static int (*sched_intercept_syscall_prologue)(struct pt_regs *);
00761 
00762 static int intercept_syscall_prologue(unsigned long event, struct pt_regs *regs){
00763         if (likely(regs->ARM_r0 >= RTAI_SYSCALL_NR)) {
00764                 unsigned long srq  = regs->ARM_r1;
00765         unsigned long arg  = regs->ARM_r2;
00766 
00767                 IF_IS_A_USI_SRQ_CALL_IT(srq, arg, (long long *)regs->ARM_r5, regs->msr, 1);
00768                 *((long long *)regs->ARM_r3) = srq > RTAI_NR_SRQS ?  rtai_lxrt_dispatcher(srq, arg, regs) : rtai_usrq_dispatcher(srq, arg);
00769                 if (!in_hrt_mode(srq = rtai_cpuid())) {
00770                         hal_test_and_fast_flush_pipeline(srq);
00771                         return 0;
00772     }
00773                 return 1;
00774         }
00775         return likely(sched_intercept_syscall_prologue != NULL) ? sched_intercept_syscall_prologue(regs) : 0;
00776 }
00777 
00778 int rtai_syscall_dispatcher (struct pt_regs *regs)
00779 {
00780     unsigned long srq = regs->ARM_r0;
00781     unsigned long arg = regs->ARM_r1;
00782 
00783     IF_IS_A_USI_SRQ_CALL_IT(srq, regs->ARM_r2, (long long *)regs->ARM_r3, regs->msr, 1);
00784 
00785     *((long long*)&regs->ARM_r0) = srq > RTAI_NR_SRQS ?  rtai_lxrt_dispatcher(srq, arg, regs) : rtai_usrq_dispatcher(srq, arg);
00786         if (!in_hrt_mode(srq = rtai_cpuid())) {
00787                 hal_test_and_fast_flush_pipeline(srq);
00788                 return 1;
00789         }
00790         return 0;
00791 }
00792 
00793 static void rtai_domain_entry(int iflag)
00794 {
00795     if (iflag) {
00796         rt_printk(KERN_INFO "RTAI[hal]: <%s> mounted over %s %s.\n", PACKAGE_VERSION, HAL_TYPE, HAL_VERSION_STRING);
00797         rt_printk(KERN_INFO "RTAI[hal]: compiled with %s.\n", CONFIG_RTAI_COMPILER);
00798     }
00799     for (;;) hal_suspend_domain();
00800 }
00801 
00802 long rtai_catch_event (struct hal_domain_struct *from, unsigned long event, int (*handler)(unsigned long, void *))
00803 {
00804         if (event == HAL_SYSCALL_PROLOGUE) {
00805                 sched_intercept_syscall_prologue = (void *)handler;
00806                 return 0;
00807         }
00808     return (long)hal_catch_event(from, event, (void *)handler);
00809 }
00810 
00811 static void *saved_hal_irq_handler;
00812 extern void *hal_irq_handler;
00813 
00814 #ifdef CONFIG_PROC_FS
00815 
00816 static int
00817 rtai_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
00818 {
00819     PROC_PRINT_VARS;
00820     int i, none;
00821 
00822     PROC_PRINT("\n** RTAI/ARM %s over Adeos %s\n\n", RTAI_RELEASE, HAL_VERSION_STRING);
00823     PROC_PRINT("    TSC frequency: %d Hz\n", RTAI_TSC_FREQ);
00824     PROC_PRINT("    Timer frequency: %d Hz\n", RTAI_TIMER_FREQ);
00825     PROC_PRINT("    Timer latency: %d ns, %d TSC ticks\n", RTAI_TIMER_LATENCY,
00826     rtai_imuldiv(RTAI_TIMER_LATENCY, RTAI_TSC_FREQ, 1000000000));
00827     PROC_PRINT("    Timer setup: %d ns\n", RTAI_TIMER_SETUP_TIME);
00828     PROC_PRINT("    Timer setup: %d TSC ticks, %d IRQ-timer ticks\n",
00829     rtai_imuldiv(RTAI_TIMER_SETUP_TIME, RTAI_TSC_FREQ, 1000000000),
00830     rtai_imuldiv(RTAI_TIMER_SETUP_TIME, RTAI_TIMER_FREQ, 1000000000));
00831 
00832     none = 1;
00833 
00834     PROC_PRINT("\n** Real-time IRQs used by RTAI: ");
00835 
00836     for (i = 0; i < NR_IRQS; i++) {
00837     if (rtai_realtime_irq[i].handler) {
00838         if (none) {
00839         PROC_PRINT("\n");
00840         none = 0;
00841         }
00842         PROC_PRINT("\n    #%d at %p", i, rtai_realtime_irq[i].handler);
00843     }
00844     }
00845 
00846     if (none)
00847     PROC_PRINT("none");
00848 
00849     PROC_PRINT("\n\n");
00850 
00851     PROC_PRINT("** RTAI extension traps: \n\n");
00852     PROC_PRINT("    SYSREQ=0x%x\n", RTAI_SYS_VECTOR);
00853 #if 0
00854     PROC_PRINT("       SHM=0x%x\n", RTAI_SHM_VECTOR);
00855 #endif
00856     PROC_PRINT("\n");
00857 
00858     none = 1;
00859     PROC_PRINT("** RTAI SYSREQs in use: ");
00860 
00861     for (i = 0; i < RTAI_NR_SRQS; i++) {
00862     if (rtai_sysreq_table[i].k_handler || rtai_sysreq_table[i].u_handler) {
00863         PROC_PRINT("#%d ", i);
00864         none = 0;
00865     }
00866     }
00867 
00868     if (none)
00869     PROC_PRINT("none");
00870 
00871     PROC_PRINT("\n\n");
00872 
00873     PROC_PRINT_DONE;
00874 }
00875 
00876 static int
00877 rtai_proc_register(void)
00878 {
00879     struct proc_dir_entry *ent;
00880 
00881     rtai_proc_root = create_proc_entry("rtai", S_IFDIR, 0);
00882 
00883     if (!rtai_proc_root) {
00884     printk(KERN_ERR "RTAI[hal]: Unable to initialize /proc/rtai.\n");
00885     return -1;
00886     }
00887 
00888     rtai_proc_root->owner = THIS_MODULE;
00889 
00890     ent = create_proc_entry("rtai", S_IFREG|S_IRUGO|S_IWUSR, rtai_proc_root);
00891 
00892     if (!ent) {
00893     printk(KERN_ERR "RTAI[hal]: Unable to initialize /proc/rtai/rtai.\n");
00894     return -1;
00895     }
00896 
00897     ent->read_proc = rtai_read_proc;
00898 
00899     return 0;
00900 }
00901 
00902 static void
00903 rtai_proc_unregister(void)
00904 {
00905     remove_proc_entry("rtai", rtai_proc_root);
00906     remove_proc_entry("rtai", 0);
00907 }
00908 
00909 #endif /* CONFIG_PROC_FS */
00910 
00911 
00912 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
00913 static inline void *hal_set_irq_handler(void *hirq_dispatcher)
00914 {
00915     if (saved_hal_irq_handler != hirq_dispatcher) {
00916         saved_hal_irq_handler = hal_irq_handler;
00917         hal_irq_handler = hirq_dispatcher;
00918         return saved_hal_irq_handler;
00919     }
00920     hal_irq_handler = hirq_dispatcher;
00921     return rtai_hirq_dispatcher;
00922 }
00923 #endif
00924 
00925 void (*rt_set_ihook (void (*hookfn)(int)))(int)
00926 {
00927 #ifdef CONFIG_RTAI_SCHED_ISR_LOCK
00928     return (void (*)(int))xchg(&rtai_isr_hook, hookfn); /* This is atomic */
00929 #else  /* !CONFIG_RTAI_SCHED_ISR_LOCK */
00930     return NULL;
00931 #endif /* CONFIG_RTAI_SCHED_ISR_LOCK */
00932 }
00933 
00934 void rtai_set_linux_task_priority (struct task_struct *task, int policy, int prio)
00935 {
00936     hal_set_linux_task_priority(task, policy, prio);
00937     if (task->rt_priority != prio || task->policy != policy) {
00938         printk("RTAI[hal]: sched_setscheduler(policy = %d, prio = %d) failed, (%s -- pid = %d)\n", policy, prio, task->comm, task->pid);
00939     }
00940 }
00941 
00942 /*
00943  * rtai_install_archdep
00944  */
00945 
00946 static void rtai_install_archdep (void)
00947 {
00948     struct hal_sysinfo_struct sysinfo;
00949 
00950 #if !defined(USE_LINUX_SYSCALL) && !defined(CONFIG_RTAI_LXRT_USE_LINUX_SYSCALL) 
00951     /* empty till a direct RTAI syscall way is decided */
00952 #endif
00953 
00954     hal_catch_event(hal_root_domain, HAL_SYSCALL_PROLOGUE, (void *)intercept_syscall_prologue);
00955 
00956     hal_get_sysinfo(&sysinfo);
00957 
00958     rtai_cpufreq_arg = (unsigned long)sysinfo.cpufreq;
00959 
00960     rtai_tunables.cpu_freq = rtai_cpufreq_arg;
00961 }
00962 
00963 /*
00964  * rtai_uninstall_archdep
00965  */
00966 
00967 static void rtai_uninstall_archdep (void)
00968 {
00969 /* something to be added when a direct RTAI syscall way is decided */
00970     hal_catch_event(hal_root_domain, HAL_SYSCALL_PROLOGUE, NULL);
00971     rtai_archdep_exit();
00972 }
00973 
00974 #define RT_PRINTK_SRQ  1
00975 
00976 static void *saved_hal_irq_handler;
00977 extern void *hal_irq_handler;
00978 
00979 int
00980 __rtai_hal_init(void)
00981 {
00982     int trapnr, halinv;
00983     struct hal_attr_struct attr;
00984 
00985     // check event handler registration, check for any already installed
00986     for (halinv = trapnr = 0; trapnr < HAL_NR_EVENTS; trapnr++) {
00987         if (hal_root_domain->hal_event_handler_fun(trapnr)) {
00988             halinv = 1;
00989             printk("EVENT %d INVALID\n", trapnr);
00990         }
00991     }
00992     if (halinv) {
00993         printk(KERN_ERR "RTAI[hal]: HAL IMMEDIATE EVENT DISPATCHING BROKEN\n");
00994         return -1;
00995     }
00996 
00997     // request a virtual interrupt for RTAI sysrqs
00998     if (!(rtai_sysreq_virq = hal_alloc_irq())) {
00999     printk(KERN_ERR "RTAI[hal]: no virtual interrupt available.\n");
01000         return -1;
01001     }
01002 
01003     // copy HAL proper pointers locally for a more effective use
01004     for (trapnr = 0; trapnr < RTAI_NR_IRQS; trapnr++) {
01005         rtai_realtime_irq[trapnr].irq_ack = hal_root_domain->irqs[trapnr].acknowledge;
01006     }
01007     for (trapnr = 0; trapnr < RTAI_NR_CPUS; trapnr++) {
01008         ipipe_root_status[trapnr] = &hal_root_domain->cpudata[trapnr].status;
01009     }
01010 
01011     // assign the RTAI sysrqs handler
01012     hal_virtualize_irq(hal_root_domain, rtai_sysreq_virq, &rtai_lsrq_dispatcher, NULL, IPIPE_HANDLE_MASK);
01013     saved_hal_irq_handler = hal_irq_handler;
01014     hal_irq_handler = rtai_hirq_dispatcher;
01015 
01016     // architecture dependent RTAI installation
01017     rtai_install_archdep();
01018 
01019 #ifdef CONFIG_PROC_FS
01020     rtai_proc_register();
01021 #endif /* CONFIG_PROC_FS */
01022 
01023     // register RTAI domain
01024     hal_init_attr(&attr);
01025     attr.name = "RTAI";
01026     attr.domid = RTAI_DOMAIN_ID;
01027     attr.entry    = (void *)rtai_domain_entry;
01028     attr.priority = get_domain_pointer(1)->priority + 100;
01029     hal_register_domain(&rtai_domain, &attr);
01030 
01031     // register trap handler for all FAULTS in the root domain
01032     for (trapnr = 0; trapnr < HAL_NR_FAULTS; trapnr++) {
01033         hal_catch_event(hal_root_domain, trapnr, (void *)rtai_trap_fault);
01034     }
01035 
01036     // log RTAI mounted
01037     printk(KERN_INFO "RTAI[hal]: mounted (%s, IMMEDIATE (INTERNAL IRQs %s).\n", HAL_TYPE, CONFIG_RTAI_DONT_DISPATCH_CORE_IRQS ? "VECTORED" : "DISPATCHED");
01038 
01039     // log PIPELINE layers
01040     printk("PIPELINE layers:\n");
01041     for (trapnr = 1; ; trapnr++) {
01042         struct hal_domain_struct *next_domain;
01043         next_domain = get_domain_pointer(trapnr);
01044         if ((unsigned long)next_domain < 10) break;
01045         printk("%p %x %s %d\n", next_domain, next_domain->domid, next_domain->name, next_domain->priority);
01046     }
01047 
01048 #ifdef CONFIG_RTAI_DIAG_TSC_SYNC
01049     init_tsc_sync();
01050 #endif
01051 
01052     return 0;
01053 }
01054 
01055 void
01056 __rtai_hal_exit(void)
01057 {
01058     int trapnr;
01059 #ifdef CONFIG_PROC_FS
01060     rtai_proc_unregister();
01061 #endif
01062 
01063     hal_irq_handler = saved_hal_irq_handler;
01064     hal_unregister_domain(&rtai_domain);
01065     for (trapnr = 0; trapnr < HAL_NR_FAULTS; trapnr++) {
01066         hal_catch_event(hal_root_domain, trapnr, NULL);
01067     }
01068     hal_virtualize_irq(hal_root_domain, rtai_sysreq_virq, NULL, NULL, 0);
01069     hal_free_irq(rtai_sysreq_virq);
01070 
01071     rtai_uninstall_archdep();
01072 
01073 #ifdef CONFIG_RTAI_DIAG_TSC_SYNC
01074     cleanup_tsc_sync();
01075 #endif
01076 
01077     printk(KERN_INFO "RTAI[hal]: unmounted.\n");
01078 }
01079 
01080 module_init(__rtai_hal_init);
01081 module_exit(__rtai_hal_exit);
01082 
01083 /*
01084  * rt_printk
01085  */
01086 
01087 asmlinkage int rt_printk(const char *fmt, ...)
01088 {
01089     va_list args;
01090     int r;
01091 
01092     va_start(args, fmt);
01093         r = vprintk(fmt, args);
01094     va_end(args);
01095 
01096     return r;
01097 }
01098 
01099 /*
01100  * rt_sync_printk
01101  */
01102 
01103 asmlinkage int rt_sync_printk(const char *fmt, ...)
01104 {
01105     va_list args;
01106     int r;
01107 
01108     va_start(args, fmt);
01109         hal_set_printk_sync(&rtai_domain);
01110             r = vprintk(fmt, args);
01111         hal_set_printk_async(&rtai_domain);
01112     va_end(args);
01113 
01114     return r;
01115 }
01116 
01117 EXPORT_SYMBOL(rtai_realtime_irq);
01118 EXPORT_SYMBOL(rt_request_irq);
01119 EXPORT_SYMBOL(rt_release_irq);
01120 EXPORT_SYMBOL(rt_set_irq_cookie);
01121 EXPORT_SYMBOL(rt_startup_irq);
01122 EXPORT_SYMBOL(rt_shutdown_irq);
01123 EXPORT_SYMBOL(rt_enable_irq);
01124 EXPORT_SYMBOL(rt_disable_irq);
01125 EXPORT_SYMBOL(rt_mask_and_ack_irq);
01126 EXPORT_SYMBOL(rt_unmask_irq);
01127 EXPORT_SYMBOL(rt_ack_irq);
01128 EXPORT_SYMBOL(rt_request_linux_irq);
01129 EXPORT_SYMBOL(rt_free_linux_irq);
01130 EXPORT_SYMBOL(rt_pend_linux_irq);
01131 EXPORT_SYMBOL(usr_rt_pend_linux_irq);
01132 EXPORT_SYMBOL(rt_set_irq_ack);
01133 
01134 EXPORT_SYMBOL(rt_request_srq);
01135 EXPORT_SYMBOL(rt_free_srq);
01136 EXPORT_SYMBOL(rt_pend_linux_srq);
01137 EXPORT_SYMBOL(rt_assign_irq_to_cpu);
01138 
01139 EXPORT_SYMBOL(rt_reset_irq_to_sym_mode);
01140 EXPORT_SYMBOL(rt_request_timer);
01141 EXPORT_SYMBOL(rt_free_timer);
01142 EXPORT_SYMBOL(rt_request_rtc);
01143 EXPORT_SYMBOL(rt_release_rtc);
01144 
01145 extern int rtai_calibrate_TC (void);
01146 EXPORT_SYMBOL(rtai_calibrate_TC);
01147 
01148 EXPORT_SYMBOL(rt_set_trap_handler);
01149 
01150 EXPORT_SYMBOL(rt_set_ihook);
01151 
01152 EXPORT_SYMBOL(rtai_critical_enter);
01153 EXPORT_SYMBOL(rtai_critical_exit);
01154 EXPORT_SYMBOL(rtai_set_linux_task_priority);
01155 EXPORT_SYMBOL(rtai_linux_context);
01156 EXPORT_SYMBOL(rtai_domain);
01157 EXPORT_SYMBOL(rtai_proc_root);
01158 EXPORT_SYMBOL(rtai_tunables);
01159 EXPORT_SYMBOL(rtai_cpu_lock);
01160 EXPORT_SYMBOL(rtai_cpu_realtime);
01161 EXPORT_SYMBOL(rt_times);
01162 EXPORT_SYMBOL(rt_smp_times);
01163 
01164 EXPORT_SYMBOL(rt_printk);
01165 EXPORT_SYMBOL(rt_sync_printk);
01166 
01167 EXPORT_SYMBOL(rtai_catch_event);
01168 
01169 EXPORT_SYMBOL(rtai_lxrt_dispatcher);
01170 EXPORT_SYMBOL(rt_scheduling);
01171 EXPORT_SYMBOL(hal_pended);
01172 EXPORT_SYMBOL(ipipe_root_status);

Generated on Tue Feb 2 17:46:04 2010 for RTAI API by  doxygen 1.4.7