source: soft/giet_vm/giet_common/utils.c @ 293

Last change on this file since 293 was 293, checked in by cfuguet, 10 years ago

Initializing the CP0 CAUSE value on the task contexts to
zero during creation of tasks (boot_scheduler_init). This
is to avoid writing non initialized data on the CAUSE
register when swithing tasks for the first time.

File size: 26.4 KB
Line 
1///////////////////////////////////////////////////////////////////////////////////
2// File     : utils.c
3// Date     : 18/10/2013
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7// The utils.c and utils.h files are part of the GIET-VM nano-kernel.
8// They define more or less the GIET-VM HAL (Hardware Abstraction Layer),
9// and contains various utility functions, that can be used by both the
10// boot code and the kernel code.
11///////////////////////////////////////////////////////////////////////////////////
12
13#include <giet_config.h>
14#include <mapping_info.h>
15#include <utils.h>
16#include <ctx_handler.h>
17#include <tty_driver.h>
18#include <stdarg.h>
19
20// This global variable is allocated in the boot.c file or in kernel_init.c file
21extern static_scheduler_t* _schedulers[NB_PROCS_MAX<<(X_WIDTH+Y_WIDTH)];
22
23///////////////////////////////////////////////////////////////////////////////////
24// This function implements a pseudo-random delay.
25// The val argument define approximately an exponentially increasing mean delay,
26// and should not be larger than 32.
27///////////////////////////////////////////////////////////////////////////////////
28inline void _random_wait( unsigned int val )
29{
30    unsigned int mask  = (1<<(val&0x1F))-1;
31    unsigned int delay = (_get_proctime() ^ (_get_procid()<<4)) & mask;
32    asm volatile( "move  $3,   %0                 \n"
33                  "loop_nic_completed:            \n"
34                  "addi  $3,   $3, -1             \n"
35                  "bnez  $3,   loop_nic_completed \n"
36                  "nop                            \n"
37                  :
38                  : "r" (delay)
39                  : "$3" ); 
40}
41///////////////////////////////////////////////////////////////////////////////////
42// Copy a source memory buffer content to a dest memory buffer (size bytes)
43// Code taken from MutekH.
44///////////////////////////////////////////////////////////////////////////////////
45inline void* _memcpy( void*        dest,     // dest buffer vbase
46                      const void*  source,   // source buffer vbase
47                      unsigned int size )    // bytes
48{
49    unsigned int*       dst = dest;
50    const unsigned int* src = source;
51
52    // word-by-word copy
53    if (!((unsigned int) dst & 3) && !((unsigned int) src & 3)) 
54    {
55        while (size > 3) 
56        {
57            *dst++ = *src++;
58            size -= 4;
59        }
60    }
61
62    unsigned char * cdst = (unsigned char *) dst;
63    unsigned char * csrc = (unsigned char *) src;
64
65    /* byte-by-byte copy */
66    while (size--) 
67    {
68        *cdst++ = *csrc++;
69    }
70    return dest;
71}
72//////////////////////////////////////////////////////////////////////////////////
73// Fill a byte string with a byte value.
74//////////////////////////////////////////////////////////////////////////////////
75inline void * _memset( void*        dst, 
76                       int          value, 
77                       unsigned int count ) 
78{
79    char * a = (char *) dst;
80    while (count--) 
81    {
82        *a++ = (char)value;
83    }
84    return dst;
85}
86
87//////////////////////////////////////////////////////////////////////////////////
88// Processor suicide: infinite loop 
89//////////////////////////////////////////////////////////////////////////////////
90inline void _exit() 
91{
92    while (1) { asm volatile ("nop"); }
93}
94///////////////////////////////////////////////////////////////////////////////////
95//         CP0 and CP2 registers access functions
96///////////////////////////////////////////////////////////////////////////////////
97
98///////////////////////////////////////////////////////////////////////////////////
99// Returns the value contained in CP0 SCHED register
100// (virtual base address of the processor scheduler).
101///////////////////////////////////////////////////////////////////////////////////
102inline unsigned int _get_sched() 
103{
104    unsigned int ret;
105    asm volatile("mfc0      %0,     $4, 2\n" : "=r"(ret) );
106    return ret;
107}
108///////////////////////////////////////////////////////////////////////////////////
109// Returns PTPR register content.
110///////////////////////////////////////////////////////////////////////////////////
111inline unsigned int _get_mmu_ptpr() 
112{
113    unsigned int ret;
114    asm volatile("mfc2      %0,     $0" : "=r"(ret));
115    return ret;
116}
117///////////////////////////////////////////////////////////////////////////////////
118// Returns EPC register content.
119///////////////////////////////////////////////////////////////////////////////////
120inline unsigned int _get_epc() 
121{
122    unsigned int ret;
123    asm volatile("mfc0      %0,     $14" : "=r"(ret));
124    return ret;
125}
126///////////////////////////////////////////////////////////////////////////////////
127// Returns BVAR register content.
128///////////////////////////////////////////////////////////////////////////////////
129inline unsigned int _get_bvar() 
130{
131    unsigned int ret;
132    asm volatile("mfc0      %0,     $8" : "=r"(ret));
133    return ret;
134}
135///////////////////////////////////////////////////////////////////////////////////
136// Returns CR register content.
137///////////////////////////////////////////////////////////////////////////////////
138inline unsigned int _get_cr() 
139{
140    unsigned int ret;
141    asm volatile("mfc0      %0,     $13" : "=r"(ret));
142    return ret;
143}
144///////////////////////////////////////////////////////////////////////////////////
145// Returns SR register content
146///////////////////////////////////////////////////////////////////////////////////
147inline unsigned int _get_sr() 
148{
149    unsigned int ret;
150    asm volatile("mfc0      %0,     $12" : "=r"(ret));
151    return ret;
152}
153//////////////////////////////////////////////////////////////////////////////
154// This function set a new value for the CP0 status register.
155//////////////////////////////////////////////////////////////////////////////
156inline void _set_sr(unsigned int val) 
157{
158    asm volatile("mtc0      %0,     $12" ::"r" (val));
159}
160//////////////////////////////////////////////////////////////////////////////////
161// Returns processor index
162//////////////////////////////////////////////////////////////////////////////////
163inline unsigned int _get_procid() 
164{
165    unsigned int ret;
166    asm volatile ("mfc0     %0,     $15, 1":"=r" (ret));
167    return (ret & 0x3FF);
168}
169///////////////////////////////////////////////////////////////////////////////////
170// Returns local time (32 bits value)
171// boot_proctime()
172///////////////////////////////////////////////////////////////////////////////////
173inline unsigned int _get_proctime() 
174{
175    unsigned int ret;
176    asm volatile ("mfc0     %0,     $9":"=r" (ret));
177    return ret;
178}
179///////////////////////////////////////////////////////////////////////////////////
180// Returns index of the currently running task from the sheduler.
181///////////////////////////////////////////////////////////////////////////////////
182unsigned int _get_proc_task_id() 
183{
184    static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
185    return (unsigned int) (psched->current);
186}
187
188///////////////////////////////////////////////////////////////////////////////////
189// Disables IRQs
190///////////////////////////////////////////////////////////////////////////////////
191inline void _it_disable() 
192{
193    asm volatile(
194            "li      $3,        0xFFFFFFFE    \n"
195            "mfc0    $4,        $12           \n"
196            "and     $3,        $3, $4        \n"
197            "mtc0    $3,        $12           \n"
198            ::: "$3", "$4");
199}
200///////////////////////////////////////////////////////////////////////////////////
201// Enables IRQs
202///////////////////////////////////////////////////////////////////////////////////
203inline void _it_enable() 
204{
205    asm volatile(
206            "li      $3,        0x00000001    \n"
207            "mfc0    $4,        $12           \n"
208            "or      $3,        $3, $4        \n"
209            "mtc0    $3,        $12           \n"
210            ::: "$3", "$4");
211}
212
213//////////////////////////////////////////////////////////////////////////////
214// This function set a new value for the MMU PTPR register.
215//////////////////////////////////////////////////////////////////////////////
216inline void _set_mmu_ptpr(unsigned int val) 
217{
218    asm volatile ("mtc2     %0,     $0"::"r" (val));
219}
220//////////////////////////////////////////////////////////////////////////////
221// This function set a new value for the MMU MODE register.
222//////////////////////////////////////////////////////////////////////////////
223inline void _set_mmu_mode(unsigned int val) 
224{
225    asm volatile ("mtc2     %0,     $1"::"r" (val));
226}
227//////////////////////////////////////////////////////////////////////////////
228// This function set a new value in CP0 SCHED register.
229// (virtual base address of the processor scheduler).
230//////////////////////////////////////////////////////////////////////////////
231inline void _set_sched(unsigned int val) 
232{
233    asm volatile ("mtc0     %0,     $4, 2"::"r" (val));
234}
235
236////////////////////////////////////////////////////////////////////////////
237//          Physical addressing related functions
238////////////////////////////////////////////////////////////////////////////
239
240////////////////////////////////////////////////////////////////////////////
241// This function makes a physical read access to a 32 bits word in memory,
242// after a temporary DTLB de-activation and paddr extension.
243////////////////////////////////////////////////////////////////////////////
244inline unsigned int _physical_read( unsigned long long paddr ) 
245{
246    unsigned int value;
247    unsigned int lsb = (unsigned int) paddr;
248    unsigned int msb = (unsigned int) (paddr >> 32);
249
250    asm volatile(
251            "mfc2   $2,     $1                 \n"     /* $2 <= MMU_MODE   */
252            "andi   $3,     $2,        0xb     \n"
253            "mtc2   $3,     $1                 \n"     /* DTLB off         */   
254
255            "mtc2   %2,     $24                \n"     /* PADDR_EXT <= msb */   
256            "lw     %0,     0(%1)              \n"     /* value <= *paddr  */
257            "mtc2   $0,     $24                \n"     /* PADDR_EXT <= 0   */   
258
259            "mtc2   $2,     $1                 \n"     /* restore MMU_MODE */
260            : "=r" (value)
261            : "r" (lsb), "r" (msb)
262            : "$2", "$3");
263    return value;
264}
265////////////////////////////////////////////////////////////////////////////
266// This function makes a physical write access to a 32 bits word in memory,
267// after a temporary DTLB de-activation and paddr extension.
268////////////////////////////////////////////////////////////////////////////
269inline void _physical_write( unsigned long long paddr, 
270                      unsigned int       value ) 
271{
272    unsigned int lsb = (unsigned int)paddr;
273    unsigned int msb = (unsigned int)(paddr >> 32);
274
275    asm volatile(
276            "mfc2   $2,     $1                 \n"     /* $2 <= MMU_MODE   */
277            "andi   $3,     $2,        0xb     \n"
278            "mtc2   $3,     $1                 \n"     /* DTLB off         */   
279
280            "mtc2   %2,     $24                \n"     /* PADDR_EXT <= msb */   
281            "sw     %0,     0(%1)              \n"     /* *paddr <= value  */
282            "mtc2   $0,     $24                \n"     /* PADDR_EXT <= 0   */   
283
284            "mtc2   $2,     $1                 \n"     /* restore MMU_MODE */
285            :
286            : "r" (value), "r" (lsb), "r" (msb)
287            : "$2", "$3");
288}
289
290///////////////////////////////////////////////////////////////////////////////////
291//     Locks access functions
292///////////////////////////////////////////////////////////////////////////////////
293
294///////////////////////////////////////////////////////////////////////////////////
295// Takes a lock with an ll/sc atomic access.
296// A pseudo random delay is introduced before retry in case of miss
297// (delay average value = 100 cycles)
298///////////////////////////////////////////////////////////////////////////////////
299inline void _get_lock(unsigned int * plock) 
300{
301    register unsigned int delay = ( _get_proctime() ^ _get_procid() << 4) & 0xFF;
302
303    if (delay == 0) delay++;
304
305    asm volatile (
306            "_lock_llsc:             \n"
307            "ll   $2,    0(%0)       \n" /* $2 <= _ioc_lock current value */
308            "bnez $2,    _lock_delay \n" /* delay if _ioc_lock already taken */
309            "li   $3,    1           \n" /* $3 <= argument for sc */
310            "sc   $3,    0(%0)       \n" /* try to set _ioc_lock */
311            "bnez $3,    _lock_ok    \n" /* exit if atomic */
312            "_lock_delay:            \n"
313            "move $4,    %1          \n" /* $4 <= delay */
314            "_lock_loop:             \n"
315            "addi $4,    $4,    -1   \n" /* $4 <= $4 - 1 */
316            "bnez $4,    _lock_loop  \n" /* test end delay */
317            "nop                     \n"
318            "j           _lock_llsc  \n" /* retry */
319            "nop                     \n"
320            "_lock_ok:               \n"
321            :
322            :"r"(plock), "r"(delay)
323            :"$2", "$3", "$4");
324}
325///////////////////////////////////////////////////////////////////////////////////
326// Release a previouly taken lock.
327///////////////////////////////////////////////////////////////////////////////////
328inline void _release_lock(unsigned int * plock) 
329{
330    asm volatile ( "sync\n" ); // necessary because of the TSAR consistency model
331    *plock = 0;
332}
333
334///////////////////////////////////////////////////////////////////////////////////
335// Display a string on TTY0 / used for system code debug and log.
336// It does not use the TTY driver, but uses the seg_tty_base variable...
337///////////////////////////////////////////////////////////////////////////////////
338void _puts(char * buffer) 
339{
340    unsigned int n;
341    for (n = 0; n < 1000; n++) 
342    {
343        if (buffer[n] == 0)  break; 
344    }
345    _tty_write( buffer, n, 0 );   // last argument is TTY channel
346}
347
348///////////////////////////////////////////////////////////////////////////////////
349//           Access functions to system terminal TTY0
350///////////////////////////////////////////////////////////////////////////////////
351
352///////////////////////////////////////////////////////////////////////////////////
353// Display a 32 bits unsigned int as an hexadecimal string on TTY0
354///////////////////////////////////////////////////////////////////////////////////
355void _putx(unsigned int val) 
356{
357    static const char HexaTab[] = "0123456789ABCDEF";
358    char buf[11];
359    unsigned int c;
360
361    buf[0] = '0';
362    buf[1] = 'x';
363    buf[10] = 0;
364
365    for (c = 0; c < 8; c++) 
366    { 
367        buf[9 - c] = HexaTab[val & 0xF];
368        val = val >> 4;
369    }
370    _puts(buf);
371}
372
373///////////////////////////////////////////////////////////////////////////////////
374// Display a 64 bits unsigned long as an hexadecimal string on TTY0
375///////////////////////////////////////////////////////////////////////////////////
376void _putl(unsigned long long val)
377{
378    static const char HexaTab[] = "0123456789ABCDEF";
379    char buf[19];
380    unsigned int c;
381
382    buf[0] = '0';
383    buf[1] = 'x';
384    buf[18] = 0;
385
386    for (c = 0; c < 16; c++) 
387    { 
388        buf[17 - c] = HexaTab[(unsigned int)val & 0xF];
389        val = val >> 4;
390    }
391    _puts(buf);
392}
393
394///////////////////////////////////////////////////////////////////////////////////
395// Display a 32 bits unsigned int as a decimal string on TTY0
396///////////////////////////////////////////////////////////////////////////////////
397void _putd(unsigned int val) 
398{
399    static const char DecTab[] = "0123456789";
400    char buf[11];
401    unsigned int i;
402    unsigned int first;
403
404    buf[10] = 0;
405
406    for (i = 0; i < 10; i++) {
407        if ((val != 0) || (i == 0)) {
408            buf[9 - i] = DecTab[val % 10];
409            first = 9 - i;
410        }
411        else {
412            break;
413        }
414        val /= 10;
415    }
416    _puts(&buf[first]);
417}
418
419///////////////////////////////////////////////////////////////////////////////////
420// Compare two strings s1 & s2 (no more than n characters)
421///////////////////////////////////////////////////////////////////////////////////
422unsigned int _strncmp( const char * s1, 
423                       const char * s2, 
424                       unsigned int n ) 
425{
426    unsigned int i;
427    for (i = 0; i < n; i++) 
428    {
429        if (s1[i] != s2[i])  return 1; 
430        if (s1[i] == 0)      break;
431    }
432    return 0;
433}
434
435///////////////////////////////////////////////////////////////////////////////////
436// Copy source string to dest string
437///////////////////////////////////////////////////////////////////////////////////
438char* _strcpy( char* dest, char* source )
439{
440    if (!dest || !source) return dest;
441
442    while (*source)
443        *(dest++) = *(source++);
444
445    return dest;
446}
447
448///////////////////////////////////////////////////////////////////////////////////
449// Invalidate all data cache lines corresponding to a memory
450// buffer (identified by an address and a size).
451// TODO This should be replaced by a write to the CP2 MMU_DCACHE_INVAL
452// register, to be more processor independant.
453///////////////////////////////////////////////////////////////////////////////////
454void _dcache_buf_invalidate( const void * buffer, 
455                             unsigned int size) 
456{
457    unsigned int i;
458    unsigned int tmp;
459    unsigned int line_size;
460
461    // compute data cache line size based on config register (bits 12:10)
462    asm volatile(
463                 "mfc0 %0, $16, 1" 
464                 : "=r" (tmp) );
465    tmp = ((tmp >> 10) & 0x7);
466    line_size = 2 << tmp;
467
468    // iterate on cache lines
469    for (i = 0; i < size; i += line_size) 
470    {
471        asm volatile(
472                " cache %0, %1"
473                : :"i" (0x11), "R" (*((unsigned char *) buffer + i)) );
474    }
475}
476
477////////////////////////////////////////////////////////////////////////////////////
478// This function returns the content of a context slot
479// for any task identified by the ltid argument (local task index),
480// and the gpid argument (global processor index)
481////////////////////////////////////////////////////////////////////////////////////
482unsigned int _get_task_slot( unsigned int gpid,
483                             unsigned int ltid,
484                             unsigned int slot )
485{
486    static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[gpid];
487    return psched->context[ltid][slot];
488}
489
490////////////////////////////////////////////////////////////////////////////////////
491// This function updates the content of a context slot
492// for any task identified by the ltid argument (local task index),
493// and the gpid argument (global processor index)
494////////////////////////////////////////////////////////////////////////////////////
495void _set_task_slot( unsigned int gpid,
496                     unsigned int ltid,
497                     unsigned int slot,
498                     unsigned int value )
499{
500    static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[gpid];
501    psched->context[ltid][slot] = value;
502}
503
504////////////////////////////////////////////////////////////////////////////////////
505// This function returns the content of a context slot
506// for the running task (defined by the scheduler current field).
507////////////////////////////////////////////////////////////////////////////////////
508unsigned int _get_context_slot( unsigned int slot )
509{
510    static_scheduler_t* psched  = (static_scheduler_t*)_get_sched();
511    unsigned int        task_id = psched->current;
512    return psched->context[task_id][slot];
513}
514
515////////////////////////////////////////////////////////////////////////////////////
516// This function updates the content of a context slot for the running task.
517////////////////////////////////////////////////////////////////////////////////////
518void _set_context_slot( unsigned int slot,
519                       unsigned int value )
520{
521    static_scheduler_t* psched  = (static_scheduler_t*)_get_sched();
522    unsigned int        task_id = psched->current;
523    psched->context[task_id][slot] = value;
524}
525
526///////////////////////////////////////////////////////////////////////////////////
527// This function returns the information associated to a heap (size and vaddr)
528// It uses the global task index (CTX_GTID_ID, unique for each giet task) and the
529// vspace index (CTX_VSID_ID) defined in the task context.
530///////////////////////////////////////////////////////////////////////////////////
531unsigned int _heap_info( unsigned int* vaddr, 
532                         unsigned int* size ) 
533{
534    mapping_header_t * header  = (mapping_header_t *) (&seg_boot_mapping_base);
535    mapping_task_t * tasks     = _get_task_base(header);
536    mapping_vobj_t * vobjs     = _get_vobj_base(header);
537    mapping_vspace_t * vspaces = _get_vspace_base(header);
538
539    unsigned int taskid        = _get_context_slot(CTX_GTID_ID);
540    unsigned int vspaceid      = _get_context_slot(CTX_VSID_ID);
541
542    int heap_local_vobjid      = tasks[taskid].heap_vobjid;
543    if (heap_local_vobjid != -1) 
544    {
545        unsigned int vobjheapid = heap_local_vobjid + vspaces[vspaceid].vobj_offset;
546        *vaddr                  = vobjs[vobjheapid].vaddr;
547        *size                   = vobjs[vobjheapid].length;
548        return 0;
549    }
550    else 
551    {
552        *vaddr = 0;
553        *size = 0;
554        return 0;
555    }
556}
557
558/////////////////////////////////////////////////////////////////////////////
559//      Access functions to mapping_info data structure
560/////////////////////////////////////////////////////////////////////////////
561inline mapping_cluster_t * _get_cluster_base(mapping_header_t * header) 
562{
563    return (mapping_cluster_t *) ((char *) header +
564            MAPPING_HEADER_SIZE);
565}
566/////////////////////////////////////////////////////////////////////////////
567inline mapping_pseg_t * _get_pseg_base(mapping_header_t * header) 
568{
569    return (mapping_pseg_t *) ((char *) header +
570            MAPPING_HEADER_SIZE +
571            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE);
572}
573/////////////////////////////////////////////////////////////////////////////
574inline mapping_vspace_t * _get_vspace_base(mapping_header_t * header) 
575{
576    return (mapping_vspace_t *)  ((char *) header +
577            MAPPING_HEADER_SIZE +
578            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
579            MAPPING_PSEG_SIZE * header->psegs);
580}
581/////////////////////////////////////////////////////////////////////////////
582inline mapping_vseg_t * _get_vseg_base(mapping_header_t * header)
583{
584    return (mapping_vseg_t *) ((char *) header +
585            MAPPING_HEADER_SIZE +
586            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
587            MAPPING_PSEG_SIZE * header->psegs +
588            MAPPING_VSPACE_SIZE * header->vspaces);
589}
590/////////////////////////////////////////////////////////////////////////////
591inline mapping_vobj_t * _get_vobj_base(mapping_header_t * header) 
592{
593    return (mapping_vobj_t *) ((char *) header +
594            MAPPING_HEADER_SIZE +
595            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
596            MAPPING_PSEG_SIZE * header->psegs +
597            MAPPING_VSPACE_SIZE * header->vspaces +
598            MAPPING_VSEG_SIZE * header->vsegs );
599}
600/////////////////////////////////////////////////////////////////////////////
601inline mapping_task_t * _get_task_base(mapping_header_t * header) 
602{
603    return (mapping_task_t *) ((char *) header +
604            MAPPING_HEADER_SIZE +
605            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
606            MAPPING_PSEG_SIZE * header->psegs +
607            MAPPING_VSPACE_SIZE * header->vspaces +
608            MAPPING_VOBJ_SIZE * header->vobjs +
609            MAPPING_VSEG_SIZE * header->vsegs);
610}
611/////////////////////////////////////////////////////////////////////////////
612inline mapping_proc_t *_get_proc_base(mapping_header_t * header) 
613{
614    return (mapping_proc_t *) ((char *) header +
615            MAPPING_HEADER_SIZE +
616            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
617            MAPPING_PSEG_SIZE * header->psegs +
618            MAPPING_VSPACE_SIZE * header->vspaces +
619            MAPPING_VSEG_SIZE * header->vsegs +
620            MAPPING_VOBJ_SIZE * header->vobjs +
621            MAPPING_TASK_SIZE * header->tasks);
622}
623/////////////////////////////////////////////////////////////////////////////
624inline mapping_irq_t *_get_irq_base(mapping_header_t * header) 
625{
626    return (mapping_irq_t *) ((char *) header +
627            MAPPING_HEADER_SIZE +
628            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
629            MAPPING_PSEG_SIZE * header->psegs +
630            MAPPING_VSPACE_SIZE * header->vspaces +
631            MAPPING_VSEG_SIZE * header->vsegs +
632            MAPPING_VOBJ_SIZE * header->vobjs +
633            MAPPING_TASK_SIZE * header->tasks +
634            MAPPING_PROC_SIZE * header->procs);
635}
636/////////////////////////////////////////////////////////////////////////////
637inline mapping_coproc_t *_get_coproc_base(mapping_header_t * header) 
638{
639    return (mapping_coproc_t *) ((char *) header +
640            MAPPING_HEADER_SIZE +
641            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
642            MAPPING_PSEG_SIZE * header->psegs +
643            MAPPING_VSPACE_SIZE * header->vspaces +
644            MAPPING_VOBJ_SIZE * header->vobjs +
645            MAPPING_VSEG_SIZE * header->vsegs +
646            MAPPING_TASK_SIZE * header->tasks +
647            MAPPING_PROC_SIZE * header->procs +
648            MAPPING_IRQ_SIZE * header->irqs);
649}
650///////////////////////////////////////////////////////////////////////////////////
651inline mapping_cp_port_t *_get_cp_port_base(mapping_header_t * header) 
652{
653    return (mapping_cp_port_t *) ((char *) header +
654            MAPPING_HEADER_SIZE +
655            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
656            MAPPING_PSEG_SIZE * header->psegs +
657            MAPPING_VSPACE_SIZE * header->vspaces +
658            MAPPING_VOBJ_SIZE * header->vobjs +
659            MAPPING_VSEG_SIZE * header->vsegs +
660            MAPPING_TASK_SIZE * header->tasks +
661            MAPPING_PROC_SIZE * header->procs +
662            MAPPING_IRQ_SIZE * header->irqs +
663            MAPPING_COPROC_SIZE * header->coprocs);
664}
665///////////////////////////////////////////////////////////////////////////////////
666inline mapping_periph_t *_get_periph_base(mapping_header_t * header) 
667{
668    return (mapping_periph_t *) ((char *) header +
669            MAPPING_HEADER_SIZE +
670            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
671            MAPPING_PSEG_SIZE * header->psegs +
672            MAPPING_VSPACE_SIZE * header->vspaces +
673            MAPPING_VOBJ_SIZE * header->vobjs +
674            MAPPING_VSEG_SIZE * header->vsegs +
675            MAPPING_TASK_SIZE * header->tasks +
676            MAPPING_PROC_SIZE * header->procs +
677            MAPPING_IRQ_SIZE * header->irqs +
678            MAPPING_COPROC_SIZE * header->coprocs +
679            MAPPING_CP_PORT_SIZE * header->cp_ports);
680}
681
682// Local Variables:
683// tab-width: 4
684// c-basic-offset: 4
685// c-file-offsets:((innamespace . 0)(inline-open . 0))
686// indent-tabs-mode: nil
687// End:
688// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
689
Note: See TracBrowser for help on using the repository browser.