hal.h

Go to the documentation of this file.
00001 
00042 #ifndef _RTAI_ASM_PPC64_HAL_H
00043 #define _RTAI_ASM_PPC64_HAL_H
00044 
00045 #include <nucleus/asm-generic/hal.h>    /* Read the generic bits. */
00046 #include <asm/div64.h>
00047 
00048 typedef unsigned long rthal_time_t;
00049 
00050 static inline unsigned long long rthal_ullmul(const unsigned long m0, 
00051                                               const unsigned long m1)
00052 {
00053     return (unsigned long long) m0 * m1;
00054 }
00055 
00056 static inline unsigned long long rthal_ulldiv (unsigned long long ull,
00057                                                const unsigned long uld,
00058                                                unsigned long *const rp)
00059 {
00060     const unsigned long r = ull % uld;
00061     ull /= uld;
00062 
00063     if (rp)
00064         *rp = r;
00065 
00066     return ull;
00067 }
00068 
00069 #define rthal_uldivrem(ull,ul,rp) ((u_long) rthal_ulldiv((ull),(ul),(rp)))
00070 
00071 static inline int rthal_imuldiv (int i, int mult, int div) {
00072 
00073     /* Returns (int)i = (unsigned long long)i*(u_long)(mult)/(u_long)div. */
00074     const unsigned long long ull = rthal_ullmul(i, mult);
00075     return rthal_uldivrem(ull, div, NULL);
00076 }
00077 
00078 static inline __attribute_const__
00079 unsigned long long __rthal_ullimd (const unsigned long long op,
00080                                    const unsigned long m,
00081                                    const unsigned long d)
00082 {
00083         return (op*m)/d;
00084 }
00085 
00086 static inline long long rthal_llimd (long long op,
00087                                      unsigned long m,
00088                                      unsigned long d)
00089 {
00090 
00091     if(op < 0LL)
00092         return -__rthal_ullimd(-op, m, d);
00093     return __rthal_ullimd(op, m, d);
00094 }
00095 
00096 static inline  __attribute_const__ unsigned long ffnz (unsigned long ul) {
00097 
00098     __asm__ ("cntlzd %0, %1" : "=r" (ul) : "r" (ul & (-ul)));
00099     return 63 - ul;
00100 }
00101 
00102 #if defined(__KERNEL__) && !defined(__cplusplus)
00103 #include <asm/system.h>
00104 #include <asm/time.h>
00105 #include <asm/timex.h>
00106 #include <nucleus/asm/atomic.h>
00107 #include <asm/processor.h>
00108 
00109 #define RTHAL_TIMER_IRQ   ADEOS_TIMER_VIRQ
00110 
00111 #define rthal_irq_descp(irq)  (irq_desc + irq)
00112 
00113 static inline unsigned long long rthal_rdtsc (void) {
00114     unsigned long long t;
00115     rthal_read_tsc(t);
00116     return t;
00117 }
00118 
00119 #if defined(CONFIG_ADEOS_CORE) && !defined(CONFIG_ADEOS_NOTHREADS)
00120 
00121 /* Since real-time interrupt handlers are called on behalf of the RTAI
00122    domain stack, we cannot infere the "current" Linux task address
00123    using %esp. We must use the suspended Linux domain's stack pointer
00124    instead. */
00125 
00126 static inline struct task_struct *rthal_root_host_task (int cpuid) {
00127     return ((struct thread_info *)(rthal_root_domain->esp[cpuid] & (~(16384-1)UL)))->task;
00128 }
00129 
00130 static inline struct task_struct *rthal_current_host_task (int cpuid)
00131 
00132 {
00133     register unsigned long esp asm ("r1");
00134     
00135     if (esp >= rthal_domain.estackbase[cpuid] && esp < rthal_domain.estackbase[cpuid] + 16384)
00136         return rthal_root_host_task(cpuid);
00137 
00138     return current;
00139 }
00140 
00141 #else /* !CONFIG_ADEOS_CORE || CONFIG_ADEOS_NOTHREADS */
00142 
00143 static inline struct task_struct *rthal_root_host_task (int cpuid) {
00144     return current;
00145 }
00146 
00147 static inline struct task_struct *rthal_current_host_task (int cpuid) {
00148     return current;
00149 }
00150 
00151 #endif /* CONFIG_ADEOS_CORE && !CONFIG_ADEOS_NOTHREADS */
00152 
00153 static inline void rthal_timer_program_shot (unsigned long delay)
00154 {
00155     if(!delay) delay = 1;
00156     set_dec(delay);
00157 }
00158 
00159     /* Private interface -- Internal use only */
00160 
00161 /* The following must be kept in sync w/ rthal_switch_context() in
00162    switch.S */
00163 #define RTHAL_SWITCH_FRAME_SIZE  224
00164 
00165 void rthal_switch_context(unsigned long *out_kspp,
00166                           unsigned long *in_kspp);
00167 
00168 #ifdef CONFIG_RTAI_HW_FPU
00169 
00170 typedef struct rthal_fpenv {
00171     
00172     /* This layout must follow exactely the definition of the FPU
00173        backup area in a PPC thread struct available from
00174        <asm-ppc/processor.h>. Specifically, fpr[] an fpscr words must
00175        be contiguous in memory (see arch/ppc/hal/fpu.S). */
00176 
00177     double fpr[32];
00178     unsigned long fpscr;       /* mffs uses 64-bit (pad in hi/fpscr in lo) */
00179 } rthal_fpenv_t;
00180 
00181 void rthal_init_fpu(rthal_fpenv_t *fpuenv);
00182 
00183 void rthal_save_fpu(rthal_fpenv_t *fpuenv);
00184 
00185 void rthal_restore_fpu(rthal_fpenv_t *fpuenv);
00186 
00187 #ifndef CONFIG_SMP
00188 #define rthal_get_fpu_owner(cur) last_task_used_math
00189 #else /* CONFIG_SMP */
00190 #define rthal_get_fpu_owner(cur) ({                             \
00191     struct task_struct * _cur = (cur);                          \
00192     ((_cur->thread.regs && (_cur->thread.regs->msr & MSR_FP))   \
00193      ? _cur : NULL);                                            \
00194 })
00195 #endif /* CONFIG_SMP */
00196     
00197 #define rthal_disable_fpu() ({                          \
00198     register unsigned long _msr;                                 \
00199     __asm__ __volatile__ ( "mfmsr %0" : "=r"(_msr) );   \
00200     __asm__ __volatile__ ( "mtmsrd %0"                   \
00201                            : /* no output */            \
00202                            : "r"(_msr & ~(MSR_FP))      \
00203                            : "memory" );                \
00204 })
00205 
00206 #define rthal_enable_fpu() ({                           \
00207     register unsigned long _msr;                                 \
00208     __asm__ __volatile__ ( "mfmsr %0" : "=r"(_msr) );   \
00209     __asm__ __volatile__ ( "mtmsrd %0"                   \
00210                            : /* no output */            \
00211                            : "r"(_msr | MSR_FP)         \
00212                            : "memory" );                \
00213 })
00214 
00215 #endif /* CONFIG_RTAI_HW_FPU */
00216 
00217 static const char *const rthal_fault_labels[] = {
00218     [0] =  "Data or instruction access",
00219     [1] =  "Alignment",
00220     [2] =  "AltiVec unavailable",
00221     [3] =  "Program check exception",
00222     [4] =  "Machine check exception",
00223     [5] =  "Unknown",
00224     [6] =  "Instruction breakpoint",
00225     [7] =  "Single-step exception",
00226     [8] =  "Non-recoverable exception",
00227     [9] =  "AltiVec assist",
00228     [10] = "System reset exception",
00229     [11] = "Kernel FP unavailable",
00230     [12] = "Performance monitor",
00231     [13] = NULL
00232 };
00233 
00234 #endif /* __KERNEL__ && !__cplusplus */
00235 
00238 #endif /* !_RTAI_ASM_PPC64_HAL_H */

Generated on Sat Sep 3 12:32:46 2005 for RTAI Fusion API by  doxygen 1.4.2