base/include/asm/rtai_lxrt.h

Go to the documentation of this file.
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 #ifdef CONFIG_RTAI_LXRT_USE_LINUX_SYSCALL 00029 #define USE_LINUX_SYSCALL 00030 #else 00031 #undef USE_LINUX_SYSCALL 00032 #endif 00033 00034 #define RTAI_SYSCALL_NR 0x70000000 00035 #define RTAI_SYSCALL_CODE ebx 00036 #define RTAI_SYSCALL_ARGS ecx 00037 #define RTAI_SYSCALL_RETPNT edx 00038 00039 #define RTAI_FAKE_LINUX_SYSCALL 20 00040 00041 #define SKIP_IMMEDIATE_LINUX_SYSCALL() 00042 00043 #define LINUX_SYSCALL_NR orig_eax 00044 #define LINUX_SYSCALL_REG1 ebx 00045 #define LINUX_SYSCALL_REG2 ecx 00046 #define LINUX_SYSCALL_REG3 edx 00047 #define LINUX_SYSCALL_REG4 esi 00048 #define LINUX_SYSCALL_REG5 edi 00049 #define LINUX_SYSCALL_REG6 ebp 00050 #define LINUX_SYSCALL_RETREG eax 00051 00052 #define SET_LXRT_RETVAL_IN_SYSCALL(regs, retval) \ 00053 do { \ 00054 if (regs->RTAI_SYSCALL_RETPNT) { \ 00055 rt_copy_to_user((void *)regs->RTAI_SYSCALL_RETPNT, &retval, sizeof(retval)); \ 00056 } \ 00057 } while (0) 00058 00059 #define LOW 0 00060 #define HIGH 1 00061 00062 #if defined(CONFIG_RTAI_RTC_FREQ) && CONFIG_RTAI_RTC_FREQ >= 2 00063 00064 #define TIMER_NAME "RTC" 00065 #define TIMER_FREQ CONFIG_RTAI_RTC_FREQ 00066 #define TIMER_LATENCY 0 00067 #define TIMER_SETUP_TIME 0 00068 #define ONESHOT_SPAN 0 00069 00070 #else /* CONFIG_RTAI_RTC_FREQ == 0 */ 00071 00072 #ifdef CONFIG_X86_LOCAL_APIC 00073 00074 #define TIMER_NAME "APIC" 00075 #define FAST_TO_READ_TSC 00076 #define TIMER_FREQ RTAI_FREQ_APIC 00077 #define TIMER_LATENCY RTAI_LATENCY_APIC 00078 #define TIMER_SETUP_TIME RTAI_SETUP_TIME_APIC 00079 #define ONESHOT_SPAN (CPU_FREQ/(CONFIG_RTAI_CAL_FREQS_FACT + 2)) //(0x7FFFFFFFLL*(CPU_FREQ/TIMER_FREQ)) 00080 #define update_linux_timer(cpuid) 00081 00082 #else /* !CONFIG_X86_LOCAL_APIC */ 00083 00084 #define USE_LINUX_TIMER 00085 #define TIMER_NAME "8254-PIT" 00086 #define TIMER_FREQ RTAI_FREQ_8254 00087 #define TIMER_LATENCY RTAI_LATENCY_8254 00088 #define TIMER_SETUP_TIME RTAI_SETUP_TIME_8254 00089 #define ONESHOT_SPAN ((0x7FFF*(CPU_FREQ/TIMER_FREQ))/(CONFIG_RTAI_CAL_FREQS_FACT + 1)) //(0x7FFF*(CPU_FREQ/TIMER_FREQ)) 00090 #define update_linux_timer(cpuid) \ 00091 do { \ 00092 if (!IS_FUSION_TIMER_RUNNING()) { \ 00093 hal_pend_uncond(TIMER_8254_IRQ, cpuid); \ 00094 } \ 00095 } while (0) 00096 00097 #endif /* CONFIG_X86_LOCAL_APIC */ 00098 00099 #endif /* CONFIG_RTAI_RTC_FREQ != 0 */ 00100 00101 union rtai_lxrt_t { 00102 RTIME rt; 00103 int i[2]; 00104 void *v[2]; 00105 }; 00106 00107 #ifdef __cplusplus 00108 extern "C" { 00109 #endif /* __cplusplus */ 00110 00111 #ifdef __KERNEL__ 00112 00113 #include <asm/segment.h> 00114 #include <asm/mmu_context.h> 00115 00116 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) 00117 #define __LXRT_GET_DATASEG(reg) "movl $" STR(__KERNEL_DS) ",%" #reg "\n\t" 00118 #else /* KERNEL_VERSION >= 2.6.0 */ 00119 #define __LXRT_GET_DATASEG(reg) "movl $" STR(__USER_DS) ",%" #reg "\n\t" 00120 #endif /* KERNEL_VERSION < 2.6.0 */ 00121 00122 static inline void _lxrt_context_switch (struct task_struct *prev, struct task_struct *next, int cpuid) 00123 { 00124 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) 00125 extern void context_switch(void *, void *); 00126 struct mm_struct *oldmm = prev->active_mm; 00127 switch_mm(oldmm, next->active_mm, next, cpuid); 00128 if (!next->mm) enter_lazy_tlb(oldmm, next, cpuid); 00129 context_switch(prev, next); // was switch_to(prev, next, prev); 00130 #else /* >= 2.6.0 */ 00131 extern void context_switch(void *, void *, void *); 00132 context_switch(0, prev, next); 00133 #endif /* < 2.6.0 */ 00134 } 00135 00136 #if 0 00137 #define IN_INTERCEPT_IRQ_ENABLE() do { rtai_hw_sti(); } while (0) 00138 #define IN_INTERCEPT_IRQ_DISABLE() do { rtai_hw_cli(); } while (0) 00139 #else 00140 #define IN_INTERCEPT_IRQ_ENABLE() do { } while (0) 00141 #define IN_INTERCEPT_IRQ_DISABLE() do { } while (0) 00142 #endif 00143 00144 #include <linux/slab.h> 00145 00146 #if 1 // optimised (?) 00147 static inline void kthread_fun_set_jump(struct task_struct *lnxtsk) 00148 { 00149 lnxtsk->rtai_tskext(TSKEXT2) = kmalloc(sizeof(struct thread_struct)/* + sizeof(struct thread_info)*/ + (lnxtsk->thread.esp & ~(THREAD_SIZE - 1)) + THREAD_SIZE - lnxtsk->thread.esp, GFP_KERNEL); 00150 *((struct thread_struct *)lnxtsk->rtai_tskext(TSKEXT2)) = lnxtsk->thread; 00151 // memcpy(lnxtsk->rtai_tskext(TSKEXT2) + sizeof(struct thread_struct), (void *)(lnxtsk->thread.esp & ~(THREAD_SIZE - 1)), sizeof(struct thread_info)); 00152 memcpy(lnxtsk->rtai_tskext(TSKEXT2) + sizeof(struct thread_struct)/* + sizeof(struct thread_info)*/, (void *)(lnxtsk->thread.esp), (lnxtsk->thread.esp & ~(THREAD_SIZE - 1)) + THREAD_SIZE - lnxtsk->thread.esp); 00153 } 00154 00155 static inline void kthread_fun_long_jump(struct task_struct *lnxtsk) 00156 { 00157 lnxtsk->thread = *((struct thread_struct *)lnxtsk->rtai_tskext(TSKEXT2)); 00158 // memcpy((void *)(lnxtsk->thread.esp & ~(THREAD_SIZE - 1)), lnxtsk->rtai_tskext(TSKEXT2) + sizeof(struct thread_struct), sizeof(struct thread_info)); 00159 memcpy((void *)lnxtsk->thread.esp, lnxtsk->rtai_tskext(TSKEXT2) + sizeof(struct thread_struct)/* + sizeof(struct thread_info)*/, (lnxtsk->thread.esp & ~(THREAD_SIZE - 1)) + THREAD_SIZE - lnxtsk->thread.esp); 00160 } 00161 #else // brute force 00162 static inline void kthread_fun_set_jump(struct task_struct *lnxtsk) 00163 { 00164 lnxtsk->rtai_tskext(TSKEXT2) = kmalloc(sizeof(struct thread_struct) + THREAD_SIZE, GFP_KERNEL); 00165 *((struct thread_struct *)lnxtsk->rtai_tskext(TSKEXT2)) = lnxtsk->thread; 00166 memcpy(lnxtsk->rtai_tskext(TSKEXT2) + sizeof(struct thread_struct), (void *)(lnxtsk->thread.esp & ~(THREAD_SIZE - 1)), THREAD_SIZE); 00167 } 00168 00169 static inline void kthread_fun_long_jump(struct task_struct *lnxtsk) 00170 { 00171 lnxtsk->thread = *((struct thread_struct *)lnxtsk->rtai_tskext(TSKEXT2)); 00172 memcpy((void *)(lnxtsk->thread.esp & ~(THREAD_SIZE - 1)), lnxtsk->rtai_tskext(TSKEXT2) + sizeof(struct thread_struct), THREAD_SIZE); 00173 } 00174 #endif 00175 00176 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) 00177 #define rt_copy_from_user __copy_from_user 00178 #define rt_copy_to_user __copy_to_user 00179 #else 00180 #define rt_copy_from_user __copy_from_user_inatomic 00181 #define rt_copy_to_user __copy_to_user_inatomic 00182 #endif 00183 #define rt_put_user __put_user 00184 00185 #else /* !__KERNEL__ */ 00186 00187 /* NOTE: Keep the following routines unfold: this is a compiler 00188 compatibility issue. */ 00189 00190 #include <sys/syscall.h> 00191 #include <unistd.h> 00192 00193 static union rtai_lxrt_t _rtai_lxrt(int srq, void *arg) 00194 { 00195 union rtai_lxrt_t retval; 00196 #ifdef USE_LINUX_SYSCALL 00197 syscall(RTAI_SYSCALL_NR, srq, arg, &retval); 00198 #else 00199 RTAI_DO_TRAP(RTAI_SYS_VECTOR, retval, srq, arg); 00200 #endif 00201 return retval; 00202 } 00203 00204 static inline union rtai_lxrt_t rtai_lxrt(short int dynx, short int lsize, int srq, void *arg) 00205 { 00206 return _rtai_lxrt(ENCODE_LXRT_REQ(dynx, srq, lsize), arg); 00207 } 00208 00209 #define rtai_iopl() do { extern int iopl(int); iopl(3); } while (0) 00210 00211 #endif /* __KERNEL__ */ 00212 00213 #ifdef __cplusplus 00214 } 00215 #endif /* __cplusplus */ 00216 00217 #endif /* !_RTAI_ASM_I386_LXRT_H */

Generated on Thu Nov 20 11:49:48 2008 for RTAI API by doxygen 1.3.8