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

Last change on this file since 595 was 594, checked in by alain, 9 years ago

1) Fix a bug in the _free() function in kernel_malloc.c
2) Introduce a strlen() function in utils.c

File size: 24.4 KB
RevLine 
[523]1///////////////////////////////////////////////////////////////////////////
[258]2// File     : utils.c
3// Date     : 18/10/2013
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
[523]6///////////////////////////////////////////////////////////////////////////
[258]7// The utils.c and utils.h files are part of the GIET-VM nano-kernel.
[523]8///////////////////////////////////////////////////////////////////////////
[258]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
[523]18// This 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
[523]21///////////////////////////////////////////////////////////////////////////
[399]22//         CP0 registers access functions
[523]23///////////////////////////////////////////////////////////////////////////
[258]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
[523]121///////////////////////////////////////////////////////////////////////////
[399]122//         CP2 registers access functions
[523]123///////////////////////////////////////////////////////////////////////////
[399]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
[523]167///////////////////////////////////////////////////////////////////////////
[258]168//          Physical addressing related functions
[523]169///////////////////////////////////////////////////////////////////////////
[258]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
[523]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
[523]185                  "mtc2   %2,     $24           \n"  /* PADDR_EXT <= msb */   
186                  "lw     %0,     0(%1)         \n"  /* value <= *paddr  */
187                  "mtc2   $0,     $24           \n"  /* PADDR_EXT <= 0   */   
[344]188
[523]189                  "mtc2   $2,     $1            \n"  /* restore MMU_MODE */
[344]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
[523]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
[523]211                  "mtc2   %2,     $24          \n"  /* PADDR_EXT <= msb */   
212                  "sw     %0,     0(%1)        \n"  /* *paddr <= value  */
213                  "mtc2   $0,     $24          \n"  /* PADDR_EXT <= 0   */   
[344]214
[523]215                  "mtc2   $2,     $1           \n"  /* restore MMU_MODE */
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
[523]235    asm volatile( "mfc2   $2,     $1           \n"  /* $2 <= MMU_MODE       */
236                  "andi   $3,     $2,    0xb   \n"
237                  "mtc2   $3,     $1           \n"  /* DTLB off             */   
[370]238
[523]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       */   
[370]243
[523]244                  "mtc2   $2,     $1           \n"  /* restore MMU_MODE     */
[370]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
[523]267    asm volatile( "mfc2   $2,     $1           \n"  /* $2 <= MMU_MODE     */
268                  "andi   $3,     $2,    0xb   \n"
269                  "mtc2   $3,     $1           \n"  /* DTLB off           */   
[370]270
[523]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     */   
[370]275
[523]276                  "mtc2   $2,     $1           \n"  /* restore MMU_MODE   */
277                  "sync                        \n"
[370]278                  :
[523]279                  : "r"(data_lsb),"r"(data_msb),"r"(addr_lsb),"r"(addr_msb)
[370]280                  : "$2", "$3" );
281
282    _it_restore(&sr);
283}
284
[442]285////////////////////////////////////////////////////
[523]286void _physical_memcpy( unsigned long long dst_paddr,  // dest 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
[523]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               */   
[344]310
[523]311                  "move   $4,     %5         \n" /* $4 < iter              */
312                  "move   $5,     %1         \n" /* $5 < src_lsb           */
313                  "move   $6,     %3         \n" /* $6 < src_lsb           */
[344]314
[523]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     */
[344]320
[523]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           */
[344]324                  "bne    $4,     $0, ph_memcpy_loop \n"
[523]325                  "nop                       \n"
[344]326
[523]327                  "mtc2   $0,     $24        \n" /* PADDR_EXT <= 0         */   
328                  "mtc2   $2,     $1         \n" /* restore MMU_MODE       */
[344]329                  : "=r" (data)
[523]330                  : "r"(src_lsb),"r"(src_msb),"r"(dst_lsb),
331                    "r"(dst_msb), "r"(iter)
[344]332                  : "$2", "$3", "$4", "$5", "$6" );
333
334    _it_restore(&sr);
[430]335} // end _physical_memcpy()
[344]336
[442]337////////////////////////////////////////////////
[523]338void _physical_memset( unsigned long long paddr,     // dest buffer paddr
[430]339                       unsigned int       size,      // bytes
340                       unsigned int       data )     // written value
341{
342    // check alignment constraints
[433]343    if ( (paddr & 3) || (size & 7) )
[430]344    {
[442]345        _puts("\n[GIET ERROR] in _physical_memset() : buffer unaligned\n");
[430]346        _exit();
347    }
348
349    unsigned int lsb  = (unsigned int)paddr;
350    unsigned int msb  = (unsigned int)(paddr >> 32);
351    unsigned int sr;
352
353    _it_disable(&sr);
354
[523]355    asm volatile( "mfc2   $8,     $1         \n" /* $8 <= current MMU_MODE */
356                  "andi   $9,     $8,   0xb  \n" /* $9 <= new MMU_MODE     */
357                  "mtc2   $9,     $1         \n" /* DTLB off               */
358                  "mtc2   %3,     $24        \n" /* PADDR_EXT <= msb       */
[430]359
[523]360                  "1:                        \n" /* set 8 bytes per iter   */
361                  "sw     %2,     0(%0)      \n" /* *src_paddr     = data  */
362                  "sw     %2,     4(%0)      \n" /* *(src_paddr+4) = data  */
363                  "addi   %1,     %1,   -8   \n" /* size -= 8              */
364                  "addi   %0,     %0,    8   \n" /* src_paddr += 8         */
365                  "bnez   %1,     1b         \n" /* loop while size != 0   */
[430]366
[523]367                  "mtc2   $0,     $24        \n" /* PADDR_EXT <= 0         */
368                  "mtc2   $8,     $1         \n" /* restore MMU_MODE       */
[433]369                  : "+r"(lsb), "+r"(size)
370                  : "r"(data), "r" (msb)
371                  : "$8", "$9", "memory" );
[430]372
373    _it_restore(&sr);
[433]374}  // _physical_memset()
[430]375
[442]376///////////////////////////////////////////////
[378]377void _io_extended_write( unsigned int*  vaddr,
[399]378                         unsigned int   value )
[295]379{
380    unsigned long long paddr;
381
382    if ( _get_mmu_mode() & 0x4 )  // MMU activated : use virtual address
383    {
384        *vaddr = value;
385    }
386    else                          // use paddr extension for IO
387    {
388        paddr = (unsigned long long)(unsigned int)vaddr +
389                (((unsigned long long)((X_IO<<Y_WIDTH) + Y_IO))<<32); 
390        _physical_write( paddr, value );
391    }
392    asm volatile("sync" ::: "memory");
393}
394
[442]395//////////////////////////////////////////////////////
[378]396unsigned int _io_extended_read( unsigned int*  vaddr )
[295]397{
398    unsigned long long paddr;
399
400    if ( _get_mmu_mode() & 0x4 )  // MMU activated : use virtual address
401    {
402        return *(volatile unsigned int*)vaddr;
403    }
404    else                          // use paddr extension for IO
405    {
406        paddr = (unsigned long long)(unsigned int)vaddr +
407                (((unsigned long long)((X_IO<<Y_WIDTH) + Y_IO))<<32); 
408        return _physical_read( paddr );
409    }
410}
411
[523]412////////////////////////////////////////////////////////////////////////////
[399]413//           Scheduler and tasks context access functions
[523]414////////////////////////////////////////////////////////////////////////////
[258]415
[430]416
[442]417///////////////////////////////////
[399]418unsigned int _get_current_task_id() 
[258]419{
[399]420    static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
421    return (unsigned int) (psched->current);
[258]422}
[442]423
424////////////////////////////////////////////
[430]425unsigned int _get_task_slot( unsigned int x,
426                             unsigned int y,
427                             unsigned int p,
[258]428                             unsigned int ltid,
429                             unsigned int slot )
430{
[430]431    static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
[258]432    return psched->context[ltid][slot];
433}
[442]434
435////////////////////////////////////
[430]436void _set_task_slot( unsigned int x,
437                     unsigned int y,
438                     unsigned int p,
[258]439                     unsigned int ltid,
440                     unsigned int slot,
441                     unsigned int value )
442{
[430]443    static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
[258]444    psched->context[ltid][slot] = value;
445}
[442]446
447///////////////////////////////////////////////////
[258]448unsigned int _get_context_slot( unsigned int slot )
449{
450    static_scheduler_t* psched  = (static_scheduler_t*)_get_sched();
451    unsigned int        task_id = psched->current;
452    return psched->context[task_id][slot];
453}
[442]454
455///////////////////////////////////////////
[258]456void _set_context_slot( unsigned int slot,
457                       unsigned int value )
458{
459    static_scheduler_t* psched  = (static_scheduler_t*)_get_sched();
460    unsigned int        task_id = psched->current;
461    psched->context[task_id][slot] = value;
462}
463
464/////////////////////////////////////////////////////////////////////////////
465//      Access functions to mapping_info data structure
466/////////////////////////////////////////////////////////////////////////////
[442]467
468////////////////////////////////////////////////////////////////
[378]469mapping_cluster_t * _get_cluster_base(mapping_header_t * header) 
[258]470{
471    return (mapping_cluster_t *) ((char *) header +
472            MAPPING_HEADER_SIZE);
473}
[442]474//////////////////////////////////////////////////////////
[378]475mapping_pseg_t * _get_pseg_base(mapping_header_t * header) 
[258]476{
477    return (mapping_pseg_t *) ((char *) header +
478            MAPPING_HEADER_SIZE +
[263]479            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE);
[258]480}
[442]481//////////////////////////////////////////////////////////////
[378]482mapping_vspace_t * _get_vspace_base(mapping_header_t * header) 
[258]483{
484    return (mapping_vspace_t *)  ((char *) header +
485            MAPPING_HEADER_SIZE +
[263]486            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
[258]487            MAPPING_PSEG_SIZE * header->psegs);
488}
[442]489//////////////////////////////////////////////////////////
[378]490mapping_vseg_t * _get_vseg_base(mapping_header_t * header)
[258]491{
492    return (mapping_vseg_t *) ((char *) header +
493            MAPPING_HEADER_SIZE +
[263]494            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
[258]495            MAPPING_PSEG_SIZE * header->psegs +
496            MAPPING_VSPACE_SIZE * header->vspaces);
497}
[442]498//////////////////////////////////////////////////////////
[378]499mapping_task_t * _get_task_base(mapping_header_t * header) 
[258]500{
501    return (mapping_task_t *) ((char *) header +
502            MAPPING_HEADER_SIZE +
[263]503            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
[258]504            MAPPING_PSEG_SIZE * header->psegs +
505            MAPPING_VSPACE_SIZE * header->vspaces +
506            MAPPING_VSEG_SIZE * header->vsegs);
507}
[442]508/////////////////////////////////////////////////////////
[378]509mapping_proc_t *_get_proc_base(mapping_header_t * header) 
[258]510{
511    return (mapping_proc_t *) ((char *) header +
512            MAPPING_HEADER_SIZE +
[263]513            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
[258]514            MAPPING_PSEG_SIZE * header->psegs +
515            MAPPING_VSPACE_SIZE * header->vspaces +
516            MAPPING_VSEG_SIZE * header->vsegs +
517            MAPPING_TASK_SIZE * header->tasks);
518}
[442]519///////////////////////////////////////////////////////
[378]520mapping_irq_t *_get_irq_base(mapping_header_t * header) 
[258]521{
522    return (mapping_irq_t *) ((char *) header +
523            MAPPING_HEADER_SIZE +
[263]524            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
[258]525            MAPPING_PSEG_SIZE * header->psegs +
526            MAPPING_VSPACE_SIZE * header->vspaces +
527            MAPPING_VSEG_SIZE * header->vsegs +
528            MAPPING_TASK_SIZE * header->tasks +
529            MAPPING_PROC_SIZE * header->procs);
530}
[442]531///////////////////////////////////////////////////////////////
[378]532mapping_periph_t *_get_periph_base(mapping_header_t * header) 
[258]533{
534    return (mapping_periph_t *) ((char *) header +
535            MAPPING_HEADER_SIZE +
[263]536            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
[258]537            MAPPING_PSEG_SIZE * header->psegs +
538            MAPPING_VSPACE_SIZE * header->vspaces +
539            MAPPING_VSEG_SIZE * header->vsegs +
540            MAPPING_TASK_SIZE * header->tasks +
541            MAPPING_PROC_SIZE * header->procs +
[523]542            MAPPING_IRQ_SIZE * header->irqs);
[258]543}
544
[523]545///////////////////////////////////////////////////////////////////////////
[442]546//             Miscelaneous functions
[523]547///////////////////////////////////////////////////////////////////////////
[399]548
[442]549//////////////////////////////////////
550__attribute__((noreturn)) void _exit() 
551{
[523]552    unsigned int procid = _get_procid();
553    unsigned int x      = (procid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1);
554    unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
555    unsigned int lpid   = procid & ((1<<P_WIDTH)-1);
[442]556
557
558    _puts("\n[GIET PANIC] processor[");
559    _putd( x );
560    _puts(",");
561    _putd( y );
562    _puts(",");
563    _putd( lpid );
[455]564    _puts("] exit at cycle ");
[442]565    _putd( _get_proctime() );
566    _puts(" ...\n");
567
568    while (1) { asm volatile ("nop"); }
569}
570
571/////////////////////////////////////
[399]572void _random_wait( unsigned int val )
573{
574    unsigned int mask  = (1<<(val&0x1F))-1;
575    unsigned int delay = (_get_proctime() ^ (_get_procid()<<4)) & mask;
576    asm volatile( "move  $3,   %0                 \n"
577                  "loop_nic_completed:            \n"
[466]578                  "nop                            \n"
[399]579                  "addi  $3,   $3, -1             \n"
580                  "bnez  $3,   loop_nic_completed \n"
581                  "nop                            \n"
582                  :
583                  : "r" (delay)
584                  : "$3" ); 
585}
[442]586
587///////////////////////////
[399]588void _break( char* string ) 
589{
590    char byte;
591
[442]592    _puts("\n[GIET DEBUG] break from ");
593    _puts( string );
594    _puts(" / stoke any key to continue\n");
[399]595    _getc( &byte );
596}
597
[594]598////////////////////////////////////
599unsigned int _strlen( char* string )
600{
601    unsigned int i = 0;
602    while ( string[i] != 0 ) i++;
603    return i;
604}
605
[442]606///////////////////////////////////////
[399]607unsigned int _strncmp( const char * s1, 
608                       const char * s2, 
609                       unsigned int n ) 
610{
611    unsigned int i;
612    for (i = 0; i < n; i++) 
613    {
614        if (s1[i] != s2[i])  return 1; 
615        if (s1[i] == 0)      break;
616    }
617    return 0;
618}
619
[442]620/////////////////////////////////////////
[399]621char* _strcpy( char* dest, char* source )
622{
623    if (!dest || !source) return dest;
624
625    while (*source)
[594]626    {
627        *(dest) = *(source);
628        dest++;
629        source++;
630    }
631    *dest = 0;
[399]632    return dest;
633}
634
[442]635/////////////////////////////////////////////////////
[408]636void _dcache_buf_invalidate( unsigned int buf_vbase, 
637                             unsigned int buf_size ) 
[399]638{
[408]639    unsigned int offset;
[399]640    unsigned int tmp;
[408]641    unsigned int line_size;   // bytes
[399]642
643    // compute data cache line size based on config register (bits 12:10)
644    asm volatile(
645                 "mfc0 %0, $16, 1" 
646                 : "=r" (tmp) );
[408]647
[399]648    tmp = ((tmp >> 10) & 0x7);
649    line_size = 2 << tmp;
650
651    // iterate on cache lines
[408]652    for ( offset = 0; offset < buf_size; offset += line_size) 
[399]653    {
[408]654        _set_mmu_dcache_inval( buf_vbase + offset );
[399]655    }
656}
657
658
659
[495]660/////////////////////////////////////////////
661void _get_sqt_footprint( unsigned int* width,
662                         unsigned int* heigth,
663                         unsigned int* levels )
664{
665    mapping_header_t*   header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
666    mapping_cluster_t*  cluster = _get_cluster_base(header);
667
668    unsigned int x;
669    unsigned int y;
670    unsigned int cid;
671    unsigned int w = 0;
672    unsigned int h = 0;
673
674    // scan all clusters to compute SQT footprint (w,h)
675    for ( x = 0 ; x < X_SIZE ; x++ )
676    {
677        for ( y = 0 ; y < Y_SIZE ; y++ )
678        {
679            cid = x * Y_SIZE + y;
680            if ( cluster[cid].procs )  // cluster contains processors
681            {
682                if ( x > w ) w = x;
683                if ( y > h ) h = y;
684            }
685        }
686    }           
687    *width  = w + 1;
688    *heigth = h + 1;
689   
690    // compute SQT levels
691    unsigned int z = (h > w) ? h : w;
692    *levels = (z < 1) ? 1 : (z < 2) ? 2 : (z < 4) ? 3 : (z < 8) ? 4 : 5;
693}
694     
695
696
[523]697///////////////////////////////////////////////////////////////////////////
[399]698//   Required by GCC
[523]699///////////////////////////////////////////////////////////////////////////
[399]700
[442]701////////////////////////////////
[399]702void* memcpy( void*        dest,     // dest buffer vbase
703              const void*  source,   // source buffer vbase
704              unsigned int size )    // bytes
705{
706    unsigned int* idst = (unsigned int*)dest;
707    unsigned int* isrc = (unsigned int*)source;
708
709    // word-by-word copy
710    if (!((unsigned int) idst & 3) && !((unsigned int) isrc & 3)) 
711    {
712        while (size > 3) 
713        {
714            *idst++ = *isrc++;
715            size -= 4;
716        }
717    }
718
719    unsigned char* cdst = (unsigned char*)dest;
720    unsigned char* csrc = (unsigned char*)source;
721
722    /* byte-by-byte copy */
723    while (size--) 
724    {
725        *cdst++ = *csrc++;
726    }
727    return dest;
728}
[442]729
730/////////////////////////////////
[594]731void* memset( void*        dst, 
732              int          value, 
733              unsigned int count ) 
[399]734{
735    // word-by-word copy
[442]736    unsigned int* idst = dst;
[399]737    unsigned int  data = (((unsigned char)value)      ) |
738                         (((unsigned char)value) <<  8) |
739                         (((unsigned char)value) << 16) |
740                         (((unsigned char)value) << 24) ;
741
742    if ( ! ((unsigned int)idst & 3) )
743    {
744        while ( count > 3 )
745        {
746            *idst++ = data;
747            count -= 4;
748        }
749    }
750   
751    // byte-by-byte copy
[442]752    unsigned char* cdst = dst;
[399]753    while (count--) 
754    {
755        *cdst++ = (unsigned char)value;
756    }
[442]757    return dst;
[399]758}
759
760
[258]761// Local Variables:
762// tab-width: 4
763// c-basic-offset: 4
764// c-file-offsets:((innamespace . 0)(inline-open . 0))
765// indent-tabs-mode: nil
766// End:
767// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
768
Note: See TracBrowser for help on using the repository browser.