system.h

00001 /*
00002  * Copyright (C) 2001,2002,2003,2004,2005 Philippe Gerum <rpm@xenomai.org>.
00003  * Copyright (C) 2004,2005 Gilles Chanteperdrix <gilles.chanteperdrix@laposte.net>.
00004  *
00005  * RTAI/fusion is free software; you can redistribute it and/or modify it
00006  * under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * RTAI/fusion is distributed in the hope that it will be useful, but
00011  * WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with RTAI/fusion; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00018  * 02111-1307, USA.
00019  */
00020 
00021 #ifndef _RTAI_ASM_GENERIC_SYSTEM_H
00022 #define _RTAI_ASM_GENERIC_SYSTEM_H
00023 
00024 #ifdef __KERNEL__
00025 
00026 #include <linux/kernel.h>
00027 #include <linux/version.h>
00028 #include <linux/module.h>
00029 #include <linux/slab.h>
00030 #include <linux/errno.h>
00031 #include <linux/adeos.h>
00032 #include <linux/vmalloc.h>
00033 #include <asm/uaccess.h>
00034 #include <asm/param.h>
00035 #include <asm/mmu_context.h>
00036 #include <rtai_config.h>
00037 #include <nucleus/asm/hal.h>
00038 #include <nucleus/asm/atomic.h>
00039 #include <nucleus/shadow.h>
00040 
00041 #define module_param_value(parm) (parm)
00042 
00043 typedef unsigned long spl_t;
00044 
00045 #define splhigh(x)  rthal_local_irq_save(x)
00046 #ifdef CONFIG_SMP
00047 #define splexit(x)  rthal_local_irq_restore((x) & 1)
00048 #else /* !CONFIG_SMP */
00049 #define splexit(x)  rthal_local_irq_restore(x)
00050 #endif /* CONFIG_SMP */
00051 #define splnone()   rthal_sti()
00052 #define spltest()   rthal_local_irq_test()
00053 #define splget(x)   rthal_local_irq_flags(x)
00054 #define splsync(x)  rthal_local_irq_sync(x)
00055 
00056 typedef struct {
00057 
00058     volatile unsigned long lock;
00059 #ifdef CONFIG_RTAI_OPT_DEBUG
00060     const char *file;
00061     const char *function;
00062     unsigned line;
00063     int cpu;
00064 #endif /* CONFIG_RTAI_OPT_DEBUG */
00065 } xnlock_t;
00066 
00067 #ifndef CONFIG_RTAI_OPT_DEBUG
00068 #define XNARCH_LOCK_UNLOCKED (xnlock_t) { 0 }
00069 #else
00070 #define XNARCH_LOCK_UNLOCKED (xnlock_t) {       \
00071         0,                                      \
00072         NULL,                                   \
00073         0,                                      \
00074         -1                                      \
00075         }
00076 #endif /* !CONFIG_RTAI_OPT_DEBUG */
00077 
00078 #ifdef CONFIG_SMP
00079 
00080 #ifndef CONFIG_RTAI_OPT_DEBUG
00081 #define xnlock_get_irqsave(lock,x)  ((x) = __xnlock_get_irqsave(lock))
00082 #else /* !CONFIG_RTAI_OPT_DEBUG */
00083 #define xnlock_get_irqsave(lock,x) \
00084     ((x) = __xnlock_get_irqsave(lock, __FILE__, __LINE__,__FUNCTION__))
00085 #endif /* CONFIG_RTAI_OPT_DEBUG */
00086 #define xnlock_clear_irqoff(lock)   xnlock_put_irqrestore(lock,1)
00087 #define xnlock_clear_irqon(lock)    xnlock_put_irqrestore(lock,0)
00088 
00089 static inline void xnlock_init (xnlock_t *lock) {
00090 
00091     *lock = XNARCH_LOCK_UNLOCKED;
00092 }
00093 
00094 #ifdef CONFIG_RTAI_OPT_DEBUG
00095 #define XNARCH_DEBUG_SPIN_LIMIT 3000000
00096 
00097 static inline spl_t
00098 __xnlock_get_irqsave (xnlock_t *lock, const char *file, unsigned line, const char *function)
00099 {
00100     unsigned spin_count = 0;
00101 #else /* !CONFIG_RTAI_OPT_DEBUG */
00102 static inline spl_t __xnlock_get_irqsave (xnlock_t *lock)
00103 {
00104 #endif /* CONFIG_RTAI_OPT_DEBUG */
00105     adeos_declare_cpuid;
00106     unsigned long flags;
00107 
00108     rthal_local_irq_save(flags);
00109 
00110     adeos_load_cpuid();
00111 
00112     if (!test_and_set_bit(cpuid,&lock->lock))
00113         {
00114         while (test_and_set_bit(BITS_PER_LONG - 1,&lock->lock))
00115             /* Use an non-locking test in the inner loop, as Linux'es
00116                bit_spin_lock. */
00117             while (test_bit(BITS_PER_LONG - 1,&lock->lock))
00118                 {
00119                 cpu_relax();
00120 
00121 #ifdef CONFIG_RTAI_OPT_DEBUG
00122                 if (++spin_count == XNARCH_DEBUG_SPIN_LIMIT)
00123                     {
00124                     adeos_set_printk_sync(adp_current);
00125                     printk(KERN_ERR
00126                            "RTAI: stuck on nucleus lock %p\n"
00127                            "      waiter = %s:%u (%s(), CPU #%d)\n"
00128                            "      owner  = %s:%u (%s(), CPU #%d)\n",
00129                            lock,file,line,function,cpuid,
00130                            lock->file,lock->line,lock->function,lock->cpu);
00131                     show_stack(NULL,NULL);
00132                     for (;;)
00133                         cpu_relax();
00134                     }
00135 #endif /* CONFIG_RTAI_OPT_DEBUG */
00136                 }
00137 
00138 #ifdef CONFIG_RTAI_OPT_DEBUG
00139         lock->file = file;
00140         lock->function = function;
00141         lock->line = line;
00142         lock->cpu = cpuid;
00143 #endif /* CONFIG_RTAI_OPT_DEBUG */
00144         }
00145     else
00146         flags |= 2;
00147 
00148     return flags;
00149 }
00150 
00151 static inline void xnlock_put_irqrestore (xnlock_t *lock, spl_t flags)
00152 
00153 {
00154     if (!(flags & 2))
00155         {
00156         adeos_declare_cpuid;
00157 
00158         rthal_cli();
00159 
00160         adeos_load_cpuid();
00161 
00162         if (test_and_clear_bit(cpuid,&lock->lock))
00163             clear_bit(BITS_PER_LONG - 1,&lock->lock);
00164         }
00165 
00166     rthal_local_irq_restore(flags & 1);
00167 }
00168 
00169 #else /* !CONFIG_SMP */
00170 
00171 #define xnlock_init(lock)              do { } while(0)
00172 #define xnlock_get_irqsave(lock,x)     rthal_local_irq_save(x)
00173 #define xnlock_put_irqrestore(lock,x)  rthal_local_irq_restore(x)
00174 #define xnlock_clear_irqoff(lock)      rthal_cli()
00175 #define xnlock_clear_irqon(lock)       rthal_sti()
00176 
00177 #endif /* CONFIG_SMP */
00178 
00179 #define XNARCH_NR_CPUS               RTHAL_NR_CPUS
00180 
00181 #define XNARCH_ROOT_STACKSZ   0 /* Only a placeholder -- no stack */
00182 
00183 #define XNARCH_PROMPT "RTAI: "
00184 #define xnarch_loginfo(fmt,args...)  printk(KERN_INFO XNARCH_PROMPT fmt , ##args)
00185 #define xnarch_logwarn(fmt,args...)  printk(KERN_WARNING XNARCH_PROMPT fmt , ##args)
00186 #define xnarch_logerr(fmt,args...)   printk(KERN_ERR XNARCH_PROMPT fmt , ##args)
00187 #define xnarch_printf(fmt,args...)   printk(KERN_INFO XNARCH_PROMPT fmt , ##args)
00188 
00189 #define xnarch_ullmod(ull,uld,rem)   ({ xnarch_ulldiv(ull,uld,rem); (*rem); })
00190 #define xnarch_uldiv(ull, d)         rthal_uldivrem(ull, d, NULL)
00191 #define xnarch_ulmod(ull, d)         ({ u_long _rem;                    \
00192                                         rthal_uldivrem(ull,d,&_rem); _rem; })
00193 
00194 #define xnarch_ullmul                rthal_ullmul
00195 #define xnarch_uldivrem              rthal_uldivrem
00196 #define xnarch_ulldiv                rthal_ulldiv
00197 #define xnarch_imuldiv               rthal_imuldiv
00198 #define xnarch_llimd                 rthal_llimd
00199 #define xnarch_get_cpu_tsc           rthal_rdtsc
00200 
00201 typedef cpumask_t xnarch_cpumask_t;
00202 #ifdef CONFIG_SMP
00203 #define xnarch_cpu_online_map            cpu_online_map
00204 #else
00205 #define xnarch_cpu_online_map            cpumask_of_cpu(0)
00206 #endif
00207 #define xnarch_num_online_cpus()         num_online_cpus()
00208 #define xnarch_cpu_set(cpu, mask)        cpu_set(cpu, mask)
00209 #define xnarch_cpu_clear(cpu, mask)      cpu_clear(cpu, mask)
00210 #define xnarch_cpus_clear(mask)          cpus_clear(mask)
00211 #define xnarch_cpu_isset(cpu, mask)      cpu_isset(cpu, mask)
00212 #define xnarch_cpus_and(dst, src1, src2) cpus_and(dst, src1, src2)
00213 #define xnarch_cpus_equal(mask1, mask2)  cpus_equal(mask1, mask2)
00214 #define xnarch_cpus_empty(mask)          cpus_empty(mask)
00215 #define xnarch_cpumask_of_cpu(cpu)       cpumask_of_cpu(cpu)
00216 #define xnarch_first_cpu(mask)           first_cpu(mask)
00217 #define XNARCH_CPU_MASK_ALL              CPU_MASK_ALL
00218 
00219 typedef struct xnarch_heapcb {
00220 
00221     atomic_t numaps;    /* # of active user-space mappings. */
00222 
00223     int kmflags;        /* Kernel memory flags (0 if vmalloc()). */
00224 
00225     void *heapbase;     /* Shared heap memory base. */
00226 
00227 } xnarch_heapcb_t;
00228 
00229 #ifdef __cplusplus
00230 extern "C" {
00231 #endif
00232 
00233 static inline long long xnarch_tsc_to_ns (long long ts) {
00234     return xnarch_llimd(ts,1000000000,RTHAL_CPU_FREQ);
00235 }
00236 
00237 static inline long long xnarch_ns_to_tsc (long long ns) {
00238     return xnarch_llimd(ns,RTHAL_CPU_FREQ,1000000000);
00239 }
00240 
00241 static inline unsigned long long xnarch_get_cpu_time (void) {
00242     return xnarch_tsc_to_ns(xnarch_get_cpu_tsc());
00243 }
00244 
00245 static inline unsigned long long xnarch_get_cpu_freq (void) {
00246     return RTHAL_CPU_FREQ;
00247 }
00248 
00249 static inline unsigned xnarch_current_cpu (void) {
00250     return adeos_processor_id();
00251 }
00252 
00253 #define xnarch_declare_cpuid  adeos_declare_cpuid
00254 #define xnarch_get_cpu(flags) adeos_get_cpu(flags)
00255 #define xnarch_put_cpu(flags) adeos_put_cpu(flags)
00256 
00257 #define xnarch_halt(emsg) \
00258 do { \
00259     adeos_set_printk_sync(adp_current); \
00260     xnarch_logerr("fatal: %s\n",emsg); \
00261     show_stack(NULL,NULL);                      \
00262     for (;;) cpu_relax();                       \
00263 } while(0)
00264 
00265 static inline int xnarch_setimask (int imask)
00266 
00267 {
00268     spl_t s;
00269     splhigh(s);
00270     splexit(!!imask);
00271     return !!s;
00272 }
00273 
00274 #ifdef XENO_INTR_MODULE
00275 
00276 static inline int xnarch_hook_irq (unsigned irq,
00277                                    void (*handler)(unsigned irq,
00278                                                    void *cookie),
00279                                    void *cookie)
00280 {
00281     return rthal_irq_request(irq,handler,cookie);
00282 }
00283 
00284 static inline int xnarch_release_irq (unsigned irq)
00285 
00286 {
00287     return rthal_irq_release(irq);
00288 }
00289 
00290 static inline int xnarch_enable_irq (unsigned irq)
00291 
00292 {
00293     return rthal_irq_enable(irq);
00294 }
00295 
00296 static inline int xnarch_disable_irq (unsigned irq)
00297 
00298 {
00299     return rthal_irq_disable(irq);
00300 }
00301 
00302 static inline void xnarch_chain_irq (unsigned irq)
00303 
00304 {
00305     rthal_irq_host_pend(irq);
00306 }
00307 
00308 static inline cpumask_t xnarch_set_irq_affinity (unsigned irq,
00309                                                  xnarch_cpumask_t affinity)
00310 {
00311     return adeos_set_irq_affinity(irq,affinity);
00312 }
00313 
00314 #endif /* XENO_INTR_MODULE */
00315 
00316 #ifdef XENO_HEAP_MODULE
00317 
00318 #include <linux/mm.h>
00319 
00320 static inline void xnarch_init_heapcb (xnarch_heapcb_t *hcb)
00321 
00322 {
00323     atomic_set(&hcb->numaps,0);
00324     hcb->kmflags = 0;
00325     hcb->heapbase = NULL;
00326 }
00327 
00328 static inline int xnarch_remap_page_range(struct vm_area_struct *vma,
00329                                           unsigned long uvaddr,
00330                                           unsigned long paddr,
00331                                           unsigned long size,
00332                                           pgprot_t prot)
00333 {
00334 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
00335     return remap_pfn_range(vma,uvaddr,paddr >> PAGE_SHIFT,size,prot);
00336 #else /* Linux version < 2.6.10 */
00337     return remap_page_range(vma,uvaddr,paddr,size,prot);
00338 #endif /* Linux version >= 2.6.10 */
00339 }
00340 
00341 #endif /* XENO_HEAP_MODULE */
00342 
00343 #ifdef __cplusplus
00344 }
00345 #endif
00346 
00347 /* Dashboard and graph control. */
00348 #define XNARCH_DECL_DISPLAY_CONTEXT();
00349 #define xnarch_init_display_context(obj)
00350 #define xnarch_create_display(obj,name,tag)
00351 #define xnarch_delete_display(obj)
00352 #define xnarch_post_graph(obj,state)
00353 #define xnarch_post_graph_if(obj,state,cond)
00354 
00355 #else /* !__KERNEL__ */
00356 
00357 #include <nucleus/system.h>
00358 
00359 #endif /* __KERNEL__ */
00360 
00361 #endif /* !_RTAI_ASM_GENERIC_SYSTEM_H */

Generated on Wed Jun 22 22:54:02 2005 for RTAI Fusion API by  doxygen 1.4.1