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

Last change on this file since 566 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
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 _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
612/////////////////////////////////////////
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
623/////////////////////////////////////////////////////
624void _dcache_buf_invalidate( unsigned int buf_vbase, 
625                             unsigned int buf_size ) 
626{
627    unsigned int offset;
628    unsigned int tmp;
629    unsigned int line_size;   // bytes
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) );
635
636    tmp = ((tmp >> 10) & 0x7);
637    line_size = 2 << tmp;
638
639    // iterate on cache lines
640    for ( offset = 0; offset < buf_size; offset += line_size) 
641    {
642        _set_mmu_dcache_inval( buf_vbase + offset );
643    }
644}
645
646
647
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
685///////////////////////////////////////////////////////////////////////////
686//   Required by GCC
687///////////////////////////////////////////////////////////////////////////
688
689////////////////////////////////
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}
717
718/////////////////////////////////
719void * memset( void*        dst, 
720               int          value, 
721               unsigned int count ) 
722{
723    // word-by-word copy
724    unsigned int* idst = dst;
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
740    unsigned char* cdst = dst;
741    while (count--) 
742    {
743        *cdst++ = (unsigned char)value;
744    }
745    return dst;
746}
747
748
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.