00001
00038 #ifndef _RTAI_ASM_I386_HAL_H
00039 #define _RTAI_ASM_I386_HAL_H
00040
00041 #include <rtai_config.h>
00042
00043 #define RTHAL_NR_CPUS ADEOS_NR_CPUS
00044
00045 typedef unsigned long long rthal_time_t;
00046
00047
00048
00049
00050 #ifndef __KERNEL__
00051 #if __GNUC__ == 2 && __GNUC_MINOR >= 96 || __GNUC__ >= 3
00052 #define __attribute_const__ __attribute__((__const__))
00053 #else
00054 #define __attribute_const__
00055 #endif
00056 #if __GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 1
00057 # define inline inline __attribute__((always_inline))
00058 #endif
00059 #endif
00060
00061 #define __rthal_u64tou32(ull, h, l) ({ \
00062 (l) = ull & 0xffffffff; \
00063 (h) = ull >> 32; \
00064 })
00065
00066 #define __rthal_u64fromu32(h, l) ({ \
00067 union { unsigned long long _ull; \
00068 struct { unsigned long _sl, _sh; } _s; } _tmp; \
00069 _tmp._s._sh=(h); \
00070 _tmp._s._sl=(l); \
00071 _tmp._ull; \
00072 })
00073
00074
00075 static inline __attribute_const__ unsigned long long
00076 rthal_ullmul(unsigned long m1, unsigned long m2) {
00077
00078 return (unsigned long long) m1 * m2;
00079 }
00080
00081
00082
00083 static inline __attribute_const__ unsigned long long
00084 __rthal_uldivrem(unsigned long long ull, unsigned long d) {
00085
00086 __asm__ ("divl %1" : "=A,A"(ull) : "r,?m"(d), "A,A"(ull));
00087
00088 return ull;
00089 }
00090
00091
00092
00093
00094 static inline unsigned long
00095 rthal_uldivrem(unsigned long long ull, unsigned long d, unsigned long *rp) {
00096
00097 unsigned long q, r;
00098 ull = __rthal_uldivrem(ull, d);
00099 __asm__ ( "": "=d"(r), "=a"(q) : "A"(ull));
00100 if(rp)
00101 *rp = r;
00102 return q;
00103 }
00104
00105
00106
00107 static inline unsigned long long rthal_ulldiv (unsigned long long ull,
00108 unsigned long d,
00109 unsigned long *rp) {
00110
00111 unsigned long h, l, qh, rh, ql;
00112 __rthal_u64tou32(ull, h, l);
00113
00114 qh = rthal_uldivrem(h, d, &rh);
00115 __asm__ ( "": "=A"(ull) : "d"(rh), "a"(l));
00116 ql = rthal_uldivrem(ull, d, rp);
00117
00118 return __rthal_u64fromu32(qh, ql);
00119 }
00120
00121
00122 #define rthal_u64div32c rthal_ulldiv
00123
00124 static inline __attribute_const__ int rthal_imuldiv (int i, int mult, int div) {
00125
00126
00127 unsigned long ui = (unsigned long) i, um = (unsigned long) mult;
00128 return __rthal_uldivrem((unsigned long long) ui * um, div);
00129 }
00130
00131 static inline __attribute_const__ long long rthal_llimd(long long ll,
00132 int mult,
00133 int div) {
00134
00135
00136
00137 __asm__ ( \
00138 "movl %%edx,%%ecx\t\n" \
00139 "mull %%esi\t\n" \
00140 "movl %%eax,%%ebx\n\t" \
00141 "movl %%ecx,%%eax\t\n" \
00142 "movl %%edx,%%ecx\t\n" \
00143 "mull %%esi\n\t" \
00144 "addl %%ecx,%%eax\t\n" \
00145 "adcl $0,%%edx\t\n" \
00146 "divl %%edi\n\t" \
00147 "movl %%eax,%%ecx\t\n" \
00148 "movl %%ebx,%%eax\t\n" \
00149 "divl %%edi\n\t" \
00150 "sal $1,%%edx\t\n" \
00151 "cmpl %%edx,%%edi\t\n" \
00152 "movl %%ecx,%%edx\n\t" \
00153 "jge 1f\t\n" \
00154 "addl $1,%%eax\t\n" \
00155 "adcl $0,%%edx\t\n" \
00156 "1:\t\n" \
00157 : "=A" (ll) \
00158 : "A" (ll), "S" (mult), "D" (div) \
00159 : "%ebx", "%ecx");
00160
00161 return ll;
00162 }
00163
00164
00165 static inline __attribute_const__ unsigned long ffnz (unsigned long word) {
00166
00167 __asm__("bsfl %1, %0"
00168 : "=r,r" (word)
00169 : "r,?m" (word));
00170 return word;
00171 }
00172
00173 #if defined(__KERNEL__) && !defined(__cplusplus)
00174 #include <linux/sched.h>
00175 #include <linux/interrupt.h>
00176 #include <asm/system.h>
00177 #include <asm/io.h>
00178 #include <asm/timex.h>
00179 #include <nucleus/asm/atomic.h>
00180 #include <asm/processor.h>
00181 #include <io_ports.h>
00182 #ifdef CONFIG_X86_LOCAL_APIC
00183 #include <asm/fixmap.h>
00184 #include <asm/apic.h>
00185 #endif
00186
00187 typedef void (*rthal_irq_handler_t)(unsigned irq,
00188 void *cookie);
00189
00190 struct rthal_calibration_data {
00191
00192 unsigned long cpu_freq;
00193 unsigned long timer_freq;
00194 };
00195
00196 extern struct rthal_calibration_data rthal_tunables;
00197
00198 extern volatile unsigned long rthal_cpu_realtime;
00199
00200 extern adomain_t rthal_domain;
00201
00202 #define RTHAL_DOMAIN_ID 0x52544149
00203
00204 #define RTHAL_NR_SRQS 32
00205
00206 #define RTHAL_TIMER_FREQ (rthal_tunables.timer_freq)
00207 #define RTHAL_CPU_FREQ (rthal_tunables.cpu_freq)
00208 #define RTHAL_8254_IRQ 0
00209
00210 #ifdef CONFIG_X86_LOCAL_APIC
00211 #define RTHAL_APIC_TIMER_VECTOR ADEOS_SERVICE_VECTOR3
00212 #define RTHAL_APIC_TIMER_IPI ADEOS_SERVICE_IPI3
00213 #define RTHAL_APIC_ICOUNT ((RTHAL_TIMER_FREQ + HZ/2)/HZ)
00214 #endif
00215
00216 #ifdef CONFIG_X86_TSC
00217 static inline unsigned long long rthal_rdtsc (void) {
00218 unsigned long long t;
00219 __asm__ __volatile__( "rdtsc" : "=A" (t));
00220 return t;
00221 }
00222 #else
00223 #define RTHAL_8254_COUNT2LATCH 0xfffe
00224 void rthal_setup_8254_tsc(void);
00225 rthal_time_t rthal_get_8254_tsc(void);
00226 #define rthal_rdtsc() rthal_get_8254_tsc()
00227 #endif
00228
00229 #define rthal_cli() adeos_stall_pipeline_from(&rthal_domain)
00230 #define rthal_sti() adeos_unstall_pipeline_from(&rthal_domain)
00231 #define rthal_local_irq_save(x) ((x) = !!adeos_test_and_stall_pipeline_from(&rthal_domain))
00232 #define rthal_local_irq_restore(x) adeos_restore_pipeline_from(&rthal_domain,(x))
00233 #define rthal_local_irq_flags(x) ((x) = !!adeos_test_pipeline_from(&rthal_domain))
00234 #define rthal_local_irq_test() (!!adeos_test_pipeline_from(&rthal_domain))
00235 #define rthal_local_irq_sync(x) ((x) = !!adeos_test_and_unstall_pipeline_from(&rthal_domain))
00236
00237 #define rthal_hw_lock(flags) adeos_hw_local_irq_save(flags)
00238 #define rthal_hw_unlock(flags) adeos_hw_local_irq_restore(flags)
00239 #define rthal_hw_enable() adeos_hw_sti()
00240 #define rthal_hw_disable() adeos_hw_cli()
00241
00242 #define rthal_linux_sti() adeos_unstall_pipeline_from(adp_root)
00243 #define rthal_linux_cli() adeos_stall_pipeline_from(adp_root)
00244 #define rthal_linux_local_irq_save(x) ((x) = !!adeos_test_and_stall_pipeline_from(adp_root))
00245 #define rthal_linux_local_irq_restore(x) adeos_restore_pipeline_from(adp_root,x)
00246 #define rthal_linux_local_irq_restore_nosync(x,cpuid) adeos_restore_pipeline_nosync(adp_root,x,cpuid)
00247
00248 #define rthal_spin_lock(lock) adeos_spin_lock(lock)
00249 #define rthal_spin_unlock(lock) adeos_spin_unlock(lock)
00250
00251 static inline void rthal_spin_lock_irq(spinlock_t *lock) {
00252
00253 rthal_cli();
00254 rthal_spin_lock(lock);
00255 }
00256
00257 static inline void rthal_spin_unlock_irq(spinlock_t *lock) {
00258
00259 rthal_spin_unlock(lock);
00260 rthal_sti();
00261 }
00262
00263 static inline unsigned long rthal_spin_lock_irqsave(spinlock_t *lock) {
00264
00265 unsigned long flags;
00266 rthal_local_irq_save(flags);
00267 rthal_spin_lock(lock);
00268 return flags;
00269 }
00270
00271 static inline void rthal_spin_unlock_irqrestore(unsigned long flags,
00272 spinlock_t *lock) {
00273 rthal_spin_unlock(lock);
00274 rthal_local_irq_restore(flags);
00275 }
00276
00277 #ifdef CONFIG_SMP
00278 #define rthal_cpu_relax(x) \
00279 do { \
00280 int i = 0; \
00281 do \
00282 cpu_relax(); \
00283 while (++i < x); \
00284 } while(0)
00285 #endif
00286
00287 #if !defined(CONFIG_ADEOS_NOTHREADS)
00288
00289
00290
00291
00292
00293
00294 static inline struct task_struct *rthal_get_root_current (int cpuid) {
00295 return ((struct thread_info *)(((u_long)adp_root->esp[cpuid]) & (~8191UL)))->task;
00296 }
00297
00298 static inline struct task_struct *rthal_get_current (int cpuid)
00299
00300 {
00301 int *esp;
00302
00303 __asm__ ("movl %%esp, %0" : "=r,?m" (esp));
00304
00305 if (esp >= rthal_domain.estackbase[cpuid] && esp < rthal_domain.estackbase[cpuid] + 2048)
00306 return rthal_get_root_current(cpuid);
00307
00308 return get_current();
00309 }
00310
00311 #else
00312
00313 static inline struct task_struct *rthal_get_root_current (int cpuid) {
00314 return current;
00315 }
00316
00317 static inline struct task_struct *rthal_get_current (int cpuid) {
00318 return current;
00319 }
00320
00321 #endif
00322
00323 static inline void rthal_set_timer_shot (unsigned long delay) {
00324
00325 if (delay) {
00326 unsigned long flags;
00327 rthal_hw_lock(flags);
00328 #ifdef CONFIG_X86_LOCAL_APIC
00329 apic_read(APIC_LVTT);
00330 apic_write_around(APIC_LVTT,RTHAL_APIC_TIMER_VECTOR);
00331 apic_read(APIC_TMICT);
00332 apic_write_around(APIC_TMICT,delay);
00333 #else
00334 outb(delay & 0xff,0x40);
00335 outb(delay >> 8,0x40);
00336 #endif
00337 rthal_hw_unlock(flags);
00338 }
00339 }
00340
00341
00342
00343 unsigned long rthal_critical_enter(void (*synch)(void));
00344
00345 void rthal_critical_exit(unsigned long flags);
00346
00347 void rthal_set_linux_task_priority(struct task_struct *task,
00348 int policy,
00349 int prio);
00350
00351 #endif
00352
00353
00354
00355 #ifdef __KERNEL__
00356
00357 #include <linux/kernel.h>
00358
00359 typedef int (*rthal_trap_handler_t)(adevinfo_t *evinfo);
00360
00361 #define rthal_printk printk
00362
00363 #ifdef __cplusplus
00364 extern "C" {
00365 #endif
00366
00367 int rthal_request_irq(unsigned irq,
00368 void (*handler)(unsigned irq, void *cookie),
00369 void *cookie);
00370
00371 int rthal_release_irq(unsigned irq);
00372
00378 int rthal_enable_irq(unsigned irq);
00379
00380 int rthal_disable_irq(unsigned irq);
00381
00384 int rthal_request_linux_irq(unsigned irq,
00385 irqreturn_t (*handler)(int irq,
00386 void *dev_id,
00387 struct pt_regs *regs),
00388 char *name,
00389 void *dev_id);
00390
00391 int rthal_release_linux_irq(unsigned irq,
00392 void *dev_id);
00393
00394 int rthal_pend_linux_irq(unsigned irq);
00395
00396 int rthal_pend_linux_srq(unsigned srq);
00397
00398 int rthal_request_srq(unsigned label,
00399 void (*handler)(void));
00400
00401 int rthal_release_srq(unsigned srq);
00402
00403 int rthal_set_irq_affinity(unsigned irq,
00404 cpumask_t cpumask,
00405 cpumask_t *oldmask);
00406
00407 int rthal_request_timer(void (*handler)(void),
00408 unsigned long nstick);
00409
00410 void rthal_release_timer(void);
00411
00412 rthal_trap_handler_t rthal_set_trap_handler(rthal_trap_handler_t handler);
00413
00414 unsigned long rthal_calibrate_timer(void);
00415
00416 #ifdef __cplusplus
00417 }
00418 #endif
00419
00420 #endif
00421
00424 #endif