00001
00042 #ifndef _RTAI_ASM_PPC64_HAL_H
00043 #define _RTAI_ASM_PPC64_HAL_H
00044
00045 #include <nucleus/asm-generic/hal.h>
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
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
00122
00123
00124
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
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
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
00160
00161
00162
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
00173
00174
00175
00176
00177 double fpr[32];
00178 unsigned long fpscr;
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
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
00196
00197 #define rthal_disable_fpu() ({ \
00198 register unsigned long _msr; \
00199 __asm__ __volatile__ ( "mfmsr %0" : "=r"(_msr) ); \
00200 __asm__ __volatile__ ( "mtmsrd %0" \
00201 : \
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 : \
00211 : "r"(_msr | MSR_FP) \
00212 : "memory" ); \
00213 })
00214
00215 #endif
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
00235
00238 #endif