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 unsigned long 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 #define xnarch_user_task(tcb)     (NULL)
00169 #define xnarch_user_pid(tcb)      0
00170 
00171 struct xnthread;
00172 
00173 typedef struct xnarchtcb {      /* Per-thread arch-dependent block */
00174 
00175     const char *name;           /* Symbolic name of thread (can be NULL) */
00176     struct xnthread *thread;    /* VM thread pointer (opaque) */
00177     void *khandle;              /* Kernel handle (opaque) */
00178     void (*entry)(void *);      /* Thread entry */
00179     void *cookie;               /* Thread cookie passed on entry */
00180     int imask;                  /* Initial interrupt mask */
00181     jmp_buf rstenv;             /* Restart context info */
00182     pthread_t thid;
00183     xncompletion_t completion;
00184 
00185     /* The following fields are not used by the Fusion skin, however
00186        they are set by the nucleus. */
00187     unsigned stacksize;         /* Aligned size of stack (bytes) */
00188     unsigned long *stackbase;   /* Stack space */
00189 
00190 } xnarchtcb_t;
00191 
00192 extern xnarchtcb_t *uvm_root;
00193 
00194 extern xnarchtcb_t *uvm_current;
00195 
00196 typedef void *xnarch_fltinfo_t; /* Unused but required */
00197 
00198 #define xnarch_fault_trap(fi)   0
00199 #define xnarch_fault_code(fi)   0
00200 #define xnarch_fault_pc(fi)     0L
00201 #define xnarch_fault_notify(fi) 1
00202 
00203 typedef struct xnarch_heapcb {
00204 
00205 #if (__GNUC__ <= 2)
00206     int old_gcc_dislikes_emptiness;
00207 #endif
00208 
00209 } xnarch_heapcb_t;
00210 
00211 static inline void xnarch_init_heapcb (xnarch_heapcb_t *cb) {
00212 }
00213 
00214 static inline int __attribute__ ((unused))
00215 xnarch_read_environ (const char *name, const char **ptype, void *pvar)
00216 
00217 {
00218     char *value;
00219 
00220     if (*ptype == NULL)
00221         return 0;       /* Already read in */
00222 
00223     value = getenv(name);
00224 
00225     if (!value)
00226         return -1;
00227 
00228     if (**ptype == 's')
00229         *((char **)pvar) = value;
00230     else if (strstr(*ptype,"int"))
00231         *((int *)pvar) = atoi(value);
00232     else if (strstr(*ptype,"long"))
00233         *((u_long *)pvar) = (u_long)atol(value);
00234 
00235     *ptype = NULL;
00236 
00237     return 1;
00238 }
00239 
00240 static int inline xnarch_lock_irq (void)
00241 {
00242     return xnarch_atomic_xchg(&uvm_irqlock,1);
00243 }
00244 
00245 static inline void xnarch_unlock_irq (int x)
00246 {
00247     extern unsigned long uvm_irqpend;
00248 
00249     if (!x && uvm_irqlock)
00250         {
00251         if (xnarch_atomic_xchg(&uvm_irqpend,0))
00252             uvm_thread_release(&uvm_irqlock);
00253         else
00254             uvm_irqlock = 0;
00255         }
00256 }
00257 
00258 void xnarch_sync_irq(void);
00259 
00260 int xnarch_setimask(int imask);
00261 
00262 #ifdef __cplusplus
00263 extern "C" {
00264 #endif
00265 
00266 void xnpod_welcome_thread(struct xnthread *);
00267 
00268 #ifdef XENO_INTR_MODULE
00269 
00270 unsigned long uvm_irqlock = 0;  /* =1 whenever IRQs are off. */
00271 
00272 unsigned long uvm_irqpend = 0;  /* =1 whenever IRQs are pending. */
00273 
00274 void xnarch_sync_irq (void) /* Synchronization point for IRQ servers. */
00275 
00276 {
00277     if (uvm_irqlock)
00278         /* IRQs are off. Set the IRQ pending flag and go to sleep,
00279            waiting for the IRQs to be unmasked. */
00280         uvm_thread_hold(&uvm_irqpend);
00281 }
00282 
00283 static inline int xnarch_hook_irq (unsigned irq,
00284                                    void (*handler)(unsigned irq,
00285                                                    void *cookie),
00286                                    int (*ackfn)(unsigned irq),
00287                                    void *cookie)
00288 {
00289     return -ENOSYS;
00290 }
00291 
00292 static inline int xnarch_release_irq (unsigned irq)
00293 
00294 {
00295     return -ENOSYS;
00296 }
00297 
00298 static inline int xnarch_enable_irq (unsigned irq)
00299 
00300 {
00301     return -ENOSYS;
00302 }
00303 
00304 static inline int xnarch_disable_irq (unsigned irq)
00305 
00306 {
00307     return -ENOSYS;
00308 }
00309 
00310 static inline void xnarch_chain_irq (unsigned irq)
00311 
00312 { /* Nop */ }
00313 
00314 static inline unsigned long xnarch_set_irq_affinity (unsigned irq,
00315                                                      unsigned long affinity)
00316 {
00317     return 0;
00318 }
00319 
00320 #define xnarch_relay_tick()  /* Nullified. */
00321 
00322 #endif /* XENO_INTR_MODULE */
00323 
00324 #ifdef XENO_MAIN_MODULE
00325 
00326 int __fusion_sys_init(void);
00327 
00328 void __fusion_sys_exit(void);
00329 
00330 int __fusion_skin_init(void);
00331 
00332 void __fusion_skin_exit(void);
00333 
00334 int __fusion_user_init(void);
00335 
00336 void __fusion_user_exit(void);
00337 
00338 static inline int xnarch_init (void) {
00339     return 0;
00340 }
00341 
00342 static inline void xnarch_exit (void) {
00343 }
00344 
00345 static void xnarch_restart_handler (int sig) {
00346 
00347     longjmp(uvm_current->rstenv,1);
00348 }
00349 
00350 int main (int argc, char *argv[])
00351 
00352 {
00353     struct sigaction sa;
00354     int err;
00355 
00356     if (geteuid() != 0)
00357         {
00358         fprintf(stderr,"This program must be run with root privileges.\n");
00359         exit(1);
00360         }
00361 
00362     err = __fusion_sys_init();
00363 
00364     if (err)
00365         {
00366         fprintf(stderr,"sys_init() failed: %s\n",strerror(-err));
00367         exit(2);
00368         }
00369 
00370     err = __fusion_skin_init();
00371 
00372     if (err)
00373         {
00374         fprintf(stderr,"skin_init() failed: %s\n",strerror(-err));
00375         exit(3);
00376         }
00377 
00378     err = __fusion_user_init();
00379 
00380     if (err)
00381         {
00382         fprintf(stderr,"user_init() failed: %s\n",strerror(-err));
00383         exit(4);
00384         }
00385 
00386     mlockall(MCL_CURRENT|MCL_FUTURE);
00387 
00388     sa.sa_handler = &xnarch_restart_handler;
00389     sigemptyset(&sa.sa_mask);
00390     sa.sa_flags = SA_RESTART;
00391     sigaction(XNARCH_SIG_RESTART,&sa,NULL);
00392 
00393     for (;;)
00394         uvm_thread_idle(&uvm_irqlock);
00395 
00396     __fusion_user_exit();
00397     __fusion_skin_exit();
00398     __fusion_sys_exit();
00399 
00400     exit(0);
00401 }
00402 
00403 #endif  /* !XENO_MAIN_MODULE */
00404 
00405 #ifdef XENO_TIMER_MODULE
00406 
00407 void *uvm_timer_handle;
00408 
00409 static inline void xnarch_program_timer_shot (unsigned long delay) {
00410     /* Empty -- not available */
00411 }
00412 
00413 static inline void xnarch_stop_timer (void) {
00414     uvm_thread_cancel(uvm_timer_handle,NULL);
00415 }
00416 
00417 static inline int xnarch_send_timer_ipi (xnarch_cpumask_t mask) {
00418 
00419     return 0;
00420 }
00421 
00422 #endif /* XENO_TIMER_MODULE */
00423 
00424 #ifdef XENO_POD_MODULE
00425 
00426 extern void *uvm_timer_handle;
00427 
00428 xnsysinfo_t uvm_info;
00429 
00430 xnarchtcb_t *uvm_root;
00431 
00432 xnarchtcb_t *uvm_current;
00433 
00434 struct xnarch_tick_parms {
00435     unsigned long nstick;
00436     void (*tickhandler)(void);
00437     xncompletion_t completion;
00438 };
00439 
00440 /*
00441  * NOTE: System-level shadow priorities underlying the UVM threads are
00442  * defined as follows:
00443  *
00444  * - uvm-root = prio_min(SCHED_FIFO)
00445  * - uvm-<user> = prio_min(SCHED_FIFO) + 1
00446  * - uvm-timer = prio_min(SCHED_FIFO) + 2
00447  */
00448 
00449 static void *xnarch_timer_thread (void *cookie)
00450 
00451 {
00452     struct xnarch_tick_parms *p = (struct xnarch_tick_parms *)cookie;
00453     void (*tickhandler)(void);
00454     struct sched_param param;
00455     unsigned long nstick;
00456     long err;
00457 
00458     param.sched_priority = sched_get_priority_min(SCHED_FIFO) + 2;
00459     sched_setscheduler(0,SCHED_FIFO,&param);
00460 
00461     /* Copy the following values laid into our parent's stack before
00462        it is unblocked from the completion by uvm_thread_create(). */
00463     tickhandler = p->tickhandler;
00464     nstick = p->nstick;
00465 
00466     uvm_thread_create("uvm-timer",NULL,&p->completion,&uvm_timer_handle);
00467 
00468     err = uvm_thread_barrier(); /* Wait for start. */
00469 
00470     if (!err)
00471         err = uvm_thread_set_periodic(0,nstick);
00472 
00473     if (err)
00474         pthread_exit((void *)err);
00475 
00476     for (;;)
00477         {
00478         if (uvm_thread_wait_period() == -EWOULDBLOCK) /* Timer killed? */
00479             break;
00480 
00481         xnarch_sync_irq();
00482         tickhandler();
00483         }
00484 
00485     pthread_exit(NULL);
00486 }
00487 
00488 static inline int xnarch_start_timer (unsigned long nstick,
00489                                       void (*tickhandler)(void))
00490 {
00491     struct xnarch_tick_parms parms;
00492     pthread_attr_t thattr;
00493     pthread_t thid;
00494     int err;
00495 
00496     if (nstick == 0) /* UVM does not provide oneshot timing. */
00497         return -ENODEV;
00498 
00499     /* However, if we use the oneshot timing which is always available
00500        at kernel level so that we can provide a better resolution for
00501        virtual machine. */
00502 
00503     err = uvm_timer_start(0);
00504 
00505     if (err)
00506         return err;
00507 
00508     parms.nstick = nstick;
00509     parms.tickhandler = tickhandler;
00510     parms.completion.syncflag = 0;
00511     parms.completion.pid = -1;
00512 
00513     pthread_attr_init(&thattr);
00514     pthread_attr_setdetachstate(&thattr,PTHREAD_CREATE_DETACHED);
00515     pthread_create(&thid,&thattr,&xnarch_timer_thread,&parms);
00516 
00517     err = uvm_thread_sync(&parms.completion);
00518 
00519     if (err == 0)
00520         uvm_thread_start(uvm_timer_handle);
00521 
00522     return err;
00523 }
00524 
00525 static inline void xnarch_leave_root(xnarchtcb_t *rootcb) {
00526 }
00527 
00528 static inline void xnarch_enter_root(xnarchtcb_t *rootcb) {
00529 }
00530 
00531 static inline void xnarch_switch_to (xnarchtcb_t *out_tcb,
00532                                      xnarchtcb_t *in_tcb)
00533 {
00534     uvm_current = in_tcb;
00535     uvm_thread_activate(in_tcb->khandle,out_tcb->khandle);
00536 }
00537 
00538 static inline void xnarch_finalize_and_switch (xnarchtcb_t *dead_tcb,
00539                                                xnarchtcb_t *next_tcb)
00540 {
00541     uvm_current = next_tcb;
00542     uvm_thread_cancel(dead_tcb->khandle,next_tcb->khandle);
00543 }
00544 
00545 static inline void xnarch_finalize_no_switch (xnarchtcb_t *dead_tcb)
00546 
00547 {
00548     uvm_thread_cancel(dead_tcb->khandle,NULL);
00549 }
00550 
00551 static inline void xnarch_init_root_tcb (xnarchtcb_t *tcb,
00552                                          struct xnthread *thread,
00553                                          const char *name)
00554 {
00555     struct sched_param param;
00556     int err;
00557 
00558     param.sched_priority = sched_get_priority_min(SCHED_FIFO);
00559     sched_setscheduler(0,SCHED_FIFO,&param);
00560     err = uvm_system_info(&uvm_info);
00561 
00562     if (err)
00563         {
00564         fprintf(stderr,"UVM init failed: %s\n",strerror(-err));
00565         exit(1);
00566         }
00567 
00568     uvm_thread_shadow("uvm-root",tcb,&tcb->khandle);
00569     tcb->name = name;
00570     uvm_root = uvm_current = tcb;
00571 }
00572 
00573 static void *xnarch_thread_trampoline (void *cookie)
00574 
00575 {
00576     xnarchtcb_t *tcb = (xnarchtcb_t *)cookie;
00577     struct sched_param param;
00578     long err;
00579 
00580     if (!setjmp(tcb->rstenv))
00581         {
00582         param.sched_priority = sched_get_priority_min(SCHED_FIFO) + 1;
00583         sched_setscheduler(0,SCHED_FIFO,&param);
00584         uvm_thread_create(tcb->name,tcb,&tcb->completion,&tcb->khandle);
00585         err = uvm_thread_barrier();     /* Wait for start. */
00586         if (err)
00587             pthread_exit((void *)err);
00588         }
00589 
00590     xnarch_setimask(tcb->imask);
00591 
00592     xnpod_welcome_thread(tcb->thread);
00593 
00594     tcb->entry(tcb->cookie);
00595 
00596     pthread_exit(NULL);
00597 }
00598 
00599 static inline void xnarch_init_thread (xnarchtcb_t *tcb,
00600                                        void (*entry)(void *),
00601                                        void *cookie,
00602                                        int imask,
00603                                        struct xnthread *thread,
00604                                        char *name)
00605 {
00606     pthread_attr_t thattr;
00607 
00608     if (tcb->khandle)   /* Restarting thread */
00609         {
00610         pthread_kill(tcb->thid,XNARCH_SIG_RESTART);
00611         return;
00612         }
00613 
00614     tcb->imask = imask;
00615     tcb->entry = entry;
00616     tcb->cookie = cookie;
00617     tcb->thread = thread;
00618     tcb->name = name;
00619     tcb->completion.syncflag = 0;
00620     tcb->completion.pid = -1;
00621 
00622     pthread_attr_init(&thattr);
00623     pthread_attr_setdetachstate(&thattr,PTHREAD_CREATE_DETACHED);
00624     pthread_create(&tcb->thid,&thattr,&xnarch_thread_trampoline,tcb);
00625     uvm_thread_sync(&tcb->completion);
00626 }
00627 
00628 static inline void xnarch_enable_fpu(xnarchtcb_t *current_tcb) {
00629     /* Handled by the in-kernel nucleus */
00630 }
00631 
00632 static inline void xnarch_init_fpu(xnarchtcb_t *tcb) {
00633     /* Handled by the in-kernel nucleus */
00634 }
00635 
00636 static inline void xnarch_save_fpu(xnarchtcb_t *tcb) {
00637     /* Handled by the in-kernel nucleus */
00638 }
00639 
00640 static inline void xnarch_restore_fpu(xnarchtcb_t *tcb) {
00641     /* Handled by the in-kernel nucleus */
00642 }
00643 
00644 int xnarch_setimask (int imask)
00645 
00646 {
00647     spl_t s;
00648     splhigh(s);
00649     splexit(!!imask);
00650     return !!s;
00651 }
00652 
00653 static inline int xnarch_send_ipi (cpumask_t cpumask) {
00654 
00655     return 0;
00656 }
00657 
00658 static inline int xnarch_hook_ipi (void (*handler)(void)) {
00659 
00660     return 0;
00661 }
00662 
00663 static inline int xnarch_release_ipi (void) {
00664 
00665     return 0;
00666 }
00667 
00668 #define xnarch_notify_ready()  /* Nullified */
00669 #define xnarch_notify_shutdown() /* Nullified */
00670 #define xnarch_notify_halt() /* Nullified */
00671 
00672 static inline unsigned long long xnarch_get_sys_time(void)
00673 {
00674     struct timeval tv;
00675 
00676     if(gettimeofday(&tv, NULL))
00677         {
00678         printf("Warning, gettimeofday failed, error %d\n", errno);
00679         return 0;
00680         }
00681 
00682     return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000;
00683 }
00684 
00685 #endif /* XENO_POD_MODULE */
00686 
00687 #ifdef XENO_THREAD_MODULE
00688 
00689 static inline void xnarch_init_tcb (xnarchtcb_t *tcb) {
00690 
00691     tcb->khandle = NULL;
00692 }
00693 
00694 #endif /* XENO_THREAD_MODULE */
00695 
00696 extern xnsysinfo_t uvm_info;
00697 
00698 static inline unsigned long long xnarch_tsc_to_ns (unsigned long long tsc) {
00699 
00700     nanostime_t ns;
00701     return uvm_timer_tsc2ns(tsc,&ns) ? 0 : ns;
00702 }
00703 
00704 static inline unsigned long long xnarch_ns_to_tsc (unsigned long long ns) {
00705 
00706     nanostime_t tsc;
00707     return uvm_timer_ns2tsc(ns,&tsc) ? 0 : tsc;
00708 }
00709 
00710 static inline unsigned long long xnarch_get_cpu_time (void)
00711 
00712 {
00713     nanotime_t t;
00714     uvm_timer_read(&t);
00715     return t;
00716 }
00717 
00718 static inline unsigned long long xnarch_get_cpu_tsc (void)
00719 
00720 {
00721     nanotime_t t;
00722     uvm_timer_tsc(&t);
00723     return t;
00724 }
00725 
00726 static inline unsigned long long xnarch_get_cpu_freq (void) {
00727     return uvm_info.cpufreq;
00728 }
00729 
00730 static inline void xnarch_halt (const char *emsg) {
00731     fprintf(stderr,"UVM fatal: %s\n",emsg);
00732     fflush(stderr);
00733     exit(99);
00734 }
00735 
00736 static inline void *xnarch_sysalloc (u_long bytes) {
00737     return malloc(bytes);
00738 }
00739 
00740 static inline void xnarch_sysfree (void *chunk, u_long bytes) {
00741     free(chunk);
00742 }
00743 
00744 #define xnarch_current_cpu()  0
00745 #define xnarch_declare_cpuid  const int cpuid = 0
00746 #define xnarch_get_cpu(x)     do  { (x) = (x); } while(0)
00747 #define xnarch_put_cpu(x)     do { } while(0)
00748 
00749 #define xnarch_alloc_stack xnmalloc
00750 #define xnarch_free_stack  xnfree
00751 
00752 #ifdef __cplusplus
00753 }
00754 #endif
00755 
00756 /* Dashboard and graph control. */
00757 #define XNARCH_DECL_DISPLAY_CONTEXT();
00758 #define xnarch_init_display_context(obj)
00759 #define xnarch_create_display(obj,name,tag)
00760 #define xnarch_delete_display(obj)
00761 #define xnarch_post_graph(obj,state)
00762 #define xnarch_post_graph_if(obj,state,cond)
00763 
00764 #endif /* !_RTAI_ASM_UVM_SYSTEM_H */

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