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

Last change on this file since 258 was 258, checked in by alain, 11 years ago

This is a major release, including a deep restructuration of code.
The main evolutions are

  • use of the Tsar preloader to load the GIET boot-loader from disk
  • introduction of a FAT32 file system library,
  • use of this fat32 library by the boot-loader to load the map.bin data structure, and the various .elf files
  • reorganisation of drivers (one file per peripheral).
  • introduction of drivers for new peripherals: vci_chbuf_dma and vci_multi_ahci.
  • introduction of a new physical memory allocator in the boot code.

This release has been tested on the tsar_generic_iob architecture,
for the two following mappings: 4c_1p_iob_four.xml and 4c_1p_iob_sort.xml

File size: 26.0 KB
RevLine 
[258]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_CLUSTERS * 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,   $22    \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// Returns processor index
155//////////////////////////////////////////////////////////////////////////////////
156inline unsigned int _get_procid() 
157{
158    unsigned int ret;
159    asm volatile ("mfc0    %0,       $15, 1":"=r" (ret));
160    return (ret & 0x3FF);
161}
162///////////////////////////////////////////////////////////////////////////////////
163// Returns local time (32 bits value)
164// boot_proctime()
165///////////////////////////////////////////////////////////////////////////////////
166inline unsigned int _get_proctime() 
167{
168    unsigned int ret;
169    asm volatile ("mfc0   %0,        $9":"=r" (ret));
170    return ret;
171}
172///////////////////////////////////////////////////////////////////////////////////
173// Returns index of the currently running task from the sheduler.
174///////////////////////////////////////////////////////////////////////////////////
175unsigned int _get_proc_task_id() 
176{
177    static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
178    return (unsigned int) (psched->current);
179}
180
181///////////////////////////////////////////////////////////////////////////////////
182// Disables IRQs
183///////////////////////////////////////////////////////////////////////////////////
184inline void _it_disable() 
185{
186    asm volatile(
187            "li      $3,        0xFFFFFFFE    \n"
188            "mfc0    $4,        $12           \n"
189            "and     $3,        $3, $4        \n"
190            "mtc0    $3,        $12           \n"
191            ::: "$3", "$4");
192}
193///////////////////////////////////////////////////////////////////////////////////
194// Enables IRQs
195///////////////////////////////////////////////////////////////////////////////////
196inline void _it_enable() 
197{
198    asm volatile(
199            "li      $3,        0x00000001    \n"
200            "mfc0    $4,        $12           \n"
201            "or      $3,        $3, $4        \n"
202            "mtc0    $3,        $12           \n"
203            ::: "$3", "$4");
204}
205
206//////////////////////////////////////////////////////////////////////////////
207// This function set a new value for the MMU PTPR register.
208//////////////////////////////////////////////////////////////////////////////
209inline void _set_mmu_ptpr(unsigned int val) 
210{
211    asm volatile ("mtc2  %0, $0"::"r" (val));
212}
213//////////////////////////////////////////////////////////////////////////////
214// This function set a new value for the MMU MODE register.
215//////////////////////////////////////////////////////////////////////////////
216inline void _set_mmu_mode(unsigned int val) 
217{
218    asm volatile ("mtc2  %0, $1"::"r" (val));
219}
220//////////////////////////////////////////////////////////////////////////////
221// This function set a new value in CP0 SCHED register.
222// (virtual base address of the processor scheduler).
223//////////////////////////////////////////////////////////////////////////////
224inline void _set_sched(unsigned int val) 
225{
226    asm volatile ("mtc0  %0, $22"::"r" (val));
227}
228
229////////////////////////////////////////////////////////////////////////////
230//          Physical addressing related functions
231////////////////////////////////////////////////////////////////////////////
232
233////////////////////////////////////////////////////////////////////////////
234// This function makes a physical read access to a 32 bits word in memory,
235// after a temporary DTLB de-activation and paddr extension.
236////////////////////////////////////////////////////////////////////////////
237inline unsigned int _physical_read( unsigned long long paddr ) 
238{
239    unsigned int value;
240    unsigned int lsb = (unsigned int) paddr;
241    unsigned int msb = (unsigned int) (paddr >> 32);
242
243    asm volatile(
244            "mfc2   $2,     $1                 \n"     /* $2 <= MMU_MODE   */
245            "andi   $3,     $2,        0xb     \n"
246            "mtc2   $3,     $1                 \n"     /* DTLB off         */   
247
248            "mtc2   %2,     $24                \n"     /* PADDR_EXT <= msb */   
249            "lw     %0,     0(%1)              \n"     /* value <= *paddr  */
250            "mtc2   $0,     $24                \n"     /* PADDR_EXT <= 0   */   
251
252            "mtc2   $2,     $1                 \n"     /* restore MMU_MODE */
253            : "=r" (value)
254            : "r" (lsb), "r" (msb)
255            : "$2", "$3");
256    return value;
257}
258////////////////////////////////////////////////////////////////////////////
259// This function makes a physical write access to a 32 bits word in memory,
260// after a temporary DTLB de-activation and paddr extension.
261////////////////////////////////////////////////////////////////////////////
262inline void _physical_write( unsigned long long paddr, 
263                      unsigned int       value ) 
264{
265    unsigned int lsb = (unsigned int)paddr;
266    unsigned int msb = (unsigned int)(paddr >> 32);
267
268    asm volatile(
269            "mfc2   $2,     $1                 \n"     /* $2 <= MMU_MODE   */
270            "andi   $3,     $2,        0xb     \n"
271            "mtc2   $3,     $1                 \n"     /* DTLB off         */   
272
273            "mtc2   %2,     $24                \n"     /* PADDR_EXT <= msb */   
274            "sw     %0,     0(%1)              \n"     /* *paddr <= value  */
275            "mtc2   $0,     $24                \n"     /* PADDR_EXT <= 0   */   
276
277            "mtc2   $2,     $1                 \n"     /* restore MMU_MODE */
278            :
279            : "r" (value), "r" (lsb), "r" (msb)
280            : "$2", "$3");
281}
282
283///////////////////////////////////////////////////////////////////////////////////
284//     Locks access functions
285///////////////////////////////////////////////////////////////////////////////////
286
287///////////////////////////////////////////////////////////////////////////////////
288// Takes a lock with an ll/sc atomic access.
289// A pseudo random delay is introduced before retry in case of miss
290// (delay average value = 100 cycles)
291///////////////////////////////////////////////////////////////////////////////////
292inline void _get_lock(unsigned int * plock) 
293{
294    register unsigned int delay = ( _get_proctime() ^ _get_procid() << 4) & 0xFF;
295
296    asm volatile (
297            "_lock_llsc:             \n"
298            "ll   $2,    0(%0)       \n" /* $2 <= _ioc_lock current value */
299            "bnez $2,    _lock_delay \n" /* delay if _ioc_lock already taken */
300            "li   $3,    1           \n" /* $3 <= argument for sc */
301            "sc   $3,    0(%0)       \n" /* try to set _ioc_lock */
302            "bnez $3,    _lock_ok    \n" /* exit if atomic */
303            "_lock_delay:            \n"
304            "move $4,    %1          \n" /* $4 <= delay */
305            "_lock_loop:             \n"
306            "addi $4,    $4,    -1   \n" /* $4 <= $4 - 1 */
307            "beqz $4,    _lock_loop  \n" /* test end delay */
308            "j           _lock_llsc  \n" /* retry */
309            "_lock_ok:               \n"
310            :
311            :"r"(plock), "r"(delay)
312            :"$2", "$3", "$4");
313}
314///////////////////////////////////////////////////////////////////////////////////
315// Release a previouly taken lock.
316///////////////////////////////////////////////////////////////////////////////////
317inline void _release_lock(unsigned int * plock) 
318{
319    asm volatile ( "sync\n" ); // necessary because of the TSAR consistency model
320    *plock = 0;
321}
322
323///////////////////////////////////////////////////////////////////////////////////
324// Display a string on TTY0 / used for system code debug and log.
325// It does not use the TTY driver, but uses the seg_tty_base variable...
326///////////////////////////////////////////////////////////////////////////////////
327void _puts(char * buffer) 
328{
329    unsigned int n;
330    for (n = 0; n < 1000; n++) 
331    {
332        if (buffer[n] == 0)  break; 
333    }
334    _tty_write( buffer, n, 0 );   // last argument is TTY channel
335}
336
337///////////////////////////////////////////////////////////////////////////////////
338//           Access functions to system terminal TTY0
339///////////////////////////////////////////////////////////////////////////////////
340
341///////////////////////////////////////////////////////////////////////////////////
342// Display a 32 bits unsigned int as an hexadecimal string on TTY0
343///////////////////////////////////////////////////////////////////////////////////
344void _putx(unsigned int val) 
345{
346    static const char HexaTab[] = "0123456789ABCDEF";
347    char buf[11];
348    unsigned int c;
349
350    buf[0] = '0';
351    buf[1] = 'x';
352    buf[10] = 0;
353
354    for (c = 0; c < 8; c++) 
355    { 
356        buf[9 - c] = HexaTab[val & 0xF];
357        val = val >> 4;
358    }
359    _puts(buf);
360}
361
362///////////////////////////////////////////////////////////////////////////////////
363// Display a 64 bits unsigned long as an hexadecimal string on TTY0
364///////////////////////////////////////////////////////////////////////////////////
365void _putl(unsigned long long val)
366{
367    static const char HexaTab[] = "0123456789ABCDEF";
368    char buf[19];
369    unsigned int c;
370
371    buf[0] = '0';
372    buf[1] = 'x';
373    buf[18] = 0;
374
375    for (c = 0; c < 16; c++) 
376    { 
377        buf[17 - c] = HexaTab[(unsigned int)val & 0xF];
378        val = val >> 4;
379    }
380    _puts(buf);
381}
382
383///////////////////////////////////////////////////////////////////////////////////
384// Display a 32 bits unsigned int as a decimal string on TTY0
385///////////////////////////////////////////////////////////////////////////////////
386void _putd(unsigned int val) 
387{
388    static const char DecTab[] = "0123456789";
389    char buf[11];
390    unsigned int i;
391    unsigned int first;
392
393    buf[10] = 0;
394
395    for (i = 0; i < 10; i++) {
396        if ((val != 0) || (i == 0)) {
397            buf[9 - i] = DecTab[val % 10];
398            first = 9 - i;
399        }
400        else {
401            break;
402        }
403        val /= 10;
404    }
405    _puts(&buf[first]);
406}
407
408///////////////////////////////////////////////////////////////////////////////////
409// Compare two strings s1 & s2 (no more than n characters)
410///////////////////////////////////////////////////////////////////////////////////
411unsigned int _strncmp( const char * s1, 
412                       const char * s2, 
413                       unsigned int n ) 
414{
415    unsigned int i;
416    for (i = 0; i < n; i++) 
417    {
418        if (s1[i] != s2[i])  return 1; 
419        if (s1[i] == 0)      break;
420    }
421    return 0;
422}
423
424///////////////////////////////////////////////////////////////////////////////////
425// Copy source string to dest string
426///////////////////////////////////////////////////////////////////////////////////
427char* _strcpy( char* dest, char* source )
428{
429    if (!dest || !source) return dest;
430
431    while (*source)
432        *(dest++) = *(source++);
433
434    return dest;
435}
436
437///////////////////////////////////////////////////////////////////////////////////
438// Invalidate all data cache lines corresponding to a memory
439// buffer (identified by an address and a size).
440// TODO This should be replaced by a write to the CP2 MMU_DCACHE_INVAL
441// register, to be more processor independant.
442///////////////////////////////////////////////////////////////////////////////////
443void _dcache_buf_invalidate( const void * buffer, 
444                             unsigned int size) 
445{
446    unsigned int i;
447    unsigned int tmp;
448    unsigned int line_size;
449
450    // compute data cache line size based on config register (bits 12:10)
451    asm volatile(
452                 "mfc0 %0, $16, 1" 
453                 : "=r" (tmp) );
454    tmp = ((tmp >> 10) & 0x7);
455    line_size = 2 << tmp;
456
457    // iterate on cache lines
458    for (i = 0; i < size; i += line_size) 
459    {
460        asm volatile(
461                " cache %0, %1"
462                : :"i" (0x11), "R" (*((unsigned char *) buffer + i)) );
463    }
464}
465
466////////////////////////////////////////////////////////////////////////////////////
467// This function returns the content of a context slot
468// for any task identified by the ltid argument (local task index),
469// and the gpid argument (global processor index)
470////////////////////////////////////////////////////////////////////////////////////
471unsigned int _get_task_slot( unsigned int gpid,
472                             unsigned int ltid,
473                             unsigned int slot )
474{
475    static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[gpid];
476    return psched->context[ltid][slot];
477}
478
479////////////////////////////////////////////////////////////////////////////////////
480// This function updates the content of a context slot
481// for any task identified by the ltid argument (local task index),
482// and the gpid argument (global processor index)
483////////////////////////////////////////////////////////////////////////////////////
484void _set_task_slot( unsigned int gpid,
485                     unsigned int ltid,
486                     unsigned int slot,
487                     unsigned int value )
488{
489    static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[gpid];
490    psched->context[ltid][slot] = value;
491}
492
493////////////////////////////////////////////////////////////////////////////////////
494// This function returns the content of a context slot
495// for the running task (defined by the scheduler current field).
496////////////////////////////////////////////////////////////////////////////////////
497unsigned int _get_context_slot( unsigned int slot )
498{
499    static_scheduler_t* psched  = (static_scheduler_t*)_get_sched();
500    unsigned int        task_id = psched->current;
501    return psched->context[task_id][slot];
502}
503
504////////////////////////////////////////////////////////////////////////////////////
505// This function updates the content of a context slot for the running task.
506////////////////////////////////////////////////////////////////////////////////////
507void _set_context_slot( unsigned int slot,
508                       unsigned int value )
509{
510    static_scheduler_t* psched  = (static_scheduler_t*)_get_sched();
511    unsigned int        task_id = psched->current;
512    psched->context[task_id][slot] = value;
513}
514
515///////////////////////////////////////////////////////////////////////////////////
516// This function returns the information associated to a heap (size and vaddr)
517// It uses the global task index (CTX_GTID_ID, unique for each giet task) and the
518// vspace index (CTX_VSID_ID) defined in the task context.
519///////////////////////////////////////////////////////////////////////////////////
520unsigned int _heap_info( unsigned int* vaddr, 
521                         unsigned int* size ) 
522{
523    mapping_header_t * header  = (mapping_header_t *) (&seg_boot_mapping_base);
524    mapping_task_t * tasks     = _get_task_base(header);
525    mapping_vobj_t * vobjs     = _get_vobj_base(header);
526    mapping_vspace_t * vspaces = _get_vspace_base(header);
527
528    unsigned int taskid        = _get_context_slot(CTX_GTID_ID);
529    unsigned int vspaceid      = _get_context_slot(CTX_VSID_ID);
530
531    int heap_local_vobjid      = tasks[taskid].heap_vobjid;
532    if (heap_local_vobjid != -1) 
533    {
534        unsigned int vobjheapid = heap_local_vobjid + vspaces[vspaceid].vobj_offset;
535        *vaddr                  = vobjs[vobjheapid].vaddr;
536        *size                   = vobjs[vobjheapid].length;
537        return 0;
538    }
539    else 
540    {
541        *vaddr = 0;
542        *size = 0;
543        return 0;
544    }
545}
546
547/////////////////////////////////////////////////////////////////////////////
548//      Access functions to mapping_info data structure
549/////////////////////////////////////////////////////////////////////////////
550inline mapping_cluster_t * _get_cluster_base(mapping_header_t * header) 
551{
552    return (mapping_cluster_t *) ((char *) header +
553            MAPPING_HEADER_SIZE);
554}
555/////////////////////////////////////////////////////////////////////////////
556inline mapping_pseg_t * _get_pseg_base(mapping_header_t * header) 
557{
558    return (mapping_pseg_t *) ((char *) header +
559            MAPPING_HEADER_SIZE +
560            MAPPING_CLUSTER_SIZE * header->clusters);
561}
562/////////////////////////////////////////////////////////////////////////////
563inline mapping_vspace_t * _get_vspace_base(mapping_header_t * header) 
564{
565    return (mapping_vspace_t *)  ((char *) header +
566            MAPPING_HEADER_SIZE +
567            MAPPING_CLUSTER_SIZE * header->clusters +
568            MAPPING_PSEG_SIZE * header->psegs);
569}
570/////////////////////////////////////////////////////////////////////////////
571inline mapping_vseg_t * _get_vseg_base(mapping_header_t * header)
572{
573    return (mapping_vseg_t *) ((char *) header +
574            MAPPING_HEADER_SIZE +
575            MAPPING_CLUSTER_SIZE * header->clusters +
576            MAPPING_PSEG_SIZE * header->psegs +
577            MAPPING_VSPACE_SIZE * header->vspaces);
578}
579/////////////////////////////////////////////////////////////////////////////
580inline mapping_vobj_t * _get_vobj_base(mapping_header_t * header) 
581{
582    return (mapping_vobj_t *) ((char *) header +
583            MAPPING_HEADER_SIZE +
584            MAPPING_CLUSTER_SIZE * header->clusters +
585            MAPPING_PSEG_SIZE * header->psegs +
586            MAPPING_VSPACE_SIZE * header->vspaces +
587            MAPPING_VSEG_SIZE * header->vsegs );
588}
589/////////////////////////////////////////////////////////////////////////////
590inline mapping_task_t * _get_task_base(mapping_header_t * header) 
591{
592    return (mapping_task_t *) ((char *) header +
593            MAPPING_HEADER_SIZE +
594            MAPPING_CLUSTER_SIZE * header->clusters +
595            MAPPING_PSEG_SIZE * header->psegs +
596            MAPPING_VSPACE_SIZE * header->vspaces +
597            MAPPING_VOBJ_SIZE * header->vobjs +
598            MAPPING_VSEG_SIZE * header->vsegs);
599}
600/////////////////////////////////////////////////////////////////////////////
601inline mapping_proc_t *_get_proc_base(mapping_header_t * header) 
602{
603    return (mapping_proc_t *) ((char *) header +
604            MAPPING_HEADER_SIZE +
605            MAPPING_CLUSTER_SIZE * header->clusters +
606            MAPPING_PSEG_SIZE * header->psegs +
607            MAPPING_VSPACE_SIZE * header->vspaces +
608            MAPPING_VSEG_SIZE * header->vsegs +
609            MAPPING_VOBJ_SIZE * header->vobjs +
610            MAPPING_TASK_SIZE * header->tasks);
611}
612/////////////////////////////////////////////////////////////////////////////
613inline mapping_irq_t *_get_irq_base(mapping_header_t * header) 
614{
615    return (mapping_irq_t *) ((char *) header +
616            MAPPING_HEADER_SIZE +
617            MAPPING_CLUSTER_SIZE * header->clusters +
618            MAPPING_PSEG_SIZE * header->psegs +
619            MAPPING_VSPACE_SIZE * header->vspaces +
620            MAPPING_VSEG_SIZE * header->vsegs +
621            MAPPING_VOBJ_SIZE * header->vobjs +
622            MAPPING_TASK_SIZE * header->tasks +
623            MAPPING_PROC_SIZE * header->procs);
624}
625/////////////////////////////////////////////////////////////////////////////
626inline mapping_coproc_t *_get_coproc_base(mapping_header_t * header) 
627{
628    return (mapping_coproc_t *) ((char *) header +
629            MAPPING_HEADER_SIZE +
630            MAPPING_CLUSTER_SIZE * header->clusters +
631            MAPPING_PSEG_SIZE * header->psegs +
632            MAPPING_VSPACE_SIZE * header->vspaces +
633            MAPPING_VOBJ_SIZE * header->vobjs +
634            MAPPING_VSEG_SIZE * header->vsegs +
635            MAPPING_TASK_SIZE * header->tasks +
636            MAPPING_PROC_SIZE * header->procs +
637            MAPPING_IRQ_SIZE * header->irqs);
638}
639///////////////////////////////////////////////////////////////////////////////////
640inline mapping_cp_port_t *_get_cp_port_base(mapping_header_t * header) 
641{
642    return (mapping_cp_port_t *) ((char *) header +
643            MAPPING_HEADER_SIZE +
644            MAPPING_CLUSTER_SIZE * header->clusters +
645            MAPPING_PSEG_SIZE * header->psegs +
646            MAPPING_VSPACE_SIZE * header->vspaces +
647            MAPPING_VOBJ_SIZE * header->vobjs +
648            MAPPING_VSEG_SIZE * header->vsegs +
649            MAPPING_TASK_SIZE * header->tasks +
650            MAPPING_PROC_SIZE * header->procs +
651            MAPPING_IRQ_SIZE * header->irqs +
652            MAPPING_COPROC_SIZE * header->coprocs);
653}
654///////////////////////////////////////////////////////////////////////////////////
655inline mapping_periph_t *_get_periph_base(mapping_header_t * header) 
656{
657    return (mapping_periph_t *) ((char *) header +
658            MAPPING_HEADER_SIZE +
659            MAPPING_CLUSTER_SIZE * header->clusters +
660            MAPPING_PSEG_SIZE * header->psegs +
661            MAPPING_VSPACE_SIZE * header->vspaces +
662            MAPPING_VOBJ_SIZE * header->vobjs +
663            MAPPING_VSEG_SIZE * header->vsegs +
664            MAPPING_TASK_SIZE * header->tasks +
665            MAPPING_PROC_SIZE * header->procs +
666            MAPPING_IRQ_SIZE * header->irqs +
667            MAPPING_COPROC_SIZE * header->coprocs +
668            MAPPING_CP_PORT_SIZE * header->cp_ports);
669}
670
671// Local Variables:
672// tab-width: 4
673// c-basic-offset: 4
674// c-file-offsets:((innamespace . 0)(inline-open . 0))
675// indent-tabs-mode: nil
676// End:
677// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
678
Note: See TracBrowser for help on using the repository browser.