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

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

The access functions to the mapping have been modified
to comply with the removing of the coproc and cp_port objects
in the mapping_info.h file.

File size: 24.2 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
[442]598///////////////////////////////////////
[399]599unsigned int _strncmp( const char * s1, 
600                       const char * s2, 
601                       unsigned int n ) 
602{
603    unsigned int i;
604    for (i = 0; i < n; i++) 
605    {
606        if (s1[i] != s2[i])  return 1; 
607        if (s1[i] == 0)      break;
608    }
609    return 0;
610}
611
[442]612/////////////////////////////////////////
[399]613char* _strcpy( char* dest, char* source )
614{
615    if (!dest || !source) return dest;
616
617    while (*source)
618        *(dest++) = *(source++);
619
620    return dest;
621}
622
[442]623/////////////////////////////////////////////////////
[408]624void _dcache_buf_invalidate( unsigned int buf_vbase, 
625                             unsigned int buf_size ) 
[399]626{
[408]627    unsigned int offset;
[399]628    unsigned int tmp;
[408]629    unsigned int line_size;   // bytes
[399]630
631    // compute data cache line size based on config register (bits 12:10)
632    asm volatile(
633                 "mfc0 %0, $16, 1" 
634                 : "=r" (tmp) );
[408]635
[399]636    tmp = ((tmp >> 10) & 0x7);
637    line_size = 2 << tmp;
638
639    // iterate on cache lines
[408]640    for ( offset = 0; offset < buf_size; offset += line_size) 
[399]641    {
[408]642        _set_mmu_dcache_inval( buf_vbase + offset );
[399]643    }
644}
645
646
647
[495]648/////////////////////////////////////////////
649void _get_sqt_footprint( unsigned int* width,
650                         unsigned int* heigth,
651                         unsigned int* levels )
652{
653    mapping_header_t*   header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
654    mapping_cluster_t*  cluster = _get_cluster_base(header);
655
656    unsigned int x;
657    unsigned int y;
658    unsigned int cid;
659    unsigned int w = 0;
660    unsigned int h = 0;
661
662    // scan all clusters to compute SQT footprint (w,h)
663    for ( x = 0 ; x < X_SIZE ; x++ )
664    {
665        for ( y = 0 ; y < Y_SIZE ; y++ )
666        {
667            cid = x * Y_SIZE + y;
668            if ( cluster[cid].procs )  // cluster contains processors
669            {
670                if ( x > w ) w = x;
671                if ( y > h ) h = y;
672            }
673        }
674    }           
675    *width  = w + 1;
676    *heigth = h + 1;
677   
678    // compute SQT levels
679    unsigned int z = (h > w) ? h : w;
680    *levels = (z < 1) ? 1 : (z < 2) ? 2 : (z < 4) ? 3 : (z < 8) ? 4 : 5;
681}
682     
683
684
[523]685///////////////////////////////////////////////////////////////////////////
[399]686//   Required by GCC
[523]687///////////////////////////////////////////////////////////////////////////
[399]688
[442]689////////////////////////////////
[399]690void* memcpy( void*        dest,     // dest buffer vbase
691              const void*  source,   // source buffer vbase
692              unsigned int size )    // bytes
693{
694    unsigned int* idst = (unsigned int*)dest;
695    unsigned int* isrc = (unsigned int*)source;
696
697    // word-by-word copy
698    if (!((unsigned int) idst & 3) && !((unsigned int) isrc & 3)) 
699    {
700        while (size > 3) 
701        {
702            *idst++ = *isrc++;
703            size -= 4;
704        }
705    }
706
707    unsigned char* cdst = (unsigned char*)dest;
708    unsigned char* csrc = (unsigned char*)source;
709
710    /* byte-by-byte copy */
711    while (size--) 
712    {
713        *cdst++ = *csrc++;
714    }
715    return dest;
716}
[442]717
718/////////////////////////////////
719void * memset( void*        dst, 
720               int          value, 
721               unsigned int count ) 
[399]722{
723    // word-by-word copy
[442]724    unsigned int* idst = dst;
[399]725    unsigned int  data = (((unsigned char)value)      ) |
726                         (((unsigned char)value) <<  8) |
727                         (((unsigned char)value) << 16) |
728                         (((unsigned char)value) << 24) ;
729
730    if ( ! ((unsigned int)idst & 3) )
731    {
732        while ( count > 3 )
733        {
734            *idst++ = data;
735            count -= 4;
736        }
737    }
738   
739    // byte-by-byte copy
[442]740    unsigned char* cdst = dst;
[399]741    while (count--) 
742    {
743        *cdst++ = (unsigned char)value;
744    }
[442]745    return dst;
[399]746}
747
748
[258]749// Local Variables:
750// tab-width: 4
751// c-basic-offset: 4
752// c-file-offsets:((innamespace . 0)(inline-open . 0))
753// indent-tabs-mode: nil
754// End:
755// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
756
Note: See TracBrowser for help on using the repository browser.