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

Last change on this file since 680 was 618, checked in by guerin, 9 years ago

utils: introduce _strcmp()

File size: 24.7 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///////////////////////////////////////////////////////////////////////////
9
10#include <utils.h>
11#include <tty0.h>
12#include <giet_config.h>
13#include <hard_config.h>
14#include <mapping_info.h>
15#include <tty_driver.h>
16#include <ctx_handler.h>
17
18// This variable is allocated in the boot.c file or in kernel_init.c file
19extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
20
21///////////////////////////////////////////////////////////////////////////
22//         CP0 registers access functions
23///////////////////////////////////////////////////////////////////////////
24
25/////////////////////////
26unsigned int _get_sched() 
27{
28    unsigned int ret;
29    asm volatile( "mfc0      %0,     $4,2    \n" 
30                  : "=r"(ret) );
31    return ret;
32}
33///////////////////////
34unsigned int _get_epc() 
35{
36    unsigned int ret;
37    asm volatile( "mfc0      %0,    $14     \n"
38                  : "=r"(ret) );
39    return ret;
40}
41////////////////////////
42unsigned int _get_bvar() 
43{
44    unsigned int ret;
45    asm volatile( "mfc0      %0,    $8     \n"
46                  : "=r"(ret));
47    return ret;
48}
49//////////////////////
50unsigned int _get_cr() 
51{
52    unsigned int ret;
53    asm volatile( "mfc0      %0,    $13    \n"
54                  : "=r"(ret));
55    return ret;
56}
57//////////////////////
58unsigned int _get_sr() 
59{
60    unsigned int ret;
61    asm volatile( "mfc0      %0,     $12   \n"
62                  : "=r"(ret));
63    return ret;
64}
65//////////////////////////
66unsigned int _get_procid() 
67{
68    unsigned int ret;
69    asm volatile ( "mfc0     %0,     $15, 1  \n"
70                   :"=r" (ret) );
71    return (ret & 0xFFF);
72}
73////////////////////////////
74unsigned int _get_proctime() 
75{
76    unsigned int ret;
77    asm volatile ( "mfc0     %0,     $9      \n"
78                   :"=r" (ret) );
79    return ret;
80}
81
82/////////////////////////////////////////////
83void _it_disable( unsigned int * save_sr_ptr) 
84{
85    unsigned int sr = 0;
86    asm volatile( "li      $3,        0xFFFFFFFE    \n"
87                  "mfc0    %0,        $12           \n"
88                  "and     $3,        $3,   %0      \n" 
89                  "mtc0    $3,        $12           \n" 
90                  : "+r"(sr)
91                  :
92                  : "$3" );
93    *save_sr_ptr = sr;
94}
95//////////////////////////////////////////////
96void _it_restore( unsigned int * save_sr_ptr ) 
97{
98    unsigned int sr = *save_sr_ptr;
99    asm volatile( "mtc0    %0,        $12           \n" 
100                  :
101                  : "r"(sr)
102                  : "memory" );
103}
104
105/////////////////////////////////
106void _set_sched(unsigned int val) 
107{
108    asm volatile ( "mtc0     %0,     $4, 2          \n"
109                   :
110                   :"r" (val) );
111}
112//////////////////////////////
113void _set_sr(unsigned int val) 
114{
115    asm volatile ( "mtc0     %0,     $12            \n"
116                   :
117                   :"r" (val) );
118}
119
120
121///////////////////////////////////////////////////////////////////////////
122//         CP2 registers access functions
123///////////////////////////////////////////////////////////////////////////
124
125////////////////////////////
126unsigned int _get_mmu_ptpr() 
127{
128    unsigned int ret;
129    asm volatile( "mfc2      %0,     $0      \n"
130                  : "=r"(ret) );
131    return ret;
132}
133////////////////////////////
134unsigned int _get_mmu_mode() 
135{
136    unsigned int ret;
137    asm volatile( "mfc2      %0,     $1      \n"
138                  : "=r"(ret) );
139    return ret;
140}
141////////////////////////////////////
142void _set_mmu_ptpr(unsigned int val) 
143{
144    asm volatile ( "mtc2     %0,     $0      \n"
145                   :
146                   :"r" (val)
147                   :"memory" );
148}
149////////////////////////////////////
150void _set_mmu_mode(unsigned int val) 
151{
152    asm volatile ( "mtc2     %0,     $1      \n"
153                   :
154                   :"r" (val)
155                   :"memory" );
156}
157////////////////////////////////////////////
158void _set_mmu_dcache_inval(unsigned int val) 
159{
160    asm volatile ( "mtc2     %0,     $7      \n"
161                   :
162                   :"r" (val)
163                   :"memory" );
164}
165
166
167///////////////////////////////////////////////////////////////////////////
168//          Physical addressing related functions
169///////////////////////////////////////////////////////////////////////////
170
171///////////////////////////////////////////////////////
172unsigned int _physical_read( unsigned long long paddr ) 
173{
174    unsigned int value;
175    unsigned int lsb = (unsigned int) paddr;
176    unsigned int msb = (unsigned int) (paddr >> 32);
177    unsigned int sr;
178
179    _it_disable(&sr);
180
181    asm volatile( "mfc2   $2,     $1            \n"  /* $2 <= MMU_MODE   */
182                  "andi   $3,     $2,     0xb   \n"
183                  "mtc2   $3,     $1            \n"  /* DTLB off         */   
184
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
194    _it_restore(&sr);
195    return value;
196}
197////////////////////////////////////////////////
198void _physical_write( unsigned long long paddr, 
199                      unsigned int       value ) 
200{
201    unsigned int lsb = (unsigned int)paddr;
202    unsigned int msb = (unsigned int)(paddr >> 32);
203    unsigned int sr;
204
205   _it_disable(&sr);
206
207    asm volatile( "mfc2   $2,     $1           \n"  /* $2 <= MMU_MODE   */
208                  "andi   $3,     $2,    0xb   \n"
209                  "mtc2   $3,     $1           \n"  /* DTLB off         */   
210
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 */
216                  "sync                        \n"
217                  :
218                  : "r" (value), "r" (lsb), "r" (msb)
219                  : "$2", "$3" );
220
221    _it_restore(&sr);
222}
223
224/////////////////////////////////////////////////////////////////
225unsigned long long _physical_read_ull( unsigned long long paddr ) 
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
255///////////////////////////////////////////////////
256void _physical_write_ull( unsigned long long paddr, 
257                          unsigned long long value ) 
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
285////////////////////////////////////////////////////
286void _physical_memcpy( unsigned long long dst_paddr,  // dest buffer paddr
287                       unsigned long long src_paddr,  // source buffer paddr
288                       unsigned int size )            // bytes
289{
290    // check alignment constraints
291    if ( (dst_paddr & 3) || (src_paddr & 3) || (size & 3) ) 
292    {
293        _puts("\n[GIET ERROR] in _physical_memcpy() : buffer unaligned\n");
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),
331                    "r"(dst_msb), "r"(iter)
332                  : "$2", "$3", "$4", "$5", "$6" );
333
334    _it_restore(&sr);
335} // end _physical_memcpy()
336
337////////////////////////////////////////////////
338void _physical_memset( unsigned long long paddr,     // dest buffer paddr
339                       unsigned int       size,      // bytes
340                       unsigned int       data )     // written value
341{
342    // check alignment constraints
343    if ( (paddr & 3) || (size & 7) )
344    {
345        _puts("\n[GIET ERROR] in _physical_memset() : buffer unaligned\n");
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
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       */
359
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   */
366
367                  "mtc2   $0,     $24        \n" /* PADDR_EXT <= 0         */
368                  "mtc2   $8,     $1         \n" /* restore MMU_MODE       */
369                  : "+r"(lsb), "+r"(size)
370                  : "r"(data), "r" (msb)
371                  : "$8", "$9", "memory" );
372
373    _it_restore(&sr);
374}  // _physical_memset()
375
376///////////////////////////////////////////////
377void _io_extended_write( unsigned int*  vaddr,
378                         unsigned int   value )
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
395//////////////////////////////////////////////////////
396unsigned int _io_extended_read( unsigned int*  vaddr )
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
412////////////////////////////////////////////////////////////////////////////
413//           Scheduler and tasks context access functions
414////////////////////////////////////////////////////////////////////////////
415
416
417///////////////////////////////////
418unsigned int _get_current_task_id() 
419{
420    static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
421    return (unsigned int) (psched->current);
422}
423
424////////////////////////////////////////////
425unsigned int _get_task_slot( unsigned int x,
426                             unsigned int y,
427                             unsigned int p,
428                             unsigned int ltid,
429                             unsigned int slot )
430{
431    static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
432    return psched->context[ltid][slot];
433}
434
435////////////////////////////////////
436void _set_task_slot( unsigned int x,
437                     unsigned int y,
438                     unsigned int p,
439                     unsigned int ltid,
440                     unsigned int slot,
441                     unsigned int value )
442{
443    static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
444    psched->context[ltid][slot] = value;
445}
446
447///////////////////////////////////////////////////
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}
454
455///////////////////////////////////////////
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/////////////////////////////////////////////////////////////////////////////
467
468////////////////////////////////////////////////////////////////
469mapping_cluster_t * _get_cluster_base(mapping_header_t * header) 
470{
471    return (mapping_cluster_t *) ((char *) header +
472            MAPPING_HEADER_SIZE);
473}
474//////////////////////////////////////////////////////////
475mapping_pseg_t * _get_pseg_base(mapping_header_t * header) 
476{
477    return (mapping_pseg_t *) ((char *) header +
478            MAPPING_HEADER_SIZE +
479            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE);
480}
481//////////////////////////////////////////////////////////////
482mapping_vspace_t * _get_vspace_base(mapping_header_t * header) 
483{
484    return (mapping_vspace_t *)  ((char *) header +
485            MAPPING_HEADER_SIZE +
486            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
487            MAPPING_PSEG_SIZE * header->psegs);
488}
489//////////////////////////////////////////////////////////
490mapping_vseg_t * _get_vseg_base(mapping_header_t * header)
491{
492    return (mapping_vseg_t *) ((char *) header +
493            MAPPING_HEADER_SIZE +
494            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
495            MAPPING_PSEG_SIZE * header->psegs +
496            MAPPING_VSPACE_SIZE * header->vspaces);
497}
498//////////////////////////////////////////////////////////
499mapping_task_t * _get_task_base(mapping_header_t * header) 
500{
501    return (mapping_task_t *) ((char *) header +
502            MAPPING_HEADER_SIZE +
503            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
504            MAPPING_PSEG_SIZE * header->psegs +
505            MAPPING_VSPACE_SIZE * header->vspaces +
506            MAPPING_VSEG_SIZE * header->vsegs);
507}
508/////////////////////////////////////////////////////////
509mapping_proc_t *_get_proc_base(mapping_header_t * header) 
510{
511    return (mapping_proc_t *) ((char *) header +
512            MAPPING_HEADER_SIZE +
513            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
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}
519///////////////////////////////////////////////////////
520mapping_irq_t *_get_irq_base(mapping_header_t * header) 
521{
522    return (mapping_irq_t *) ((char *) header +
523            MAPPING_HEADER_SIZE +
524            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
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}
531///////////////////////////////////////////////////////////////
532mapping_periph_t *_get_periph_base(mapping_header_t * header) 
533{
534    return (mapping_periph_t *) ((char *) header +
535            MAPPING_HEADER_SIZE +
536            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
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 +
542            MAPPING_IRQ_SIZE * header->irqs);
543}
544
545///////////////////////////////////////////////////////////////////////////
546//             Miscelaneous functions
547///////////////////////////////////////////////////////////////////////////
548
549//////////////////////////////////////
550__attribute__((noreturn)) void _exit() 
551{
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);
556
557
558    _puts("\n[GIET PANIC] processor[");
559    _putd( x );
560    _puts(",");
561    _putd( y );
562    _puts(",");
563    _putd( lpid );
564    _puts("] exit at cycle ");
565    _putd( _get_proctime() );
566    _puts(" ...\n");
567
568    while (1) { asm volatile ("nop"); }
569}
570
571/////////////////////////////////////
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"
578                  "nop                            \n"
579                  "addi  $3,   $3, -1             \n"
580                  "bnez  $3,   loop_nic_completed \n"
581                  "nop                            \n"
582                  :
583                  : "r" (delay)
584                  : "$3" ); 
585}
586
587///////////////////////////
588void _break( char* string ) 
589{
590    char byte;
591
592    _puts("\n[GIET DEBUG] break from ");
593    _puts( string );
594    _puts(" / stoke any key to continue\n");
595    _getc( &byte );
596}
597
598////////////////////////////////////
599unsigned int _strlen( char* string )
600{
601    unsigned int i = 0;
602    while ( string[i] != 0 ) i++;
603    return i;
604}
605
606///////////////////////////////////////
607unsigned int _strcmp( const char * s1,
608                      const char * s2 )
609{
610    while (1)
611    {
612        if (*s1 != *s2) return 1;
613        if (*s1 == 0)   break;
614        s1++, s2++;
615    }
616    return 0;
617}
618
619///////////////////////////////////////
620unsigned int _strncmp( const char * s1, 
621                       const char * s2, 
622                       unsigned int n ) 
623{
624    unsigned int i;
625    for (i = 0; i < n; i++) 
626    {
627        if (s1[i] != s2[i])  return 1; 
628        if (s1[i] == 0)      break;
629    }
630    return 0;
631}
632
633/////////////////////////////////////////
634char* _strcpy( char* dest, char* source )
635{
636    if (!dest || !source) return dest;
637
638    while (*source)
639    {
640        *(dest) = *(source);
641        dest++;
642        source++;
643    }
644    *dest = 0;
645    return dest;
646}
647
648/////////////////////////////////////////////////////
649void _dcache_buf_invalidate( unsigned int buf_vbase, 
650                             unsigned int buf_size ) 
651{
652    unsigned int offset;
653    unsigned int tmp;
654    unsigned int line_size;   // bytes
655
656    // compute data cache line size based on config register (bits 12:10)
657    asm volatile(
658                 "mfc0 %0, $16, 1" 
659                 : "=r" (tmp) );
660
661    tmp = ((tmp >> 10) & 0x7);
662    line_size = 2 << tmp;
663
664    // iterate on cache lines
665    for ( offset = 0; offset < buf_size; offset += line_size) 
666    {
667        _set_mmu_dcache_inval( buf_vbase + offset );
668    }
669}
670
671
672
673/////////////////////////////////////////////
674void _get_sqt_footprint( unsigned int* width,
675                         unsigned int* heigth,
676                         unsigned int* levels )
677{
678    mapping_header_t*   header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
679    mapping_cluster_t*  cluster = _get_cluster_base(header);
680
681    unsigned int x;
682    unsigned int y;
683    unsigned int cid;
684    unsigned int w = 0;
685    unsigned int h = 0;
686
687    // scan all clusters to compute SQT footprint (w,h)
688    for ( x = 0 ; x < X_SIZE ; x++ )
689    {
690        for ( y = 0 ; y < Y_SIZE ; y++ )
691        {
692            cid = x * Y_SIZE + y;
693            if ( cluster[cid].procs )  // cluster contains processors
694            {
695                if ( x > w ) w = x;
696                if ( y > h ) h = y;
697            }
698        }
699    }           
700    *width  = w + 1;
701    *heigth = h + 1;
702   
703    // compute SQT levels
704    unsigned int z = (h > w) ? h : w;
705    *levels = (z < 1) ? 1 : (z < 2) ? 2 : (z < 4) ? 3 : (z < 8) ? 4 : 5;
706}
707     
708
709
710///////////////////////////////////////////////////////////////////////////
711//   Required by GCC
712///////////////////////////////////////////////////////////////////////////
713
714////////////////////////////////
715void* memcpy( void*        dest,     // dest buffer vbase
716              const void*  source,   // source buffer vbase
717              unsigned int size )    // bytes
718{
719    unsigned int* idst = (unsigned int*)dest;
720    unsigned int* isrc = (unsigned int*)source;
721
722    // word-by-word copy
723    if (!((unsigned int) idst & 3) && !((unsigned int) isrc & 3)) 
724    {
725        while (size > 3) 
726        {
727            *idst++ = *isrc++;
728            size -= 4;
729        }
730    }
731
732    unsigned char* cdst = (unsigned char*)dest;
733    unsigned char* csrc = (unsigned char*)source;
734
735    /* byte-by-byte copy */
736    while (size--) 
737    {
738        *cdst++ = *csrc++;
739    }
740    return dest;
741}
742
743/////////////////////////////////
744void* memset( void*        dst, 
745              int          value, 
746              unsigned int count ) 
747{
748    // word-by-word copy
749    unsigned int* idst = dst;
750    unsigned int  data = (((unsigned char)value)      ) |
751                         (((unsigned char)value) <<  8) |
752                         (((unsigned char)value) << 16) |
753                         (((unsigned char)value) << 24) ;
754
755    if ( ! ((unsigned int)idst & 3) )
756    {
757        while ( count > 3 )
758        {
759            *idst++ = data;
760            count -= 4;
761        }
762    }
763   
764    // byte-by-byte copy
765    unsigned char* cdst = dst;
766    while (count--) 
767    {
768        *cdst++ = (unsigned char)value;
769    }
770    return dst;
771}
772
773
774// Local Variables:
775// tab-width: 4
776// c-basic-offset: 4
777// c-file-offsets:((innamespace . 0)(inline-open . 0))
778// indent-tabs-mode: nil
779// End:
780// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
781
Note: See TracBrowser for help on using the repository browser.