00001
00036 #ifndef _RTAI_ASM_PPC_HAL_H
00037 #define _RTAI_ASM_PPC_HAL_H
00038
00039 #include <rtai_config.h>
00040
00041 #define RTHAL_NR_CPUS ADEOS_NR_CPUS
00042
00043 typedef unsigned long long rthal_time_t;
00044
00045 static inline unsigned long long rthal_ulldiv (unsigned long long ull,
00046 unsigned long uld,
00047 unsigned long *r)
00048 {
00049 unsigned long long q, rf;
00050 unsigned long qh, rh, ql, qf;
00051
00052 q = 0;
00053 rf = (unsigned long long)(0xFFFFFFFF - (qf = 0xFFFFFFFF / uld) * uld) + 1ULL;
00054
00055 while (ull >= uld)
00056 {
00057 ((unsigned long *)&q)[0] += (qh = ((unsigned long *)&ull)[0] / uld);
00058 rh = ((unsigned long *)&ull)[0] - qh * uld;
00059 q += rh * (unsigned long long)qf + (ql = ((unsigned long *)&ull)[1] / uld);
00060 ull = rh * rf + (((unsigned long *)&ull)[1] - ql * uld);
00061 }
00062
00063 if (r)
00064 *r = ull;
00065
00066 return q;
00067 }
00068
00069 #define rthal_uldivrem(ull,ul,rp) ((u_long) rthal_ulldiv((ull),(ul),(rp)))
00070
00071 static inline unsigned long long rthal_ullmul(unsigned long m0,
00072 unsigned long m1)
00073 {
00074 unsigned long long res;
00075
00076 __asm__ __volatile__ ("mulhwu %0, %1, %2"
00077 : "=r" (((unsigned long *)&res)[0])
00078 : "%r" (m0), "r" (m1));
00079
00080 ((unsigned long *)&res)[1] = m0*m1;
00081
00082 return res;
00083 }
00084
00085 static inline int rthal_imuldiv (int i, int mult, int div) {
00086
00087
00088
00089 unsigned long q, r;
00090 q = rthal_ulldiv(rthal_ullmul(i, mult), div, &r);
00091 return (r + r) > div ? q + 1 : q;
00092 }
00093
00094 static inline long long rthal_llimd(long long ll, int mult, int div) {
00095
00096
00097
00098 unsigned long long low;
00099 unsigned long q, r;
00100
00101 low = rthal_ullmul(((unsigned long *)&ll)[1], mult);
00102 q = rthal_ulldiv(rthal_ullmul(((unsigned long *)&ll)[0], mult) +
00103 ((unsigned long *)&low)[0], div, (unsigned long *)&low);
00104 low = rthal_ulldiv(low, div, &r);
00105 ((unsigned long *)&low)[0] += q;
00106
00107 return (r + r) > div ? low + 1 : low;
00108 }
00109
00110 static inline unsigned long ffnz (unsigned long ul) {
00111
00112 __asm__ __volatile__ ("cntlzw %0, %1" : "=r" (ul) : "r" (ul & (-ul)));
00113 return 31 - ul;
00114 }
00115
00116 #if defined(__KERNEL__) && !defined(__cplusplus)
00117 #include <linux/sched.h>
00118 #include <linux/interrupt.h>
00119 #include <asm/system.h>
00120 #include <asm/time.h>
00121 #include <asm/timex.h>
00122 #include <nucleus/asm/atomic.h>
00123 #include <asm/processor.h>
00124
00125 typedef void (*rthal_irq_handler_t)(unsigned irq,
00126 void *cookie);
00127
00128 struct rthal_calibration_data {
00129
00130 unsigned long cpu_freq;
00131 unsigned long timer_freq;
00132 };
00133
00134 extern struct rthal_calibration_data rthal_tunables;
00135
00136 extern volatile unsigned long rthal_cpu_realtime;
00137
00138 extern adomain_t rthal_domain;
00139
00140 #define RTHAL_DOMAIN_ID 0x52544149
00141
00142 #define RTHAL_NR_SRQS 32
00143
00144 #define RTHAL_TIMER_IRQ ADEOS_TIMER_VIRQ
00145 #define RTHAL_TIMER_FREQ (rthal_tunables.timer_freq)
00146 #define RTHAL_CPU_FREQ (rthal_tunables.cpu_freq)
00147
00148 static inline unsigned long long rthal_rdtsc (void) {
00149 unsigned long long t;
00150 adeos_hw_tsc(t);
00151 return t;
00152 }
00153
00154 #define rthal_cli() adeos_stall_pipeline_from(&rthal_domain)
00155 #define rthal_sti() adeos_unstall_pipeline_from(&rthal_domain)
00156 #define rthal_local_irq_save(x) ((x) = !!adeos_test_and_stall_pipeline_from(&rthal_domain))
00157 #define rthal_local_irq_restore(x) adeos_restore_pipeline_from(&rthal_domain,(x))
00158 #define rthal_local_irq_flags(x) ((x) = !!adeos_test_pipeline_from(&rthal_domain))
00159 #define rthal_local_irq_test() (!!adeos_test_pipeline_from(&rthal_domain))
00160 #define rthal_local_irq_sync(x) ((x) = !!adeos_test_and_unstall_pipeline_from(&rthal_domain))
00161
00162 #define rthal_hw_lock(flags) adeos_hw_local_irq_save(flags)
00163 #define rthal_hw_unlock(flags) adeos_hw_local_irq_restore(flags)
00164 #define rthal_hw_enable() adeos_hw_sti()
00165 #define rthal_hw_disable() adeos_hw_cli()
00166
00167 #define rthal_linux_sti() adeos_unstall_pipeline_from(adp_root)
00168 #define rthal_linux_cli() adeos_stall_pipeline_from(adp_root)
00169 #define rthal_linux_local_irq_save(x) ((x) = !!adeos_test_and_stall_pipeline_from(adp_root))
00170 #define rthal_linux_local_irq_restore(x) adeos_restore_pipeline_from(adp_root,x)
00171 #define rthal_linux_local_irq_restore_nosync(x,cpuid) adeos_restore_pipeline_nosync(adp_root,x,cpuid)
00172
00173 #define rthal_spin_lock(lock) adeos_spin_lock(lock)
00174 #define rthal_spin_unlock(lock) adeos_spin_unlock(lock)
00175
00176 static inline void rthal_spin_lock_irq(spinlock_t *lock) {
00177
00178 rthal_cli();
00179 rthal_spin_lock(lock);
00180 }
00181
00182 static inline void rthal_spin_unlock_irq(spinlock_t *lock) {
00183
00184 rthal_spin_unlock(lock);
00185 rthal_sti();
00186 }
00187
00188 static inline unsigned long rthal_spin_lock_irqsave(spinlock_t *lock) {
00189
00190 unsigned long flags;
00191 rthal_local_irq_save(flags);
00192 rthal_spin_lock(lock);
00193 return flags;
00194 }
00195
00196 static inline void rthal_spin_unlock_irqrestore(unsigned long flags,
00197 spinlock_t *lock) {
00198 rthal_spin_unlock(lock);
00199 rthal_local_irq_restore(flags);
00200 }
00201
00202 #ifdef CONFIG_SMP
00203 #define rthal_cpu_relax(x) \
00204 do { \
00205 int i = 0; \
00206 do \
00207 cpu_relax(); \
00208 while (++i < x); \
00209 } while(0)
00210 #endif
00211
00212 #if !defined(CONFIG_ADEOS_NOTHREADS)
00213
00214
00215
00216
00217
00218
00219 static inline struct task_struct *rthal_get_root_current (int cpuid) {
00220 return ((struct thread_info *)(adp_root->esp[cpuid] & (~8191UL)))->task;
00221 }
00222
00223 static inline struct task_struct *rthal_get_current (int cpuid)
00224
00225 {
00226 register unsigned long esp asm ("r1");
00227
00228
00229 if (esp >= rthal_domain.estackbase[cpuid] && esp < rthal_domain.estackbase[cpuid] + 8192)
00230 return rthal_get_root_current(cpuid);
00231
00232 return current;
00233 }
00234
00235 #else
00236
00237 static inline struct task_struct *rthal_get_root_current (int cpuid) {
00238 return current;
00239 }
00240
00241 static inline struct task_struct *rthal_get_current (int cpuid) {
00242 return current;
00243 }
00244
00245 #endif
00246
00247 static inline void rthal_set_timer_shot (unsigned long delay) {
00248
00249 if (delay) {
00250 #ifdef CONFIG_40x
00251 mtspr(SPRN_PIT,delay);
00252 #else
00253 set_dec(delay);
00254 #endif
00255 }
00256 }
00257
00258
00259
00260 unsigned long rthal_critical_enter(void (*synch)(void));
00261
00262 void rthal_critical_exit(unsigned long flags);
00263
00264 void rthal_set_linux_task_priority(struct task_struct *task,
00265 int policy,
00266 int prio);
00267
00268
00269
00270 #define RTHAL_SWITCH_FRAME_SIZE 108
00271
00272 void rthal_switch_context(unsigned long *out_kspp,
00273 unsigned long *in_kspp);
00274
00275 #ifdef CONFIG_RTAI_HW_FPU
00276
00277 typedef struct rthal_fpenv {
00278
00279
00280
00281
00282
00283
00284 double fpr[32];
00285 unsigned long fpscr_pad;
00286 unsigned long fpscr;
00287
00288 } rthal_fpenv_t;
00289
00290 void rthal_init_fpu(rthal_fpenv_t *fpuenv);
00291
00292 void rthal_save_fpu(rthal_fpenv_t *fpuenv);
00293
00294 void rthal_restore_fpu(rthal_fpenv_t *fpuenv);
00295
00296 #endif
00297
00298 #endif
00299
00300
00301
00302 #ifdef __KERNEL__
00303
00304 #include <linux/kernel.h>
00305
00306 typedef int (*rthal_trap_handler_t)(adevinfo_t *evinfo);
00307
00308 #define rthal_printk printk
00309
00310 #ifdef __cplusplus
00311 extern "C" {
00312 #endif
00313
00314 int rthal_request_irq(unsigned irq,
00315 void (*handler)(unsigned irq, void *cookie),
00316 void *cookie);
00317
00318 int rthal_release_irq(unsigned irq);
00319
00325 int rthal_enable_irq(unsigned irq);
00326
00327 int rthal_disable_irq(unsigned irq);
00328
00331 int rthal_request_linux_irq(unsigned irq,
00332 irqreturn_t (*handler)(int irq,
00333 void *dev_id,
00334 struct pt_regs *regs),
00335 char *name,
00336 void *dev_id);
00337
00338 int rthal_release_linux_irq(unsigned irq,
00339 void *dev_id);
00340
00341 int rthal_pend_linux_irq(unsigned irq);
00342
00343 int rthal_pend_linux_srq(unsigned srq);
00344
00345 int rthal_request_srq(unsigned label,
00346 void (*handler)(void));
00347
00348 int rthal_release_srq(unsigned srq);
00349
00350 int rthal_set_irq_affinity(unsigned irq,
00351 cpumask_t cpumask,
00352 cpumask_t *oldmask);
00353
00354 int rthal_request_timer(void (*handler)(void),
00355 unsigned long nstick);
00356
00357 void rthal_release_timer(void);
00358
00359 rthal_trap_handler_t rthal_set_trap_handler(rthal_trap_handler_t handler);
00360
00361 unsigned long rthal_calibrate_timer(void);
00362
00363 #ifdef __cplusplus
00364 }
00365 #endif
00366
00367 #endif
00368
00371 #endif