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 <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
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
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
00098
00099
#endif
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
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
00119
#define __LXRT_GET_DATASEG(reg) "movl $" STR(__USER_DS) ",%" #reg "\n\t"
00120
#endif
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);
00130
#else
00131
extern void context_switch(
void *,
void *,
void *);
00132 context_switch(0, prev, next);
00133
#endif
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) + (lnxtsk->thread.esp & ~(THREAD_SIZE - 1)) + THREAD_SIZE - lnxtsk->thread.esp, GFP_KERNEL);
00150 *((
struct thread_struct *)lnxtsk->rtai_tskext(TSKEXT2)) = lnxtsk->thread;
00151
00152 memcpy(lnxtsk->rtai_tskext(TSKEXT2) +
sizeof(
struct thread_struct), (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
00159 memcpy((
void *)lnxtsk->thread.esp, lnxtsk->rtai_tskext(TSKEXT2) +
sizeof(
struct thread_struct), (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
00186
00187
00188
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
00212
00213
#ifdef __cplusplus
00214
}
00215
#endif
00216
00217
#endif