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

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

Using the CP0 $4,2 register for the scheduler virtual address
instead of the CP0 $22 register

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[X_SIZE * Y_SIZE * NB_PROCS_MAX];
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.