00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef _RTAI_ASM_MIPS_RTAI_H_
00032 #define _RTAI_ASM_MIPS_RTAI_H_
00033
00034 #include <rtai_types.h>
00035
00036 static inline unsigned long long ullmul(unsigned long m0, unsigned long m1)
00037 {
00038
00039 unsigned long long __res;
00040
00041 __asm__ __volatile__ (
00042 "multu\t%2,%3\n\t"
00043 "mflo\t%0\n\t"
00044 "mfhi\t%1\n\t"
00045 : "=r" (((unsigned long *)&__res)[0]),
00046 "=r" (((unsigned long *)&__res)[1])
00047 : "r" (m0), "r" (m1));
00048
00049 return(__res);
00050
00051 }
00052
00053
00054 static inline unsigned long long ulldiv(unsigned long long ull,
00055 unsigned long uld, unsigned long *r)
00056 {
00057 unsigned long long q, rf;
00058 unsigned long qh, rh, ql, qf;
00059
00060 q = 0;
00061 rf = (unsigned long long)(0xFFFFFFFF - (qf = 0xFFFFFFFF / uld) * uld)
00062 + 1ULL;
00063
00064 while (ull >= uld) {
00065 ((unsigned long *)&q)[1] +=
00066 (qh = ((unsigned long *)&ull)[1] / uld);
00067
00068 rh = ((unsigned long *)&ull)[1] - qh * uld;
00069 q += rh * (unsigned long long)qf +
00070 (ql = ((unsigned long *)&ull)[0] / uld);
00071
00072 ull = rh * rf + (((unsigned long *)&ull)[0] - ql * uld);
00073 }
00074
00075 *r = ull;
00076 return(q);
00077 }
00078
00079 static inline int imuldiv(int i, int mult, int div)
00080 {
00081 unsigned long q, r;
00082
00083 q = ulldiv(ullmul(i, mult), div, &r);
00084
00085 return (r + r) > div ? q + 1 : q;
00086 }
00087
00088 static inline unsigned long long llimd(unsigned long long ull,
00089 unsigned long mult, unsigned long div)
00090 {
00091 unsigned long long low;
00092 unsigned long q, r;
00093
00094 low = ullmul(((unsigned long *)&ull)[0], mult);
00095 q = ulldiv( ullmul(((unsigned long *)&ull)[1], mult) +
00096 ((unsigned long *)&low)[1], div, (unsigned long *)&low);
00097 low = ulldiv(low, div, &r);
00098 ((unsigned long *)&low)[1] += q;
00099
00100 return (r + r) > div ? low + 1 : low;
00101 }
00102
00103
00104 #ifdef __KERNEL__
00105
00106 #ifndef __cplusplus
00107 #include <linux/smp.h>
00108 #include <linux/spinlock.h>
00109 #include <linux/irq.h>
00110 #include <asm/system.h>
00111 #include <asm/bitops.h>
00112 #include <asm/mipsregs.h>
00113 #include <asm/rtai_atomic.h>
00114 #endif
00115
00116
00117
00118
00119 #define IRQ_s334 3
00120 #define IRQ_EIC 5
00121 #define IRQ_TIMER 7
00122
00123
00124
00125
00126 #define RTAI_NR_TRAPS 16
00127
00128
00129
00130
00131 #define CPU_FREQ (tuned.cpu_freq)
00132 #define FREQ_DECR CPU_FREQ
00133 #define CALIBRATED_CPU_FREQ 0
00134
00135
00136
00137
00138 #define FREQ_8254 CPU_FREQ
00139 #define FREQ_APIC CPU_FREQ
00140 #define LATENCY_8254 3000
00141 #define SETUP_TIME_8254 500
00142 #define TIMER_8254_IRQ IRQ_TIMER
00143
00144 #define IFLAG 9
00145
00146 #ifndef CLOCK_TICK_RATE
00147 #define CLOCK_TICK_RATE 1193180
00148 #endif
00149
00150
00151
00152
00153 #define IFLAG_POS 0
00154
00155 #define NR_RT_CPUS 1
00156
00157 #define rt_write_timer_count(cnt) do { \
00158 write_c0_count(cnt); } while(0)
00159
00160 #define rt_read_timer_countg() read_c0_count();
00161
00162 #define rt_write_timer_comp(cnt) do { \
00163 write_c0_compare(cnt); } while(0)
00164
00165 #define rt_read_timer_comp() do { \
00166 read_c0_compare(); } while(0)
00167
00168 #define rt_set_timer_incr(x) do { \
00169 write_c0_compare((x)); } while(0)
00170
00171 #define hard_cpu_id() hard_smp_processor_id()
00172
00173 #define rt_spin_lock(lock)
00174 #define rt_spin_unlock(lock)
00175
00176 #define rt_get_global_lock() hard_cli()
00177 #define rt_release_global_lock()
00178
00179 #define save_fpenv(x)
00180 #define restore_fpenv(x)
00181
00182 #define RT_TIME_END 0x7fffffffffffffffLL
00183
00184 struct apic_timer_setup_data;
00185
00186 struct global_rt_status {
00187 volatile unsigned int pending_irqs_l;
00188 volatile unsigned int pending_irqs_h;
00189 volatile unsigned int activ_irqs;
00190 volatile unsigned int pending_srqs;
00191 volatile unsigned int activ_srqs;
00192 volatile unsigned int cpu_in_sti;
00193 volatile unsigned int used_by_linux;
00194 volatile unsigned int locked_cpus;
00195 volatile unsigned int hard_nesting;
00196 volatile unsigned int hard_lock_all_service;
00197 #ifdef CONFIG_X86_REMOTE_DEBUG
00198 volatile unsigned int used_by_gdbstub;
00199 #endif
00200 spinlock_t hard_lock;
00201 spinlock_t data_lock;
00202 };
00203
00204
00205 struct apic_timer_setup_data {
00206 int mode;
00207 int count;
00208 };
00209
00210
00211
00212 struct calibration_data {
00213 unsigned int cpu_freq;
00214 unsigned int apic_freq;
00215 int latency;
00216 int setup_time_TIMER_CPUNIT;
00217 int setup_time_TIMER_UNIT;
00218 int timers_tol[NR_RT_CPUS];
00219 };
00220
00221
00222 typedef struct mips_fpu_env { unsigned long fpu_reg[32]; } FPU_ENV;
00223
00224
00225 #define save_cr0_and_clts(x)
00226 #define restore_cr0(x)
00227 #define enable_fpu()
00228 #define DECLR_8254_TSC_EMULATION
00229 #define TICK_8254_TSC_EMULATION
00230 #define SETUP_8254_TSC_EMULATION
00231 #define CLEAR_8254_TSC_EMULATION
00232
00233
00234 extern unsigned volatile int *locked_cpus;
00235
00236 static inline void rt_spin_lock_irq(spinlock_t *lock)
00237 {
00238 hard_cli();
00239 rt_spin_lock(lock);
00240 }
00241
00242 static inline void rt_spin_unlock_irq(spinlock_t *lock)
00243 {
00244 rt_spin_unlock(lock);
00245 hard_sti();
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 static inline unsigned int rt_spin_lock_irqsave(spinlock_t *lock)
00259 {
00260 unsigned long flags;
00261 hard_save_flags_and_cli(flags);
00262 rt_spin_lock(lock);
00263 return flags;
00264 }
00265
00266 static inline void rt_spin_unlock_irqrestore(unsigned long flags,
00267 spinlock_t *lock)
00268 {
00269 rt_spin_unlock(lock);
00270 hard_restore_flags(flags);
00271 }
00272
00273
00274
00275
00276
00277
00278
00279 static inline void rt_global_cli(void)
00280 {
00281 rt_get_global_lock();
00282 }
00283
00284 static inline void rt_global_sti(void)
00285 {
00286 rt_release_global_lock();
00287 hard_sti();
00288 }
00289
00290
00291 static inline int rt_global_save_flags_and_cli(void)
00292 {
00293 unsigned long flags;
00294
00295 hard_save_flags_and_cli(flags);
00296 if (!test_and_set_bit(hard_cpu_id(), locked_cpus)) {
00297 while (test_and_set_bit(31, locked_cpus));
00298 return ((flags & (1 << IFLAG)) + 1);
00299 } else {
00300 return (flags & (1 << IFLAG));
00301 }
00302 }
00303
00304
00305 static inline void rt_global_save_flags(unsigned long *flags)
00306 {
00307 unsigned long hflags, rflags;
00308
00309 hard_save_flags_and_cli(hflags);
00310 hflags = hflags & (1 << IFLAG);
00311 rflags = hflags | !test_bit(hard_cpu_id(), locked_cpus);
00312 if (hflags) {
00313 hard_sti();
00314 }
00315 *flags = rflags;
00316 }
00317
00318
00319 static inline void rt_global_restore_flags(unsigned long flags)
00320 {
00321 switch (flags) {
00322 case (1 << IFLAG) | 1: rt_release_global_lock();
00323 hard_sti();
00324 break;
00325 case (1 << IFLAG) | 0: rt_get_global_lock();
00326 hard_sti();
00327 break;
00328 case (0 << IFLAG) | 1: rt_release_global_lock();
00329 break;
00330 case (0 << IFLAG) | 0: rt_get_global_lock();
00331 break;
00332 }
00333 }
00334
00335
00336 extern struct rt_times rt_times;
00337 extern struct rt_times rt_smp_times[NR_RT_CPUS];
00338 extern struct calibration_data tuned;
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 extern __inline__ unsigned long ffnz(unsigned long word)
00350 {
00351 unsigned int __res;
00352 unsigned int __mask = 1;
00353
00354 __asm__ (
00355 ".set\tnoreorder\n\t"
00356 ".set\tnoat\n\t"
00357 "move\t%0,$0\n"
00358 "1:\tand\t$1,%2,%1\n\t"
00359 "bnez\t$1,2f\n\t"
00360 "sll\t%1,1\n\t"
00361 "bnez\t%1,1b\n\t"
00362 "addiu\t%0,1\n\t"
00363 ".set\tat\n\t"
00364 ".set\treorder\n"
00365 "2:\n\t"
00366 : "=&r" (__res), "=r" (__mask)
00367 : "r" (word), "1" (__mask)
00368 : "$1");
00369
00370 return __res;
00371 }
00372
00373
00374 static inline unsigned long long rdtsc(void)
00375 {
00376 extern struct rt_hal rthal;
00377 unsigned long count;
00378 long flags;
00379
00380 count = read_c0_count();
00381 hard_save_flags_and_cli(flags);
00382 rthal.tsc.hltsc[1] += (count < rthal.tsc.hltsc[0]);
00383 rthal.tsc.hltsc[0] = count;
00384 hard_restore_flags(flags);
00385 return rthal.tsc.tsc;
00386
00387 }
00388
00389
00390
00391
00392
00393
00394 int rt_request_global_irq(unsigned int irq, void (*handler)(void));
00395 int rt_free_global_irq(unsigned int irq);
00396 void rt_ack_irq(unsigned int irq);
00397 void rt_mask_and_ack_irq(unsigned int irq);
00398 void rt_unmask_irq(unsigned int irq);
00399 unsigned int rt_startup_irq(unsigned int irq);
00400 void rt_shutdown_irq(unsigned int irq);
00401 void rt_enable_irq(unsigned int irq);
00402 void rt_disable_irq(unsigned int irq);
00403 int rt_request_linux_irq(unsigned int irq,
00404 void (*linux_handler)(int irq, void *dev_id, struct pt_regs *regs),
00405 char *linux_handler_id, void *dev_id);
00406 int rt_free_linux_irq(unsigned int irq, void *dev_id);
00407 void rt_pend_linux_irq(unsigned int irq);
00408 int rt_request_srq(unsigned int label, void (*rtai_handler)(void),
00409 long long (*user_handler)(unsigned int whatever));
00410 int rt_free_srq(unsigned int srq);
00411 void rt_pend_linux_srq(unsigned int srq);
00412 int rt_request_cpu_own_irq(unsigned int irq, void (*handler)(void));
00413 int rt_free_cpu_own_irq(unsigned int irq);
00414 int rt_request_timer(void (*handler)(void), unsigned int tick, int apic);
00415 int rt_free_timer(void);
00416 void rt_request_apic_timers(void (*handler)(void),
00417 struct apic_timer_setup_data *apic_timer_data);
00418 void rt_free_apic_timers(void);
00419 void rt_mount_rtai(void);
00420 void rt_umount_rtai(void);
00421 int rt_printk(const char *format, ...);
00422 int rtai_print_to_screen(const char *format, ...);
00423 extern void rt_switch_to_linux(int cpuid);
00424 extern void rt_switch_to_real_time(int cpuid);
00425
00426 #define rt_assign_irq_to_cpu(irq, cpu)
00427 #define rt_reset_irq_to_sym_mode(irq)
00428
00429
00430
00431
00432
00433
00434 static inline void rt_set_timer_delay(int delay)
00435 {
00436 unsigned long flags;
00437
00438 hard_save_flags_and_cli(flags);
00439 write_c0_compare(read_c0_count() +
00440 (delay ? delay : rt_times.periodic_tick));
00441 hard_restore_flags(flags);
00442 rt_enable_irq(TIMER_8254_IRQ);
00443
00444 }
00445
00446 #endif
00447
00448 #define RTAI_DEFAULT_TICK 200000
00449 #define RTAI_DEFAULT_STACKSZ 1000
00450
00451 #endif // _RTAI_ASM_MIPS_RTAI_H_