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

Last change on this file since 442 was 442, checked in by alain, 10 years ago

Removing the _printf() function in the boot code i
and in the drivers used by the boot code.

File size: 30.6 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 <utils.h>
14#include <giet_config.h>
15#include <hard_config.h>
16#include <mapping_info.h>
17#include <tty_driver.h>
18#include <ctx_handler.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//         CP0 registers access functions
25///////////////////////////////////////////////////////////////////////////////////
26
27/////////////////////////
28unsigned int _get_sched() 
29{
30    unsigned int ret;
31    asm volatile( "mfc0      %0,     $4,2    \n" 
32                  : "=r"(ret) );
33    return ret;
34}
35///////////////////////
36unsigned int _get_epc() 
37{
38    unsigned int ret;
39    asm volatile( "mfc0      %0,    $14     \n"
40                  : "=r"(ret) );
41    return ret;
42}
43////////////////////////
44unsigned int _get_bvar() 
45{
46    unsigned int ret;
47    asm volatile( "mfc0      %0,    $8     \n"
48                  : "=r"(ret));
49    return ret;
50}
51//////////////////////
52unsigned int _get_cr() 
53{
54    unsigned int ret;
55    asm volatile( "mfc0      %0,    $13    \n"
56                  : "=r"(ret));
57    return ret;
58}
59//////////////////////
60unsigned int _get_sr() 
61{
62    unsigned int ret;
63    asm volatile( "mfc0      %0,     $12   \n"
64                  : "=r"(ret));
65    return ret;
66}
67//////////////////////////
68unsigned int _get_procid() 
69{
70    unsigned int ret;
71    asm volatile ( "mfc0     %0,     $15, 1  \n"
72                   :"=r" (ret) );
73    return (ret & 0xFFF);
74}
75////////////////////////////
76unsigned int _get_proctime() 
77{
78    unsigned int ret;
79    asm volatile ( "mfc0     %0,     $9      \n"
80                   :"=r" (ret) );
81    return ret;
82}
83
84/////////////////////////////////////////////
85void _it_disable( unsigned int * save_sr_ptr) 
86{
87    unsigned int sr = 0;
88    asm volatile( "li      $3,        0xFFFFFFFE    \n"
89                  "mfc0    %0,        $12           \n"
90                  "and     $3,        $3,   %0      \n" 
91                  "mtc0    $3,        $12           \n" 
92                  : "+r"(sr)
93                  :
94                  : "$3" );
95    *save_sr_ptr = sr;
96}
97//////////////////////////////////////////////
98void _it_restore( unsigned int * save_sr_ptr ) 
99{
100    unsigned int sr = *save_sr_ptr;
101    asm volatile( "mtc0    %0,        $12           \n" 
102                  :
103                  : "r"(sr)
104                  : "memory" );
105}
106
107/////////////////////////////////
108void _set_sched(unsigned int val) 
109{
110    asm volatile ( "mtc0     %0,     $4, 2          \n"
111                   :
112                   :"r" (val) );
113}
114//////////////////////////////
115void _set_sr(unsigned int val) 
116{
117    asm volatile ( "mtc0     %0,     $12            \n"
118                   :
119                   :"r" (val) );
120}
121
122
123///////////////////////////////////////////////////////////////////////////////////
124//         CP2 registers access functions
125///////////////////////////////////////////////////////////////////////////////////
126
127////////////////////////////
128unsigned int _get_mmu_ptpr() 
129{
130    unsigned int ret;
131    asm volatile( "mfc2      %0,     $0      \n"
132                  : "=r"(ret) );
133    return ret;
134}
135////////////////////////////
136unsigned int _get_mmu_mode() 
137{
138    unsigned int ret;
139    asm volatile( "mfc2      %0,     $1      \n"
140                  : "=r"(ret) );
141    return ret;
142}
143////////////////////////////////////
144void _set_mmu_ptpr(unsigned int val) 
145{
146    asm volatile ( "mtc2     %0,     $0      \n"
147                   :
148                   :"r" (val)
149                   :"memory" );
150}
151////////////////////////////////////
152void _set_mmu_mode(unsigned int val) 
153{
154    asm volatile ( "mtc2     %0,     $1      \n"
155                   :
156                   :"r" (val)
157                   :"memory" );
158}
159////////////////////////////////////////////
160void _set_mmu_dcache_inval(unsigned int val) 
161{
162    asm volatile ( "mtc2     %0,     $7      \n"
163                   :
164                   :"r" (val)
165                   :"memory" );
166}
167
168
169////////////////////////////////////////////////////////////////////////////
170//          Physical addressing related functions
171////////////////////////////////////////////////////////////////////////////
172
173///////////////////////////////////////////////////////
174unsigned int _physical_read( unsigned long long paddr ) 
175{
176    unsigned int value;
177    unsigned int lsb = (unsigned int) paddr;
178    unsigned int msb = (unsigned int) (paddr >> 32);
179    unsigned int sr;
180
181    _it_disable(&sr);
182
183    asm volatile( "mfc2   $2,     $1                 \n"     /* $2 <= MMU_MODE   */
184                  "andi   $3,     $2,        0xb     \n"
185                  "mtc2   $3,     $1                 \n"     /* DTLB off         */   
186
187                  "mtc2   %2,     $24                \n"     /* PADDR_EXT <= msb */   
188                  "lw     %0,     0(%1)              \n"     /* value <= *paddr  */
189                  "mtc2   $0,     $24                \n"     /* PADDR_EXT <= 0   */   
190
191                  "mtc2   $2,     $1                 \n"     /* restore MMU_MODE */
192                  : "=r" (value)
193                  : "r" (lsb), "r" (msb)
194                  : "$2", "$3" );
195
196    _it_restore(&sr);
197    return value;
198}
199////////////////////////////////////////////////
200void _physical_write( unsigned long long paddr, 
201                      unsigned int       value ) 
202{
203    unsigned int lsb = (unsigned int)paddr;
204    unsigned int msb = (unsigned int)(paddr >> 32);
205    unsigned int sr;
206
207   _it_disable(&sr);
208
209    asm volatile( "mfc2   $2,     $1                 \n"     /* $2 <= MMU_MODE   */
210                  "andi   $3,     $2,        0xb     \n"
211                  "mtc2   $3,     $1                 \n"     /* DTLB off         */   
212
213                  "mtc2   %2,     $24                \n"     /* PADDR_EXT <= msb */   
214                  "sw     %0,     0(%1)              \n"     /* *paddr <= value  */
215                  "mtc2   $0,     $24                \n"     /* PADDR_EXT <= 0   */   
216
217                  "mtc2   $2,     $1                 \n"     /* restore MMU_MODE */
218                  "sync                              \n"
219                  :
220                  : "r" (value), "r" (lsb), "r" (msb)
221                  : "$2", "$3" );
222
223    _it_restore(&sr);
224}
225
226/////////////////////////////////////////////////////////////////
227unsigned long long _physical_read_ull( unsigned long long paddr ) 
228{
229    unsigned int data_lsb;
230    unsigned int data_msb;
231    unsigned int addr_lsb = (unsigned int) paddr;
232    unsigned int addr_msb = (unsigned int) (paddr >> 32);
233    unsigned int sr;
234
235    _it_disable(&sr);
236
237    asm volatile( "mfc2   $2,     $1                 \n"     /* $2 <= MMU_MODE       */
238                  "andi   $3,     $2,        0xb     \n"
239                  "mtc2   $3,     $1                 \n"     /* DTLB off             */   
240
241                  "mtc2   %3,     $24                \n"     /* PADDR_EXT <= msb     */   
242                  "lw     %0,     0(%2)              \n"     /* data_lsb <= *paddr   */
243                  "lw     %1,     4(%2)              \n"     /* data_msb <= *paddr+4 */
244                  "mtc2   $0,     $24                \n"     /* PADDR_EXT <= 0       */   
245
246                  "mtc2   $2,     $1                 \n"     /* restore MMU_MODE     */
247                  : "=r" (data_lsb), "=r"(data_msb)
248                  : "r" (addr_lsb), "r" (addr_msb)
249                  : "$2", "$3" );
250
251    _it_restore(&sr);
252
253    return ( (((unsigned long long)data_msb)<<32) +
254             (((unsigned long long)data_lsb)) );
255}
256
257///////////////////////////////////////////////////
258void _physical_write_ull( unsigned long long paddr, 
259                          unsigned long long value ) 
260{
261    unsigned int addr_lsb = (unsigned int)paddr;
262    unsigned int addr_msb = (unsigned int)(paddr >> 32);
263    unsigned int data_lsb = (unsigned int)value;
264    unsigned int data_msb = (unsigned int)(value >> 32);
265    unsigned int sr;
266
267    _it_disable(&sr);
268
269    asm volatile( "mfc2   $2,     $1                 \n"     /* $2 <= MMU_MODE     */
270                  "andi   $3,     $2,        0xb     \n"
271                  "mtc2   $3,     $1                 \n"     /* DTLB off           */   
272
273                  "mtc2   %3,     $24                \n"     /* PADDR_EXT <= msb   */   
274                  "sw     %0,     0(%2)              \n"     /* *paddr <= value    */
275                  "sw     %1,     4(%2)              \n"     /* *paddr+4 <= value  */
276                  "mtc2   $0,     $24                \n"     /* PADDR_EXT <= 0     */   
277
278                  "mtc2   $2,     $1                 \n"     /* restore MMU_MODE   */
279                  "sync                              \n"
280                  :
281                  : "r" (data_lsb), "r" (data_msb), "r" (addr_lsb), "r" (addr_msb)
282                  : "$2", "$3" );
283
284    _it_restore(&sr);
285}
286
287////////////////////////////////////////////////////
288void _physical_memcpy( unsigned long long dst_paddr,  // destination buffer paddr
289                       unsigned long long src_paddr,  // source buffer paddr
290                       unsigned int size )            // bytes
291{
292    // check alignment constraints
293    if ( (dst_paddr & 3) || (src_paddr & 3) || (size & 3) ) 
294    {
295        _puts("\n[GIET ERROR] in _physical_memcpy() : buffer unaligned\n");
296        _exit();
297    }
298
299    unsigned int src_lsb = (unsigned int)src_paddr;
300    unsigned int src_msb = (unsigned int)(src_paddr >> 32);
301    unsigned int dst_lsb = (unsigned int)dst_paddr;
302    unsigned int dst_msb = (unsigned int)(dst_paddr >> 32);
303    unsigned int iter    = size>>2;
304    unsigned int data;
305    unsigned int sr;
306
307    _it_disable(&sr);
308
309    asm volatile( "mfc2   $2,     $1                 \n"     /* $2 <= current MMU_MODE */
310                  "andi   $3,     $2,        0xb     \n"     /* $3 <= new MMU_MODE     */
311                  "mtc2   $3,     $1                 \n"     /* DTLB off               */   
312
313                  "move   $4,     %5                 \n"     /* $4 < iter              */
314                  "move   $5,     %1                 \n"     /* $5 < src_lsb           */
315                  "move   $6,     %3                 \n"     /* $6 < src_lsb           */
316
317                  "ph_memcpy_loop:                   \n"
318                  "mtc2   %2,     $24                \n"     /* PADDR_EXT <= src_msb   */   
319                  "lw     %0,     0($5)              \n"     /* data <= *src_paddr     */
320                  "mtc2   %4,     $24                \n"     /* PADDR_EXT <= dst_msb   */   
321                  "sw     %0,     0($6)              \n"     /* *dst_paddr <= data     */
322
323                  "addi   $4,     $4,       -1       \n"     /* iter = iter - 1        */
324                  "addi   $5,     $5,        4       \n"     /* src_lsb += 4           */
325                  "addi   $6,     $6,        4       \n"     /* dst_lsb += 4           */
326                  "bne    $4,     $0, ph_memcpy_loop \n"
327                  "nop                               \n"
328
329                  "mtc2   $0,     $24                \n"     /* PADDR_EXT <= 0         */   
330                  "mtc2   $2,     $1                 \n"     /* restore MMU_MODE       */
331                  : "=r" (data)
332                  : "r" (src_lsb), "r" (src_msb), "r" (dst_lsb), "r"(dst_msb), "r"(iter)
333                  : "$2", "$3", "$4", "$5", "$6" );
334
335    _it_restore(&sr);
336} // end _physical_memcpy()
337
338////////////////////////////////////////////////
339void _physical_memset( unsigned long long paddr,     // destination buffer paddr
340                       unsigned int       size,      // bytes
341                       unsigned int       data )     // written value
342{
343    // check alignment constraints
344    if ( (paddr & 3) || (size & 7) )
345    {
346        _puts("\n[GIET ERROR] in _physical_memset() : buffer unaligned\n");
347        _exit();
348    }
349
350    unsigned int lsb  = (unsigned int)paddr;
351    unsigned int msb  = (unsigned int)(paddr >> 32);
352    unsigned int sr;
353
354    _it_disable(&sr);
355
356    asm volatile( "mfc2   $8,     $1                 \n"     /* $8 <= current MMU_MODE */
357                  "andi   $9,     $8,        0xb     \n"     /* $9 <= new MMU_MODE     */
358                  "mtc2   $9,     $1                 \n"     /* DTLB off               */
359                  "mtc2   %3,     $24                \n"     /* PADDR_EXT <= msb       */
360
361                  "1:                                \n"     /* set 8 bytes per iter   */
362                  "sw     %2,     0(%0)              \n"     /* *src_paddr     = data  */
363                  "sw     %2,     4(%0)              \n"     /* *(src_paddr+4) = data  */
364                  "addi   %1,     %1,       -8       \n"     /* size -= 8              */
365                  "addi   %0,     %0,        8       \n"     /* src_paddr += 8         */
366                  "bnez   %1,     1b                 \n"     /* loop while size != 0   */
367
368                  "mtc2   $0,     $24                \n"     /* PADDR_EXT <= 0         */
369                  "mtc2   $8,     $1                 \n"     /* restore MMU_MODE       */
370                  : "+r"(lsb), "+r"(size)
371                  : "r"(data), "r" (msb)
372                  : "$8", "$9", "memory" );
373
374    _it_restore(&sr);
375}  // _physical_memset()
376
377///////////////////////////////////////////////
378void _io_extended_write( unsigned int*  vaddr,
379                         unsigned int   value )
380{
381    unsigned long long paddr;
382
383    if ( _get_mmu_mode() & 0x4 )  // MMU activated : use virtual address
384    {
385        *vaddr = value;
386    }
387    else                          // use paddr extension for IO
388    {
389        paddr = (unsigned long long)(unsigned int)vaddr +
390                (((unsigned long long)((X_IO<<Y_WIDTH) + Y_IO))<<32); 
391        _physical_write( paddr, value );
392    }
393    asm volatile("sync" ::: "memory");
394}
395
396//////////////////////////////////////////////////////
397unsigned int _io_extended_read( unsigned int*  vaddr )
398{
399    unsigned long long paddr;
400
401    if ( _get_mmu_mode() & 0x4 )  // MMU activated : use virtual address
402    {
403        return *(volatile unsigned int*)vaddr;
404    }
405    else                          // use paddr extension for IO
406    {
407        paddr = (unsigned long long)(unsigned int)vaddr +
408                (((unsigned long long)((X_IO<<Y_WIDTH) + Y_IO))<<32); 
409        return _physical_read( paddr );
410    }
411}
412
413///////////////////////////////////////////////////////////////////////////////////
414//                      Locks access functions
415///////////////////////////////////////////////////////////////////////////////////
416
417///////////////////////////////////
418void _get_lock( giet_lock_t* lock ) 
419{
420    register unsigned int* plock = &(lock->value);
421
422#if NO_HARD_CC
423
424    register unsigned int delay  = (_get_proctime() ^ _get_procid() << 4) & 0xFF;
425    if (delay == 0) delay = 0x80;
426
427    asm volatile (
428            "_lock_llsc:             \n"
429            "    ll   $2,    0(%0)       \n" /* $2 <= lock current value         */
430            "    bnez $2,    _lock_delay \n" /* delay if lock already taken      */
431            "    li   $3,    1           \n" /* $3 <= argument for sc            */
432            "    sc   $3,    0(%0)       \n" /* try to set lock                  */
433            "    bnez $3,    _lock_ok    \n" /* exit if atomic                   */
434            "    _lock_delay:            \n"
435            "    move $4,    %1          \n" /* $4 <= delay                      */
436            "    _lock_loop:             \n"
437            "    addi $4,    $4,    -1   \n" /* $4 <= $4 - 1                     */
438            "    bnez $4,    _lock_loop  \n" /* test end delay                   */
439            "    nop                     \n"
440            "    j           _lock_llsc  \n" /* retry                            */
441            "    nop                     \n"
442            "    _lock_ok:               \n"
443            :
444            :"r"(plock), "r"(delay)
445            :"$2", "$3", "$4", "memory");
446#else
447
448    asm volatile (
449            "_lock_llsc:                 \n"
450            "    lw   $2,    0(%0)       \n" /* $2 <= lock current value         */
451            "    bnez $2,    _lock_llsc  \n" /* retry if lock already taken      */
452            "    nop                     \n"
453            "    ll   $2,    0(%0)       \n" /* ll_buffer <= lock current value  */
454            "    bnez $2,    _lock_llsc  \n" /* retry if lock already taken      */
455            "    li   $3,    1           \n" /* $3 <= argument for sc            */
456            "    sc   $3,    0(%0)       \n" /* try to set lock                  */
457            "    beqz $3,    _lock_llsc  \n" /* retry if sc failure              */
458            "    nop                     \n"
459            :
460            :"r"(plock)
461            :"$2", "$3", "memory");
462#endif
463
464}
465
466///////////////////////////////////////
467void _release_lock( giet_lock_t* lock ) 
468{
469    asm volatile ( "sync\n" ::: "memory" ); 
470    // sync is necessary because of the TSAR consistency model
471    lock->value = 0;
472}
473
474///////////////////////////////////////////////////////////////////////////////////
475//           Access functions to kernel terminal TTY0
476///////////////////////////////////////////////////////////////////////////////////
477
478//////////////////////////
479void _puts( char* string ) 
480{
481    unsigned int n = 0;
482
483    while ( string[n] > 0 )
484    {
485        // test status register
486        while ( (_tty_get_register( 0, TTY_STATUS ) & 0x2) );
487
488        // write one byte
489        if ( string[n] == '\n') {
490            _tty_set_register( 0, TTY_WRITE, (unsigned int)'\r' );
491        }
492        _tty_set_register( 0, TTY_WRITE, (unsigned int)string[n] );
493        n++;
494    }
495}
496
497//////////////////////////////
498void _putx( unsigned int val )
499{
500    static const char HexaTab[] = "0123456789ABCDEF";
501    char buf[11];
502    unsigned int c;
503
504    buf[0] = '0';
505    buf[1] = 'x';
506    buf[10] = 0;
507
508    for (c = 0; c < 8; c++) 
509    { 
510        buf[9 - c] = HexaTab[val & 0xF];
511        val = val >> 4;
512    }
513    _puts( buf );
514}
515
516////////////////////////////////////
517void _putl( unsigned long long val )
518{
519    static const char HexaTab[] = "0123456789ABCDEF";
520    char buf[19];
521    unsigned int c;
522
523    buf[0] = '0';
524    buf[1] = 'x';
525    buf[18] = 0;
526
527    for (c = 0; c < 16; c++) 
528    { 
529        buf[17 - c] = HexaTab[(unsigned int)val & 0xF];
530        val = val >> 4;
531    }
532    _puts( buf );
533}
534
535//////////////////////////////
536void _putd( unsigned int val ) 
537{
538    static const char DecTab[] = "0123456789";
539    char buf[11];
540    unsigned int i;
541    unsigned int first = 0;
542
543    buf[10] = 0;
544
545    for (i = 0; i < 10; i++) 
546    {
547        if ((val != 0) || (i == 0)) 
548        {
549            buf[9 - i] = DecTab[val % 10];
550            first = 9 - i;
551        }
552        else 
553        {
554            break;
555        }
556        val /= 10;
557    }
558    _puts( &buf[first] );
559}
560
561/////////////////////////
562void _getc( char*  byte )
563{
564    // test status register
565    while ( _tty_get_register( 0, TTY_STATUS ) == 0 );
566
567    // read one byte
568    *byte = (char)_tty_get_register( 0, TTY_READ );
569}
570
571
572////////////////////////////////////////////////////////////////////////////////////
573//           Scheduler and tasks context access functions
574////////////////////////////////////////////////////////////////////////////////////
575
576
577///////////////////////////////////
578unsigned int _get_current_task_id() 
579{
580    static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
581    return (unsigned int) (psched->current);
582}
583
584////////////////////////////////////////////
585unsigned int _get_task_slot( unsigned int x,
586                             unsigned int y,
587                             unsigned int p,
588                             unsigned int ltid,
589                             unsigned int slot )
590{
591    static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
592    return psched->context[ltid][slot];
593}
594
595////////////////////////////////////
596void _set_task_slot( unsigned int x,
597                     unsigned int y,
598                     unsigned int p,
599                     unsigned int ltid,
600                     unsigned int slot,
601                     unsigned int value )
602{
603    static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
604    psched->context[ltid][slot] = value;
605}
606
607///////////////////////////////////////////////////
608unsigned int _get_context_slot( unsigned int slot )
609{
610    static_scheduler_t* psched  = (static_scheduler_t*)_get_sched();
611    unsigned int        task_id = psched->current;
612    return psched->context[task_id][slot];
613}
614
615///////////////////////////////////////////
616void _set_context_slot( unsigned int slot,
617                       unsigned int value )
618{
619    static_scheduler_t* psched  = (static_scheduler_t*)_get_sched();
620    unsigned int        task_id = psched->current;
621    psched->context[task_id][slot] = value;
622}
623
624/////////////////////////////////////////////////////////////////////////////
625//      Access functions to mapping_info data structure
626/////////////////////////////////////////////////////////////////////////////
627
628////////////////////////////////////////////////////////////////
629mapping_cluster_t * _get_cluster_base(mapping_header_t * header) 
630{
631    return (mapping_cluster_t *) ((char *) header +
632            MAPPING_HEADER_SIZE);
633}
634//////////////////////////////////////////////////////////
635mapping_pseg_t * _get_pseg_base(mapping_header_t * header) 
636{
637    return (mapping_pseg_t *) ((char *) header +
638            MAPPING_HEADER_SIZE +
639            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE);
640}
641//////////////////////////////////////////////////////////////
642mapping_vspace_t * _get_vspace_base(mapping_header_t * header) 
643{
644    return (mapping_vspace_t *)  ((char *) header +
645            MAPPING_HEADER_SIZE +
646            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
647            MAPPING_PSEG_SIZE * header->psegs);
648}
649//////////////////////////////////////////////////////////
650mapping_vseg_t * _get_vseg_base(mapping_header_t * header)
651{
652    return (mapping_vseg_t *) ((char *) header +
653            MAPPING_HEADER_SIZE +
654            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
655            MAPPING_PSEG_SIZE * header->psegs +
656            MAPPING_VSPACE_SIZE * header->vspaces);
657}
658//////////////////////////////////////////////////////////
659mapping_vobj_t * _get_vobj_base(mapping_header_t * header) 
660{
661    return (mapping_vobj_t *) ((char *) header +
662            MAPPING_HEADER_SIZE +
663            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
664            MAPPING_PSEG_SIZE * header->psegs +
665            MAPPING_VSPACE_SIZE * header->vspaces +
666            MAPPING_VSEG_SIZE * header->vsegs );
667}
668//////////////////////////////////////////////////////////
669mapping_task_t * _get_task_base(mapping_header_t * header) 
670{
671    return (mapping_task_t *) ((char *) header +
672            MAPPING_HEADER_SIZE +
673            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
674            MAPPING_PSEG_SIZE * header->psegs +
675            MAPPING_VSPACE_SIZE * header->vspaces +
676            MAPPING_VOBJ_SIZE * header->vobjs +
677            MAPPING_VSEG_SIZE * header->vsegs);
678}
679/////////////////////////////////////////////////////////
680mapping_proc_t *_get_proc_base(mapping_header_t * header) 
681{
682    return (mapping_proc_t *) ((char *) header +
683            MAPPING_HEADER_SIZE +
684            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
685            MAPPING_PSEG_SIZE * header->psegs +
686            MAPPING_VSPACE_SIZE * header->vspaces +
687            MAPPING_VSEG_SIZE * header->vsegs +
688            MAPPING_VOBJ_SIZE * header->vobjs +
689            MAPPING_TASK_SIZE * header->tasks);
690}
691///////////////////////////////////////////////////////
692mapping_irq_t *_get_irq_base(mapping_header_t * header) 
693{
694    return (mapping_irq_t *) ((char *) header +
695            MAPPING_HEADER_SIZE +
696            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
697            MAPPING_PSEG_SIZE * header->psegs +
698            MAPPING_VSPACE_SIZE * header->vspaces +
699            MAPPING_VSEG_SIZE * header->vsegs +
700            MAPPING_VOBJ_SIZE * header->vobjs +
701            MAPPING_TASK_SIZE * header->tasks +
702            MAPPING_PROC_SIZE * header->procs);
703}
704/////////////////////////////////////////////////////////////
705mapping_coproc_t *_get_coproc_base(mapping_header_t * header) 
706{
707    return (mapping_coproc_t *) ((char *) header +
708            MAPPING_HEADER_SIZE +
709            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
710            MAPPING_PSEG_SIZE * header->psegs +
711            MAPPING_VSPACE_SIZE * header->vspaces +
712            MAPPING_VOBJ_SIZE * header->vobjs +
713            MAPPING_VSEG_SIZE * header->vsegs +
714            MAPPING_TASK_SIZE * header->tasks +
715            MAPPING_PROC_SIZE * header->procs +
716            MAPPING_IRQ_SIZE * header->irqs);
717}
718///////////////////////////////////////////////////////////////
719mapping_cp_port_t *_get_cp_port_base(mapping_header_t * header) 
720{
721    return (mapping_cp_port_t *) ((char *) header +
722            MAPPING_HEADER_SIZE +
723            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
724            MAPPING_PSEG_SIZE * header->psegs +
725            MAPPING_VSPACE_SIZE * header->vspaces +
726            MAPPING_VOBJ_SIZE * header->vobjs +
727            MAPPING_VSEG_SIZE * header->vsegs +
728            MAPPING_TASK_SIZE * header->tasks +
729            MAPPING_PROC_SIZE * header->procs +
730            MAPPING_IRQ_SIZE * header->irqs +
731            MAPPING_COPROC_SIZE * header->coprocs);
732}
733/////////////////////////////////////////////////////////////
734mapping_periph_t *_get_periph_base(mapping_header_t * header) 
735{
736    return (mapping_periph_t *) ((char *) header +
737            MAPPING_HEADER_SIZE +
738            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
739            MAPPING_PSEG_SIZE * header->psegs +
740            MAPPING_VSPACE_SIZE * header->vspaces +
741            MAPPING_VOBJ_SIZE * header->vobjs +
742            MAPPING_VSEG_SIZE * header->vsegs +
743            MAPPING_TASK_SIZE * header->tasks +
744            MAPPING_PROC_SIZE * header->procs +
745            MAPPING_IRQ_SIZE * header->irqs +
746            MAPPING_COPROC_SIZE * header->coprocs +
747            MAPPING_CP_PORT_SIZE * header->cp_ports);
748}
749
750///////////////////////////////////////////////////////////////////////////////////
751//             Miscelaneous functions
752///////////////////////////////////////////////////////////////////////////////////
753
754//////////////////////////////////////
755__attribute__((noreturn)) void _exit() 
756{
757    unsigned int procid     = _get_procid();
758    unsigned int x          = (procid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1);
759    unsigned int y          = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
760    unsigned int lpid       = procid & ((1<<P_WIDTH)-1);
761
762
763    _puts("\n[GIET PANIC] processor[");
764    _putd( x );
765    _puts(",");
766    _putd( y );
767    _puts(",");
768    _putd( lpid );
769    _puts("] exit at cycle");
770    _putd( _get_proctime() );
771    _puts(" ...\n");
772
773    while (1) { asm volatile ("nop"); }
774}
775
776/////////////////////////////////////
777void _random_wait( unsigned int val )
778{
779    unsigned int mask  = (1<<(val&0x1F))-1;
780    unsigned int delay = (_get_proctime() ^ (_get_procid()<<4)) & mask;
781    asm volatile( "move  $3,   %0                 \n"
782                  "loop_nic_completed:            \n"
783                  "addi  $3,   $3, -1             \n"
784                  "bnez  $3,   loop_nic_completed \n"
785                  "nop                            \n"
786                  :
787                  : "r" (delay)
788                  : "$3" ); 
789}
790
791///////////////////////////
792void _break( char* string ) 
793{
794    char byte;
795
796    _puts("\n[GIET DEBUG] break from ");
797    _puts( string );
798    _puts(" / stoke any key to continue\n");
799    _getc( &byte );
800}
801
802///////////////////////////////////////
803unsigned int _strncmp( const char * s1, 
804                       const char * s2, 
805                       unsigned int n ) 
806{
807    unsigned int i;
808    for (i = 0; i < n; i++) 
809    {
810        if (s1[i] != s2[i])  return 1; 
811        if (s1[i] == 0)      break;
812    }
813    return 0;
814}
815
816/////////////////////////////////////////
817char* _strcpy( char* dest, char* source )
818{
819    if (!dest || !source) return dest;
820
821    while (*source)
822        *(dest++) = *(source++);
823
824    return dest;
825}
826
827/////////////////////////////////////////////////////
828void _dcache_buf_invalidate( unsigned int buf_vbase, 
829                             unsigned int buf_size ) 
830{
831    unsigned int offset;
832    unsigned int tmp;
833    unsigned int line_size;   // bytes
834
835    // compute data cache line size based on config register (bits 12:10)
836    asm volatile(
837                 "mfc0 %0, $16, 1" 
838                 : "=r" (tmp) );
839
840    tmp = ((tmp >> 10) & 0x7);
841    line_size = 2 << tmp;
842
843    // iterate on cache lines
844    for ( offset = 0; offset < buf_size; offset += line_size) 
845    {
846        _set_mmu_dcache_inval( buf_vbase + offset );
847    }
848}
849
850
851
852///////////////////////////////////////////////////////////////////////////////////
853//   Required by GCC
854///////////////////////////////////////////////////////////////////////////////////
855
856////////////////////////////////
857void* memcpy( void*        dest,     // dest buffer vbase
858              const void*  source,   // source buffer vbase
859              unsigned int size )    // bytes
860{
861    unsigned int* idst = (unsigned int*)dest;
862    unsigned int* isrc = (unsigned int*)source;
863
864    // word-by-word copy
865    if (!((unsigned int) idst & 3) && !((unsigned int) isrc & 3)) 
866    {
867        while (size > 3) 
868        {
869            *idst++ = *isrc++;
870            size -= 4;
871        }
872    }
873
874    unsigned char* cdst = (unsigned char*)dest;
875    unsigned char* csrc = (unsigned char*)source;
876
877    /* byte-by-byte copy */
878    while (size--) 
879    {
880        *cdst++ = *csrc++;
881    }
882    return dest;
883}
884
885/////////////////////////////////
886void * memset( void*        dst, 
887               int          value, 
888               unsigned int count ) 
889{
890    // word-by-word copy
891    unsigned int* idst = dst;
892    unsigned int  data = (((unsigned char)value)      ) |
893                         (((unsigned char)value) <<  8) |
894                         (((unsigned char)value) << 16) |
895                         (((unsigned char)value) << 24) ;
896
897    if ( ! ((unsigned int)idst & 3) )
898    {
899        while ( count > 3 )
900        {
901            *idst++ = data;
902            count -= 4;
903        }
904    }
905   
906    // byte-by-byte copy
907    unsigned char* cdst = dst;
908    while (count--) 
909    {
910        *cdst++ = (unsigned char)value;
911    }
912    return dst;
913}
914
915
916// Local Variables:
917// tab-width: 4
918// c-basic-offset: 4
919// c-file-offsets:((innamespace . 0)(inline-open . 0))
920// indent-tabs-mode: nil
921// End:
922// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
923
Note: See TracBrowser for help on using the repository browser.