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

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

1) Introducing a hierarchical, distributed lock, implemented as a

Sliced Binary Tree (sbt_lock_t) in the locks.c and locks.h files.

2) Introducing a kernel level distributed, remote_malloc() service,

In the kernel_malloc.c and kernel_malloc.h files.
This service requires one heap[x][y] global vseg per cluster.
This service is used by the distributed lock.

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