00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _RTAI_ASM_I386_LXRT_H
00022 #define _RTAI_ASM_I386_LXRT_H
00023
00024 #include <asm/rtai_vectors.h>
00025
00026 #define LOW 0
00027 #define HIGH 1
00028
00029 union rtai_lxrt_t {
00030
00031 RTIME rt;
00032 int i[2];
00033 void *v[2];
00034 };
00035
00036 #ifdef __cplusplus
00037 extern "C" {
00038 #endif
00039
00040 #ifdef __KERNEL__
00041
00042 #include <asm/segment.h>
00043 #include <asm/mmu_context.h>
00044
00045 #define RTAI_LXRT_HANDLER rtai_lxrt_handler
00046
00047 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
00048 #define __LXRT_GET_DATASEG(reg) "movl $" STR(__KERNEL_DS) ",%" #reg "\n\t"
00049 #else
00050 #define __LXRT_GET_DATASEG(reg) "movl $" STR(__USER_DS) ",%" #reg "\n\t"
00051 #endif
00052
00053 #define DEFINE_LXRT_HANDLER() \
00054 asmlinkage long long rtai_lxrt_invoke(unsigned int lxsrq, void *arg); \
00055 asmlinkage int rtai_lxrt_fastpath(void); \
00056 asmlinkage void RTAI_LXRT_HANDLER(void); \
00057 __asm__( \
00058 "\n" __ALIGN_STR"\n\t" \
00059 SYMBOL_NAME_STR(rtai_lxrt_handler) ":\n\t" \
00060 "cld\n\t" \
00061 "pushl $0\n\t" \
00062 "pushl %es\n\t" \
00063 "pushl %ds\n\t" \
00064 "pushl %eax\n\t" \
00065 "pushl %ebp\n\t" \
00066 "pushl %edi\n\t" \
00067 "pushl %esi\n\t" \
00068 "pushl %edx\n\t" \
00069 "pushl %ecx\n\t" \
00070 "pushl %ebx\n\t" \
00071 __LXRT_GET_DATASEG(ebx) \
00072 "movl %ebx,%ds\t\n" \
00073 "movl %ebx,%es\t\n" \
00074 "pushl %edx\n\t" \
00075 "pushl %eax\n\t" \
00076 "call "SYMBOL_NAME_STR(rtai_lxrt_invoke)"\n\t" \
00077 "addl $8,%esp;\n\t" \
00078 "movl %edx,8(%esp);\n\t" \
00079 "movl %eax,24(%esp);\n\t" \
00080 "call "SYMBOL_NAME_STR(rtai_lxrt_fastpath)"\n\t" \
00081 "testl %eax,%eax;\n\t" \
00082 "jz "SYMBOL_NAME_STR(ret_from_intr)"\n\t" \
00083 "popl %ebx\n\t" \
00084 "popl %ecx\n\t" \
00085 "popl %edx\n\t" \
00086 "popl %esi\n\t" \
00087 "popl %edi\n\t" \
00088 "popl %ebp\n\t" \
00089 "popl %eax\n\t" \
00090 "popl %ds\n\t" \
00091 "popl %es\n\t" \
00092 "addl $4,%esp\n\t" \
00093 "iret\n\t")
00094
00095 static inline void lxrt_context_switch (struct task_struct *prev,
00096 struct task_struct *next,
00097 int cpuid)
00098 {
00099 struct mm_struct *oldmm = prev->active_mm;
00100
00101 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
00102 switch_mm(oldmm,next->active_mm,next,cpuid);
00103 #else
00104 switch_mm(oldmm,next->active_mm,next);
00105 #endif
00106
00107 if (!next->mm)
00108 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
00109 enter_lazy_tlb(oldmm,next,cpuid);
00110 #else
00111 enter_lazy_tlb(oldmm,next);
00112 #endif
00113
00114 __asm__ __volatile__( \
00115 "pushfl\n\t" \
00116 "cli\n\t" \
00117 "pushl %%esi\n\t" \
00118 "pushl %%edi\n\t" \
00119 "pushl %%ebp\n\t" \
00120 "movl %%esp,%0\n\t" \
00121 "movl %3,%%esp\n\t" \
00122 "movl $1f,%1\n\t" \
00123 "pushl %4\n\t" \
00124 "jmp "SYMBOL_NAME_STR(__switch_to)"\n" \
00125 "1:\t" \
00126 "popl %%ebp\n\t" \
00127 "popl %%edi\n\t" \
00128 "popl %%esi\n\t" \
00129 "popfl\n\t" \
00130 :"=m" (prev->thread.esp),"=m" (prev->thread.eip), \
00131 "=b" (prev) \
00132 :"m" (next->thread.esp),"m" (next->thread.eip), \
00133 "a" (prev), "d" (next), \
00134 "b" (prev)); \
00135 barrier();
00136 }
00137
00138 #endif
00139
00140 static union rtai_lxrt_t _rtai_lxrt(int srq, void *arg)
00141 {
00142 union rtai_lxrt_t retval;
00143 RTAI_DO_TRAP(RTAI_LXRT_VECTOR,retval,srq,arg);
00144 return retval;
00145 }
00146
00147 static inline union rtai_lxrt_t rtai_lxrt(short int dynx, short int lsize, int srq, void *arg)
00148 {
00149 return _rtai_lxrt((dynx << 28) | ((srq & 0xFFF) << 16) | lsize, arg);
00150 }
00151
00152 #ifdef __cplusplus
00153 }
00154 #endif
00155
00156 #endif