system.h

00001 /*
00002  * Copyright (C) 2001,2002,2003 Philippe Gerum <rpm@xenomai.org>.
00003  *
00004  * RTAI/fusion is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published
00006  * by the Free Software Foundation; either version 2 of the License,
00007  * or (at your option) any later version.
00008  *
00009  * RTAI/fusion is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with RTAI/fusion; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00017  * 02111-1307, USA.
00018  */
00019 
00020 #ifndef _RTAI_ASM_UVM_SYSTEM_H
00021 #define _RTAI_ASM_UVM_SYSTEM_H
00022 
00023 #include <sys/time.h>
00024 #include <sys/mman.h>
00025 #include <errno.h>
00026 #include <malloc.h>
00027 #include <stdlib.h>
00028 #include <unistd.h>
00029 #include <string.h>
00030 #include <signal.h>
00031 #include <stdio.h>
00032 #include <limits.h>
00033 #include <setjmp.h>
00034 #include <pthread.h>
00035 #include <rtai_config.h>
00036 #include <nucleus/asm/atomic.h>
00037 #include <nucleus/asm/syscall.h>
00038 #include <uvm/uvm.h>
00039 
00040 /* Module arg macros */
00041 #define vartype(var)               var ## _ ## tYpE
00042 #define MODULE_DESCRIPTION(s);
00043 #define MODULE_LICENSE(s);
00044 #define MODULE_AUTHOR(s);
00045 #define MODULE_PARM_DESC(name,desc);
00046 #define module_param_named(name,var,type,perm)  static const char *vartype(var) = #type
00047 #define module_param_value(var)   ({ xnarch_read_environ(#var,&vartype(var),&var); var; })
00048 
00049 /* Nullify other kernel macros */
00050 #define EXPORT_SYMBOL(sym);
00051 #define module_init(sym);
00052 #define module_exit(sym);
00053 #define __init
00054 #define __exit
00055 
00056 typedef int spl_t;
00057 
00058 typedef unsigned long cpumask_t;
00059 
00060 #ifdef CONFIG_SMP
00061 #error "UVM over SMP not supported yet -- CONFIG_RTAI_OPT_UVM needs to be switched off"
00062 #endif /* CONFIG_SMP */
00063 
00064 extern int uvm_irqlock;
00065 
00066 #define splhigh(x)    ((x) = xnarch_lock_irq())
00067 #define splexit(x)    xnarch_unlock_irq(x)
00068 #define splnone()     xnarch_unlock_irq(0)
00069 
00070 typedef unsigned long xnlock_t;
00071 
00072 #define XNARCH_LOCK_UNLOCKED 0
00073 
00074 #define xnlock_init(lock)              do { } while(0)
00075 #define xnlock_get_irqsave(lock,x)     ((x) = xnarch_lock_irq())
00076 #define xnlock_put_irqrestore(lock,x)  xnarch_unlock_irq(x)
00077 #define xnlock_clear_irqoff(lock)      xnarch_lock_irq()
00078 #define xnlock_clear_irqon(lock)       xnarch_unlock_irq(0)
00079 
00080 #define XNARCH_NR_CPUS             1
00081 
00082 #define XNARCH_DEFAULT_TICK        1000000 /* ns, i.e. 1ms */
00083 #define XNARCH_SIG_RESTART         SIGUSR1
00084 #define XNARCH_HOST_TICK           0    /* No host ticking service */
00085 
00086 #define XNARCH_THREAD_STACKSZ 0 /* Use the default POSIX value. */
00087 #define XNARCH_ROOT_STACKSZ   0 /* Only a placeholder -- no stack */
00088 
00089 #define xnarch_alloc_stack xnmalloc
00090 #define xnarch_free_stack  xnfree
00091 
00092 #define XNARCH_PROMPT "RTAI/uvm: "
00093 #define xnarch_loginfo(fmt,args...)  fprintf(stdout, XNARCH_PROMPT fmt , ##args)
00094 #define xnarch_logwarn(fmt,args...)  fprintf(stderr, XNARCH_PROMPT fmt , ##args)
00095 #define xnarch_logerr(fmt,args...)   fprintf(stderr, XNARCH_PROMPT fmt , ##args)
00096 #define xnarch_printf(fmt,args...)   fprintf(stdout, fmt, ##args)
00097 #define printk(fmt,args...)          xnarch_loginfo(fmt, ##args)
00098 
00099 typedef unsigned long xnarch_cpumask_t;
00100 #define xnarch_num_online_cpus()         XNARCH_NR_CPUS
00101 #define xnarch_cpu_online_map            ((1<<xnarch_num_online_cpus()) - 1)
00102 #define xnarch_cpu_set(cpu, mask)        ((mask) |= 1 << (cpu))
00103 #define xnarch_cpu_clear(cpu, mask)      ((mask) &= 1 << (cpu))
00104 #define xnarch_cpus_clear(mask)          ((mask) = 0UL)
00105 #define xnarch_cpu_isset(cpu, mask)      (!!((mask) & (1 << (cpu))))
00106 #define xnarch_cpus_and(dst, src1, src2) ((dst) = (src1) & (src2))
00107 #define xnarch_cpus_equal(mask1, mask2)  ((mask1) == (mask2))
00108 #define xnarch_cpus_empty(mask)          ((mask) == 0UL)
00109 #define xnarch_cpumask_of_cpu(cpu)       (1 << (cpu)) 
00110 #define xnarch_first_cpu(mask)           (ffnz(mask))
00111 #define XNARCH_CPU_MASK_ALL              (~0UL)
00112 
00113 #define xnarch_ullmod(ull,uld,rem)   ((*rem) = ((ull) % (uld)))
00114 #define xnarch_uldivrem(ull,uld,rem) ((u_long)xnarch_ulldiv((ull),(uld),(rem)))
00115 #define xnarch_uldiv(ull, d)         xnarch_uldivrem(ull, d, NULL)
00116 #define xnarch_ulmod(ull, d)         ({ u_long _rem;                    \
00117                                         xnarch_uldivrem(ull,d,&_rem); _rem; })
00118 
00119 static inline int xnarch_imuldiv(int i, int mult, int div)
00120 {
00121     unsigned long long ull = (unsigned long long) (unsigned) i * (unsigned) mult;
00122     return ull / (unsigned) div;
00123 }
00124 
00125 static inline unsigned long long __xnarch_ullimd(unsigned long long ull,
00126                                                  u_long m,
00127                                                  u_long d) {
00128 
00129     unsigned long long mh, ml;
00130     u_long h, l, mlh, mll, qh, r, ql;
00131 
00132     h = ull >> 32; l = ull & 0xffffffff; /* Split ull. */
00133     mh = (unsigned long long) h * m;
00134     ml = (unsigned long long) l * m;
00135     mlh = ml >> 32; mll = ml & 0xffffffff; /* Split ml. */
00136     mh += mlh;
00137     qh = mh / d;
00138     r = mh % d;
00139     ml = (((unsigned long long) r) << 32) + mll; /* assemble r and mll */
00140     ql = ml / d;
00141 
00142     return (((unsigned long long) qh) << 32) + ql;
00143 }
00144 
00145 static inline long long xnarch_llimd(long long ll, u_long m, u_long d) {
00146     if(ll < 0)
00147         return -__xnarch_ullimd(-ll, m, d);
00148     return __xnarch_ullimd(ll, m, d);
00149 }
00150 
00151 static inline unsigned long long xnarch_ullmul(unsigned long m1,
00152                                                unsigned long m2) {
00153     return (unsigned long long) m1 * m2;
00154 }
00155 
00156 static inline unsigned long long xnarch_ulldiv (unsigned long long ull,
00157                                                 unsigned long uld,
00158                                                 unsigned long *rem)
00159 {
00160     if (rem)
00161         *rem = ull % uld;
00162 
00163     return ull / uld;
00164 }
00165 
00166 #define xnarch_stack_size(tcb)     ((tcb)->stacksize)
00167 #define xnarch_fpu_ptr(tcb)        (NULL)
00168 
00169 struct xnthread;
00170 
00171 typedef struct xnarchtcb {      /* Per-thread arch-dependent block */
00172 
00173     const char *name;           /* Symbolic name of thread (can be NULL) */
00174     struct xnthread *thread;    /* VM thread pointer (opaque) */
00175     void *khandle;              /* Kernel handle (opaque) */
00176     void (*entry)(void *);      /* Thread entry */
00177     void *cookie;               /* Thread cookie passed on entry */
00178     int imask;                  /* Initial interrupt mask */
00179     jmp_buf rstenv;             /* Restart context info */
00180     pthread_t thid;
00181     xncompletion_t completion;
00182 
00183     /* The following fields are not used by the Fusion skin, however
00184        they are set by the nucleus. */
00185     unsigned stacksize;         /* Aligned size of stack (bytes) */
00186     unsigned long *stackbase;   /* Stack space */
00187 
00188 } xnarchtcb_t;
00189 
00190 extern xnarchtcb_t *uvm_root;
00191 
00192 extern xnarchtcb_t *uvm_current;
00193 
00194 typedef void *xnarch_fltinfo_t; /* Unused but required */
00195 
00196 #define xnarch_fault_trap(fi)   0
00197 #define xnarch_fault_code(fi)   0
00198 #define xnarch_fault_pc(fi)     0L
00199 #define xnarch_fault_notify(fi) 1
00200 
00201 typedef struct xnarch_heapcb {
00202 
00203 #if (__GNUC__ <= 2)
00204     int old_gcc_dislikes_emptiness;
00205 #endif
00206 
00207 } xnarch_heapcb_t;
00208 
00209 static inline void xnarch_init_heapcb (xnarch_heapcb_t *cb) {
00210 }
00211 
00212 static inline int __attribute__ ((unused))
00213 xnarch_read_environ (const char *name, const char **ptype, void *pvar)
00214 
00215 {
00216     char *value;
00217 
00218     if (*ptype == NULL)
00219         return 0;       /* Already read in */
00220 
00221     value = getenv(name);
00222 
00223     if (!value)
00224         return -1;
00225 
00226     if (**ptype == 's')
00227         *((char **)pvar) = value;
00228     else if (strstr(*ptype,"int"))
00229         *((int *)pvar) = atoi(value);
00230     else if (strstr(*ptype,"long"))
00231         *((u_long *)pvar) = (u_long)atol(value);
00232 
00233     *ptype = NULL;
00234 
00235     return 1;
00236 }
00237 
00238 static int inline xnarch_lock_irq (void)
00239 {
00240     return xnarch_atomic_xchg(&uvm_irqlock,1);
00241 }
00242 
00243 static inline void xnarch_unlock_irq (int x)
00244 {
00245     extern int uvm_irqpend;
00246 
00247     if (!x && uvm_irqlock)
00248         {
00249         if (xnarch_atomic_xchg(&uvm_irqpend,0))
00250             uvm_thread_release(&uvm_irqlock);
00251         else
00252             uvm_irqlock = 0;
00253         }
00254 }
00255 
00256 void xnarch_sync_irq(void);
00257 
00258 int xnarch_setimask(int imask);
00259 
00260 #ifdef __cplusplus
00261 extern "C" {
00262 #endif
00263 
00264 void xnpod_welcome_thread(struct xnthread *);
00265 
00266 #ifdef XENO_INTR_MODULE
00267 
00268 int uvm_irqlock = 0;    /* =1 whenever IRQs are off. */
00269 
00270 int uvm_irqpend = 0;    /* =1 whenever IRQs are pending. */
00271 
00272 void xnarch_sync_irq (void) /* Synchronization point for IRQ servers. */
00273 
00274 {
00275     if (uvm_irqlock)
00276         /* IRQs are off. Set the IRQ pending flag and go to sleep,
00277            waiting for the IRQs to be unmasked. */
00278         uvm_thread_hold(&uvm_irqpend);
00279 }
00280 
00281 static inline int xnarch_hook_irq (unsigned irq,
00282                                    void (*handler)(unsigned irq,
00283                                                    void *cookie),
00284                                    void *cookie)
00285 {
00286     return -ENOSYS;
00287 }
00288 
00289 static inline int xnarch_release_irq (unsigned irq)
00290 
00291 {
00292     return -ENOSYS;
00293 }
00294 
00295 static inline int xnarch_enable_irq (unsigned irq)
00296 
00297 {
00298     return -ENOSYS;
00299 }
00300 
00301 static inline int xnarch_disable_irq (unsigned irq)
00302 
00303 {
00304     return -ENOSYS;
00305 }
00306 
00307 static inline void xnarch_chain_irq (unsigned irq)
00308 
00309 { /* Nop */ }
00310 
00311 static inline unsigned long xnarch_set_irq_affinity (unsigned irq,
00312                                                      unsigned long affinity)
00313 {
00314     return 0;
00315 }
00316 
00317 #define xnarch_relay_tick()  /* Nullified. */
00318 
00319 #endif /* XENO_INTR_MODULE */
00320 
00321 #ifdef XENO_MAIN_MODULE
00322 
00323 int __fusion_sys_init(void);
00324 
00325 void __fusion_sys_exit(void);
00326 
00327 int __fusion_skin_init(void);
00328 
00329 void __fusion_skin_exit(void);
00330 
00331 int __fusion_user_init(void);
00332 
00333 void __fusion_user_exit(void);
00334 
00335 static inline int xnarch_init (void) {
00336     return 0;
00337 }
00338 
00339 static inline void xnarch_exit (void) {
00340 }
00341 
00342 static void xnarch_restart_handler (int sig) {
00343 
00344     longjmp(uvm_current->rstenv,1);
00345 }
00346 
00347 int main (int argc, char *argv[])
00348 
00349 {
00350     struct sigaction sa;
00351     int err;
00352 
00353     if (geteuid() !=0)
00354         {
00355         fprintf(stderr,"This program must be run with root privileges.\n");
00356         exit(1);
00357         }
00358 
00359     err = __fusion_sys_init();
00360 
00361     if (err)
00362         {
00363         fprintf(stderr,"sys_init() failed: %s\n",strerror(-err));
00364         exit(2);
00365         }
00366 
00367     err = __fusion_skin_init();
00368 
00369     if (err)
00370         {
00371         fprintf(stderr,"skin_init() failed: %s\n",strerror(-err));
00372         exit(3);
00373         }
00374 
00375     err = __fusion_user_init();
00376 
00377     if (err)
00378         {
00379         fprintf(stderr,"user_init() failed: %s\n",strerror(-err));
00380         exit(4);
00381         }
00382 
00383     /* Lock all the memory space which has been allocated from the
00384        user initialization code. We leave MCL_FUTURE in the hands of
00385        the user, since use of mapped I/O memory might require
00386        decoupling the locking operations as follows:
00387        mlockall(MCL_CURRENT) + mmap() + mlockall(MCL_FUTURE). */
00388     mlockall(MCL_CURRENT);
00389 
00390     sa.sa_handler = &xnarch_restart_handler;
00391     sigemptyset(&sa.sa_mask);
00392     sa.sa_flags = SA_RESTART;
00393     sigaction(XNARCH_SIG_RESTART,&sa,NULL);
00394 
00395     for (;;)
00396         uvm_thread_idle(&uvm_irqlock);
00397 
00398     __fusion_user_exit();
00399     __fusion_skin_exit();
00400     __fusion_sys_exit();
00401 
00402     exit(0);
00403 }
00404 
00405 #endif  /* !XENO_MAIN_MODULE */
00406 
00407 #ifdef XENO_TIMER_MODULE
00408 
00409 void *uvm_timer_handle;
00410 
00411 static inline void xnarch_program_timer_shot (unsigned long delay) {
00412     /* Empty -- not available */
00413 }
00414 
00415 static inline void xnarch_stop_timer (void) {
00416     uvm_thread_cancel(uvm_timer_handle,NULL);
00417 }
00418 
00419 static inline int xnarch_send_timer_ipi (xnarch_cpumask_t mask) {
00420 
00421     return 0;
00422 }
00423 
00424 static inline void xnarch_read_timings (unsigned long long *shot,
00425                                         unsigned long long *delivery,
00426                                         unsigned long long defval)
00427 {
00428     *shot = defval;
00429     *delivery = defval;
00430 }
00431 
00432 #endif /* XENO_TIMER_MODULE */
00433 
00434 #ifdef XENO_POD_MODULE
00435 
00436 extern void *uvm_timer_handle;
00437 
00438 xnsysinfo_t uvm_info;
00439 
00440 xnarchtcb_t *uvm_root;
00441 
00442 xnarchtcb_t *uvm_current;
00443 
00444 struct xnarch_tick_parms {
00445     unsigned long nstick;
00446     void (*tickhandler)(void);
00447     xncompletion_t completion;
00448 };
00449 
00450 /*
00451  * NOTE: System-level shadow priorities underlying the UVM threads are
00452  * defined as follows:
00453  *
00454  * - uvm-root = prio_min(SCHED_FIFO)
00455  * - uvm-<user> = prio_min(SCHED_FIFO) + 1
00456  * - uvm-timer = prio_min(SCHED_FIFO) + 2
00457  */
00458 
00459 static void *xnarch_timer_thread (void *cookie)
00460 
00461 {
00462     struct xnarch_tick_parms *p = (struct xnarch_tick_parms *)cookie;
00463     void (*tickhandler)(void);
00464     struct sched_param param;
00465     unsigned long nstick;
00466     long err;
00467 
00468     param.sched_priority = sched_get_priority_min(SCHED_FIFO) + 2;
00469     sched_setscheduler(0,SCHED_FIFO,&param);
00470 
00471     /* Copy the following values laid into our parent's stack before
00472        it is unblocked from the completion by uvm_thread_create(). */
00473     tickhandler = p->tickhandler;
00474     nstick = p->nstick;
00475 
00476     uvm_thread_create("uvm-timer",NULL,&p->completion,&uvm_timer_handle);
00477 
00478     err = uvm_thread_barrier(); /* Wait for start. */
00479 
00480     if (!err)
00481         err = uvm_thread_set_periodic(0,nstick);
00482 
00483     if (err)
00484         pthread_exit((void *)err);
00485 
00486     for (;;)
00487         {
00488         if (uvm_thread_wait_period() == -EWOULDBLOCK) /* Timer killed? */
00489             break;
00490 
00491         xnarch_sync_irq();
00492         tickhandler();
00493         }
00494 
00495     pthread_exit(NULL);
00496 }
00497 
00498 static inline int xnarch_start_timer (unsigned long nstick,
00499                                       void (*tickhandler)(void))
00500 {
00501     struct xnarch_tick_parms parms;
00502     pthread_attr_t thattr;
00503     pthread_t thid;
00504     int err;
00505 
00506     if (nstick == 0) /* UVM does not provide oneshot timing. */
00507         return -ENODEV;
00508 
00509     /* However, if oneshot timing is available at system level, use it
00510        so that we can provide a better resolution for virtual machine
00511        ticks. Otherwise, ask for plain periodic mode, hoping that the
00512        period given will be compatible with Linux's own requirements
00513        wrt its jiffy-based timer. */
00514 
00515 #ifdef CONFIG_RTAI_HW_APERIODIC_TIMER
00516     err = uvm_timer_start(0);
00517 #else /* !CONFIG_RTAI_HW_APERIODIC_TIMER */
00518     err = uvm_timer_start(nstick);
00519 #endif /* CONFIG_RTAI_HW_APERIODIC_TIMER */
00520 
00521     if (err)
00522         return err;
00523 
00524     parms.nstick = nstick;
00525     parms.tickhandler = tickhandler;
00526     parms.completion.syncflag = 0;
00527     parms.completion.pid = -1;
00528 
00529     pthread_attr_init(&thattr);
00530     pthread_attr_setdetachstate(&thattr,PTHREAD_CREATE_DETACHED);
00531     pthread_create(&thid,&thattr,&xnarch_timer_thread,&parms);
00532 
00533     err = uvm_thread_sync(&parms.completion);
00534 
00535     if (err == 0)
00536         uvm_thread_start(uvm_timer_handle);
00537 
00538     return err;
00539 }
00540 
00541 static inline void xnarch_leave_root(xnarchtcb_t *rootcb) {
00542 }
00543 
00544 static inline void xnarch_enter_root(xnarchtcb_t *rootcb) {
00545 }
00546 
00547 static inline void xnarch_switch_to (xnarchtcb_t *out_tcb,
00548                                      xnarchtcb_t *in_tcb)
00549 {
00550     uvm_current = in_tcb;
00551     uvm_thread_activate(in_tcb->khandle,out_tcb->khandle);
00552 }
00553 
00554 static inline void xnarch_finalize_and_switch (xnarchtcb_t *dead_tcb,
00555                                                xnarchtcb_t *next_tcb)
00556 {
00557     uvm_current = next_tcb;
00558     uvm_thread_cancel(dead_tcb->khandle,next_tcb->khandle);
00559 }
00560 
00561 static inline void xnarch_finalize_no_switch (xnarchtcb_t *dead_tcb)
00562 
00563 {
00564     uvm_thread_cancel(dead_tcb->khandle,NULL);
00565 }
00566 
00567 static inline void xnarch_init_root_tcb (xnarchtcb_t *tcb,
00568                                          struct xnthread *thread,
00569                                          const char *name)
00570 {
00571     struct sched_param param;
00572     int err;
00573 
00574     param.sched_priority = sched_get_priority_min(SCHED_FIFO);
00575     sched_setscheduler(0,SCHED_FIFO,&param);
00576     err = uvm_system_info(&uvm_info);
00577 
00578     if (err)
00579         {
00580         fprintf(stderr,"UVM init failed: %s\n",strerror(-err));
00581         exit(1);
00582         }
00583 
00584     uvm_thread_shadow("uvm-root",tcb,&tcb->khandle);
00585     tcb->name = name;
00586     uvm_root = uvm_current = tcb;
00587 }
00588 
00589 static void *xnarch_thread_trampoline (void *cookie)
00590 
00591 {
00592     xnarchtcb_t *tcb = (xnarchtcb_t *)cookie;
00593     struct sched_param param;
00594     long err;
00595 
00596     if (!setjmp(tcb->rstenv))
00597         {
00598         param.sched_priority = sched_get_priority_min(SCHED_FIFO) + 1;
00599         sched_setscheduler(0,SCHED_FIFO,&param);
00600         uvm_thread_create(tcb->name,tcb,&tcb->completion,&tcb->khandle);
00601         err = uvm_thread_barrier();     /* Wait for start. */
00602         if (err)
00603             pthread_exit((void *)err);
00604         }
00605 
00606     xnarch_setimask(tcb->imask);
00607 
00608     xnpod_welcome_thread(tcb->thread);
00609 
00610     tcb->entry(tcb->cookie);
00611 
00612     pthread_exit(NULL);
00613 }
00614 
00615 static inline void xnarch_init_thread (xnarchtcb_t *tcb,
00616                                        void (*entry)(void *),
00617                                        void *cookie,
00618                                        int imask,
00619                                        struct xnthread *thread,
00620                                        char *name)
00621 {
00622     pthread_attr_t thattr;
00623 
00624     if (tcb->khandle)   /* Restarting thread */
00625         {
00626         pthread_kill(tcb->thid,XNARCH_SIG_RESTART);
00627         return;
00628         }
00629 
00630     tcb->imask = imask;
00631     tcb->entry = entry;
00632     tcb->cookie = cookie;
00633     tcb->thread = thread;
00634     tcb->name = name;
00635     tcb->completion.syncflag = 0;
00636     tcb->completion.pid = -1;
00637 
00638     pthread_attr_init(&thattr);
00639     pthread_attr_setdetachstate(&thattr,PTHREAD_CREATE_DETACHED);
00640     pthread_create(&tcb->thid,&thattr,&xnarch_thread_trampoline,tcb);
00641     uvm_thread_sync(&tcb->completion);
00642 }
00643 
00644 static inline void xnarch_enable_fpu(xnarchtcb_t *current_tcb) {
00645     /* Handled by the in-kernel nucleus */
00646 }
00647 
00648 static inline void xnarch_init_fpu(xnarchtcb_t *tcb) {
00649     /* Handled by the in-kernel nucleus */
00650 }
00651 
00652 static inline void xnarch_save_fpu(xnarchtcb_t *tcb) {
00653     /* Handled by the in-kernel nucleus */
00654 }
00655 
00656 static inline void xnarch_restore_fpu(xnarchtcb_t *tcb) {
00657     /* Handled by the in-kernel nucleus */
00658 }
00659 
00660 int xnarch_setimask (int imask)
00661 
00662 {
00663     spl_t s;
00664     splhigh(s);
00665     splexit(!!imask);
00666     return !!s;
00667 }
00668 
00669 static inline int xnarch_send_ipi (cpumask_t cpumask) {
00670 
00671     return 0;
00672 }
00673 
00674 static inline int xnarch_hook_ipi (void (*handler)(void)) {
00675 
00676     return 0;
00677 }
00678 
00679 static inline int xnarch_release_ipi (void) {
00680 
00681     return 0;
00682 }
00683 
00684 #define xnarch_notify_ready()  /* Nullified */
00685 #define xnarch_notify_shutdown() /* Nullified */
00686 #define xnarch_notify_halt() /* Nullified */
00687 
00688 #endif /* XENO_POD_MODULE */
00689 
00690 #ifdef XENO_THREAD_MODULE
00691 
00692 static inline void xnarch_init_tcb (xnarchtcb_t *tcb) {
00693 
00694     tcb->khandle = NULL;
00695 }
00696 
00697 #endif /* XENO_THREAD_MODULE */
00698 
00699 extern xnsysinfo_t uvm_info;
00700 
00701 static inline unsigned long long xnarch_tsc_to_ns (unsigned long long tsc) {
00702 
00703     nanostime_t ns;
00704     return uvm_timer_tsc2ns(tsc,&ns) ? 0 : ns;
00705 }
00706 
00707 static inline unsigned long long xnarch_ns_to_tsc (unsigned long long ns) {
00708 
00709     nanostime_t tsc;
00710     return uvm_timer_ns2tsc(ns,&tsc) ? 0 : tsc;
00711 }
00712 
00713 static inline unsigned long long xnarch_get_cpu_time (void)
00714 
00715 {
00716     nanotime_t t;
00717     uvm_timer_read(&t);
00718     return t;
00719 }
00720 
00721 static inline unsigned long long xnarch_get_cpu_tsc (void)
00722 
00723 {
00724     nanotime_t t;
00725     uvm_timer_tsc(&t);
00726     return t;
00727 }
00728 
00729 static inline unsigned long long xnarch_get_cpu_freq (void) {
00730     return uvm_info.cpufreq;
00731 }
00732 
00733 static inline void xnarch_halt (const char *emsg) {
00734     fprintf(stderr,"UVM fatal: %s\n",emsg);
00735     fflush(stderr);
00736     exit(99);
00737 }
00738 
00739 static inline void *xnarch_sysalloc (u_long bytes) {
00740     return malloc(bytes);
00741 }
00742 
00743 static inline void xnarch_sysfree (void *chunk, u_long bytes) {
00744     free(chunk);
00745 }
00746 
00747 #define xnarch_current_cpu()  0
00748 #define xnarch_declare_cpuid  const int cpuid = 0
00749 #define xnarch_get_cpu(x)     do  { (x) = (x); } while(0)
00750 #define xnarch_put_cpu(x)     do { } while(0)
00751 
00752 #define xnarch_alloc_stack xnmalloc
00753 #define xnarch_free_stack  xnfree
00754 
00755 #ifdef __cplusplus
00756 }
00757 #endif
00758 
00759 /* Dashboard and graph control. */
00760 #define XNARCH_DECL_DISPLAY_CONTEXT();
00761 #define xnarch_init_display_context(obj)
00762 #define xnarch_create_display(obj,name,tag)
00763 #define xnarch_delete_display(obj)
00764 #define xnarch_post_graph(obj,state)
00765 #define xnarch_post_graph_if(obj,state,cond)
00766 
00767 #endif /* !_RTAI_ASM_UVM_SYSTEM_H */

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