rtai_lxrt.h

00001 /*
00002  * Copyright (C) 1999-2003 Paolo Mantegazza <mantegazza@aero.polimi.it>
00003  * extensions for user space modules are jointly copyrighted (2000) with:
00004  *              Pierre Cloutier <pcloutier@poseidoncontrols.com>,
00005  *              Steve Papacharalambous <stevep@zentropix.com>.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
00019  */
00020 
00021 #ifndef _RTAI_ASM_I386_LXRT_H
00022 #define _RTAI_ASM_I386_LXRT_H
00023 
00024 #include <linux/version.h>
00025 
00026 #include <asm/rtai_vectors.h>
00027 
00028 //#define USE_LINUX_SYSCALL
00029 
00030 #define SYSCALL_NR      orig_eax
00031 #define SYSCALL_ARGS    ecx
00032 #define SYSCALL_RETPNT  edx
00033 
00034 #define SET_LXRT_RETVAL_IN_SYSCALL(retval) \
00035         do { \
00036                 if (r->SYSCALL_RETPNT) { \
00037                         copy_to_user((void *)r->SYSCALL_RETPNT, &retval, sizeof(retval)); \
00038                 } \
00039         } while (0)
00040 
00041 #define LOW  0
00042 #define HIGH 1
00043 
00044 #ifdef CONFIG_X86_LOCAL_APIC
00045 
00046 #define TIMER_NAME "APIC"
00047 #define FAST_TO_READ_TSC
00048 #define TIMER_FREQ RTAI_FREQ_APIC
00049 #define TIMER_LATENCY RTAI_LATENCY_APIC
00050 #define TIMER_SETUP_TIME RTAI_SETUP_TIME_APIC
00051 #define ONESHOT_SPAN (0x7FFFFFFFLL*(CPU_FREQ/TIMER_FREQ))
00052 #define update_linux_timer(cpuid)
00053 
00054 #else /* !CONFIG_X86_LOCAL_APIC */
00055 
00056 #define USE_LINUX_TIMER
00057 #define TIMER_NAME "8254-PIT"
00058 #define TIMER_FREQ RTAI_FREQ_8254
00059 #define TIMER_LATENCY RTAI_LATENCY_8254
00060 #define TIMER_SETUP_TIME RTAI_SETUP_TIME_8254
00061 #define ONESHOT_SPAN (0x7FFF*(CPU_FREQ/TIMER_FREQ))
00062 #define update_linux_timer(cpuid) adeos_pend_uncond(TIMER_8254_IRQ, cpuid)
00063 
00064 #endif /* CONFIG_X86_LOCAL_APIC */
00065 
00066 union rtai_lxrt_t {
00067 
00068     RTIME rt;
00069     int i[2];
00070     void *v[2];
00071 };
00072 
00073 #ifdef __cplusplus
00074 extern "C" {
00075 #endif /* __cplusplus */
00076 
00077 #ifdef __KERNEL__
00078 
00079 #include <asm/segment.h>
00080 #include <asm/mmu_context.h>
00081 
00082 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
00083 #define __LXRT_GET_DATASEG(reg) "movl $" STR(__KERNEL_DS) ",%" #reg "\n\t"
00084 #else /* KERNEL_VERSION >= 2.6.0 */
00085 #define __LXRT_GET_DATASEG(reg) "movl $" STR(__USER_DS) ",%" #reg "\n\t"
00086 #endif  /* KERNEL_VERSION < 2.6.0 */
00087 
00088 static inline void _lxrt_context_switch (struct task_struct *prev,
00089                                          struct task_struct *next,
00090                                          int cpuid)
00091 {
00092     struct mm_struct *oldmm = prev->active_mm;
00093 
00094 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
00095     switch_mm(oldmm,next->active_mm,next,cpuid);
00096 
00097     if (!next->mm)
00098         enter_lazy_tlb(oldmm,next,cpuid);
00099 #else /* >= 2.6.0 */
00100     switch_mm(oldmm,next->active_mm,next);
00101 
00102     if (!next->mm) enter_lazy_tlb(oldmm,next);
00103 #endif /* < 2.6.0 */
00104 
00105 /* NOTE: Do not use switch_to() directly: this is a compiler
00106    compatibility issue. */
00107 
00108 /* It might be so but, with 2.6.xx at least, only for the inlined case. 
00109    Compiler compatibility issues related to inlines can appear anywhere.
00110    This case seems to be solved by staticalising without inlining, see LXRT.
00111    So let's experiment a bit more, simple Linux reuse is better (Paolo) */
00112 
00113 #if 1
00114     switch_to(prev, next, prev);
00115 #else
00116     __asm__ __volatile__(                                               \
00117                  "pushfl\n\t"                                           \
00118                  "cli\n\t"                                              \
00119                  "pushl %%esi\n\t"                                      \
00120                  "pushl %%edi\n\t"                                      \
00121                  "pushl %%ebp\n\t"                                      \
00122                  "movl %%esp,%0\n\t"    /* save ESP */                  \
00123                  "movl %3,%%esp\n\t"    /* restore ESP */               \
00124                  "movl $1f,%1\n\t"      /* save EIP */                  \
00125                  "pushl %4\n\t"         /* restore EIP */               \
00126                  "jmp "SYMBOL_NAME_STR(__switch_to)"\n"                 \
00127                  "1:\t"                                                 \
00128                  "popl %%ebp\n\t"                                       \
00129                  "popl %%edi\n\t"                                       \
00130                  "popl %%esi\n\t"                                       \
00131                  "popfl\n\t"                                            \
00132                  :"=m" (prev->thread.esp),"=m" (prev->thread.eip),      \
00133                   "=b" (prev)                                           \
00134                  :"m" (next->thread.esp),"m" (next->thread.eip),        \
00135                   "a" (prev), "d" (next),                               \
00136                   "b" (prev));                                          
00137 #endif
00138     barrier();
00139 }
00140 
00141 #if 0
00142 #define IN_INTERCEPT_IRQ_ENABLE()   do { rtai_hw_sti(); } while (0)
00143 #define IN_INTERCEPT_IRQ_DISABLE()  do { rtai_hw_cli(); } while (0)
00144 #else
00145 #define IN_INTERCEPT_IRQ_ENABLE()   do { } while (0)
00146 #define IN_INTERCEPT_IRQ_DISABLE()  do { } while (0)
00147 #endif
00148 
00149 #else /* !__KERNEL__ */
00150 
00151 /* NOTE: Keep the following routines unfold: this is a compiler
00152    compatibility issue. */
00153 
00154 static union rtai_lxrt_t _rtai_lxrt(int srq, void *arg)
00155 {
00156         union rtai_lxrt_t retval;
00157 #ifdef USE_LINUX_SYSCALL
00158         RTAI_DO_TRAP(SYSCALL_VECTOR, retval, srq, arg);
00159 #else
00160         RTAI_DO_TRAP(RTAI_SYS_VECTOR, retval, srq, arg);
00161 #endif
00162         return retval;
00163 }
00164 
00165 static inline union rtai_lxrt_t rtai_lxrt(short int dynx, short int lsize, int srq, void *arg)
00166 {
00167         return _rtai_lxrt(ENCODE_LXRT_REQ(dynx, srq, lsize), arg);
00168 }
00169 
00170 #endif /* __KERNEL__ */
00171 
00172 #ifdef __cplusplus
00173 }
00174 #endif /* __cplusplus */
00175 
00176 #endif /* !_RTAI_ASM_I386_LXRT_H */

Generated on Tue Jan 18 22:53:52 2005 for RTAI API by  doxygen 1.3.9.1