source: soft/giet_vm/giet_kernel/sys_handler.c @ 528

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

1) Introducing support for external IRQs dynamic routing.
2) Simplifying the _v2p_translate() function.
3) Removing the generic IOC driver (integrated in the FAT library).

  • Property svn:executable set to *
File size: 56.5 KB
RevLine 
[258]1///////////////////////////////////////////////////////////////////////////////////
2// File     : sys_handler.c
3// Date     : 01/04/2012
4// Author   : alain greiner and joel porquet
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7
8#include <sys_handler.h>
9#include <tty_driver.h>
10#include <tim_driver.h>
11#include <ioc_driver.h>
12#include <nic_driver.h>
[440]13#include <mmc_driver.h>
[519]14#include <mwr_driver.h>
[440]15#include <cma_driver.h>
[258]16#include <ctx_handler.h>
17#include <fat32.h>
18#include <utils.h>
[478]19#include <kernel_malloc.h>
[459]20#include <tty0.h>
[396]21#include <vmem.h>
[322]22#include <hard_config.h>
[258]23#include <giet_config.h>
24#include <mapping_info.h>
[519]25#include <io.h>
[258]26
[322]27#if !defined(SEG_BOOT_MAPPING_BASE)
28# error: You must define SEG_BOOT_MAPPING_BASE in the hard_config.h file
29#endif
30
[449]31#if !defined(NB_TTY_CHANNELS)
32# error: You must define NB_TTY_CHANNELS in the hard_config.h file
33#endif
34
[459]35#if (NB_TTY_CHANNELS < 1)
36# error: NB_TTY_CHANNELS cannot be smaller than 1!
37#endif
38
[449]39#if !defined(NB_TIM_CHANNELS)
40# error: You must define NB_TIM_CHANNELS in the hard_config.h file
41#endif
42
43#if !defined(NB_NIC_CHANNELS)
44# error: You must define NB_NIC_CHANNELS in the hard_config.h file
45#endif
46
47#if !defined(NB_CMA_CHANNELS)
48# error: You must define NB_CMA_CHANNELS in the hard_config.h file
49#endif
50
[478]51#if !defined(GIET_NO_HARD_CC)
52# error: You must define GIET_NO_HARD_CC in the giet_config.h file
[449]53#endif
54
[478]55#if !defined ( GIET_NIC_MAC4 )
56# error: You must define GIET_NIC_MAC4 in the giet_config.h file
[449]57#endif
58
[478]59#if !defined ( GIET_NIC_MAC2 )
60# error: You must define GIET_NIC_MAC2 in the giet_config.h file
[449]61#endif
62
[258]63////////////////////////////////////////////////////////////////////////////
[528]64//        Extern variables
[519]65////////////////////////////////////////////////////////////////////////////
66
[528]67// allocated in tty0.c file.
68extern sqt_lock_t _tty0_sqt_lock;
[519]69
[528]70// allocated in mwr_driver.c file.
71extern simple_lock_t  _coproc_lock[X_SIZE*Y_SIZE];
72extern unsigned int   _coproc_done[X_SIZE*Y_SIZE];
[519]73
[528]74// allocated in tty_driver.c file.
75extern unsigned int _tty_rx_full[NB_TTY_CHANNELS];
76extern unsigned int _tty_rx_buf[NB_TTY_CHANNELS];
77
[519]78////////////////////////////////////////////////////////////////////////////
[440]79//     Channel allocators for peripherals
80//     (TTY[0] is reserved for kernel)
81////////////////////////////////////////////////////////////////////////////
82
[494]83__attribute__((section(".kdata")))
[478]84unsigned int _tty_channel_allocator    = 1;
[494]85
86__attribute__((section(".kdata")))
[478]87unsigned int _tim_channel_allocator    = 0;
[494]88
89__attribute__((section(".kdata")))
[478]90unsigned int _cma_channel_allocator    = 0;
[494]91
92__attribute__((section(".kdata")))
[449]93unsigned int _nic_rx_channel_allocator = 0;
[494]94
95__attribute__((section(".kdata")))
[449]96unsigned int _nic_tx_channel_allocator = 0;
[440]97
98////////////////////////////////////////////////////////////////////////////
[478]99//     NIC_RX and NIC_TX chbuf arrays
[449]100////////////////////////////////////////////////////////////////////////////
101
[494]102__attribute__((section(".kdata")))
[459]103nic_chbuf_t  _nic_rx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64)));
104
[494]105__attribute__((section(".kdata")))
[459]106nic_chbuf_t  _nic_tx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64)));
107
[478]108////////////////////////////////////////////////////////////////////////////
109// FBF related chbuf descriptors array, indexed by the CMA channel index.
110// Physical addresses of these chbuf descriptors required for L2 cache sync.
111////////////////////////////////////////////////////////////////////////////
[459]112
[494]113__attribute__((section(".kdata")))
[478]114fbf_chbuf_t _fbf_chbuf[NB_CMA_CHANNELS] __attribute__((aligned(64)));
[459]115
[494]116__attribute__((section(".kdata")))
[478]117unsigned long long _fbf_chbuf_paddr[NB_CMA_CHANNELS];
118
[449]119////////////////////////////////////////////////////////////////////////////
[258]120//    Initialize the syscall vector with syscall handlers
121// Note: This array must be synchronised with the define in file stdio.h
122////////////////////////////////////////////////////////////////////////////
[494]123
124__attribute__((section(".kdata")))
[258]125const void * _syscall_vector[64] = 
126{
[519]127    &_sys_proc_xyp,             /* 0x00 */
128    &_get_proctime,             /* 0x01 */
129    &_sys_tty_write,            /* 0x02 */
130    &_sys_tty_read,             /* 0x03 */
131    &_sys_tty_alloc,            /* 0x04 */
132    &_sys_tty_get_lock,         /* 0x05 */
133    &_sys_tty_release_lock,     /* 0x06 */
134    &_sys_heap_info,            /* 0x07 */
135    &_sys_local_task_id,        /* 0x08 */
136    &_sys_global_task_id,       /* 0x09 */ 
137    &_sys_fbf_cma_alloc,        /* 0x0A */
138    &_sys_fbf_cma_start,        /* 0x0B */
139    &_sys_fbf_cma_display,      /* 0x0C */
140    &_sys_fbf_cma_stop,         /* 0x0D */
141    &_sys_task_exit,            /* 0x0E */
142    &_sys_procs_number,         /* 0x0F */
[258]143
[519]144    &_sys_fbf_sync_write,       /* 0x10 */
145    &_sys_fbf_sync_read,        /* 0x11 */
146    &_sys_thread_id,            /* 0x12 */
147    &_sys_ukn,                  /* 0x13 */
148    &_sys_tim_alloc,            /* 0x14 */
149    &_sys_tim_start,            /* 0x15 */ 
150    &_sys_tim_stop,             /* 0x16 */
151    &_sys_ukn,                  /* 0x17 */
152    &_sys_ukn,                  /* 0x18 */   
[528]153    &_sys_context_switch,       /* 0x19 */
[519]154    &_sys_vseg_get_vbase,       /* 0x1A */
155    &_sys_vseg_get_length,      /* 0x1B */
156    &_sys_xy_from_ptr,          /* 0x1C */
157    &_sys_ukn,                  /* 0x1D */
158    &_sys_ukn,                  /* 0x1E */
159    &_sys_ukn,                  /* 0x1F */
[258]160
[519]161    &_fat_user_open,            /* 0x20 */
162    &_fat_user_read,            /* 0x21 */
163    &_fat_user_write,           /* 0x22 */
164    &_fat_user_lseek,           /* 0x23 */
165    &_fat_fstat,                /* 0x24 */
166    &_fat_close,                /* 0x25 */
167    &_sys_ukn,                  /* 0x26 */
168    &_sys_ukn,                  /* 0x27 */
169    &_sys_ukn,                  /* 0x28 */
170    &_sys_ukn,                  /* 0x29 */
171    &_sys_ukn,                  /* 0x2A */
172    &_sys_ukn,                  /* 0x2B */
173    &_sys_ukn,                  /* 0x2C */
174    &_sys_ukn,                  /* 0x2D */
175    &_sys_ukn,                  /* 0x2E */
176    &_sys_ukn,                  /* 0x2F */
[258]177
[519]178    &_sys_nic_alloc,            /* 0x30 */
179    &_sys_nic_start,            /* 0x31 */
180    &_sys_nic_move,             /* 0x32 */
181    &_sys_nic_stop,             /* 0x33 */
182    &_sys_nic_stats,            /* 0x34 */
183    &_sys_nic_clear,            /* 0x35 */ 
184    &_sys_ukn,                  /* 0x36 */
185    &_sys_ukn,                  /* 0x37 */
186    &_sys_coproc_register_get,  /* 0x38 */   
187    &_sys_coproc_register_set,  /* 0x39 */
188    &_sys_coproc_release,       /* 0x3A */
189    &_sys_coproc_completed,     /* 0x3B */
190    &_sys_coproc_alloc,         /* 0x3C */
191    &_sys_coproc_channel_init,  /* 0x3D */
192    &_sys_coproc_channel_start, /* 0x3E */
193    &_sys_coproc_channel_stop,  /* 0x3F */
[258]194};
195
[459]196
[258]197//////////////////////////////////////////////////////////////////////////////
[519]198//           Coprocessors related syscall handlers
199//////////////////////////////////////////////////////////////////////////////
200
201///////////////////////////////////////////////////////
202int _sys_coproc_register_set( unsigned int  cluster_xy,
203                              unsigned int  reg_index,
204                              unsigned int  value )
205{
206    // TODO checking coprocessor ownership...
207
208    _mwr_set_coproc_register( cluster_xy , reg_index , value );
209    return 0;
210} 
211
212///////////////////////////////////////////////////////
213int _sys_coproc_register_get( unsigned int   cluster_xy,
214                              unsigned int   reg_index,
215                              unsigned int*  buffer )
216{
217    // TODO checking coprocessor ownership...
218
219    *buffer = _mwr_get_coproc_register( cluster_xy , reg_index );
220    return 0;
221} 
222
223//////////////////////////////////////////////////
224int _sys_coproc_alloc( unsigned int   coproc_type,
225                       unsigned int*  coproc_info,
226                       unsigned int*  cluster_xy )
227{
228    // In this implementation, the allocation policy is constrained:
229    // the coprocessor must be in the same cluster as the calling task,
230    // and ther is at most one coprocessor per cluster
231
232    mapping_header_t  * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
233    mapping_cluster_t * cluster = _get_cluster_base(header);
234    mapping_periph_t  * periph  = _get_periph_base(header);
235
236    // get cluster coordinates and cluster global index
237    unsigned int procid     = _get_procid();
238    unsigned int x          = procid >> (Y_WIDTH + P_WIDTH);
239    unsigned int y          = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
240    unsigned int cluster_id = x*Y_SIZE + y;
241 
242    // search coprocessor in cluster
243    mapping_periph_t*  found = NULL;
244    unsigned int min   = cluster[cluster_id].periph_offset;
245    unsigned int max   = min + cluster[cluster_id].periphs;
246    unsigned int periph_id;
247    for ( periph_id = min ; periph_id < max ; periph_id++ )
248    {
249        if ( (periph[periph_id].type == PERIPH_TYPE_MWR) &&
250             (periph[periph_id].subtype == coproc_type) )
251        {
252            found = &periph[periph_id];
253            break;
254        }
255    } 
256
257    if ( found != NULL )
258    {
259        // get the lock (at most one coproc per cluster)
260        _simple_lock_acquire( &_coproc_lock[cluster_id] );
261 
262        // returns coprocessor info
263        *coproc_info = (found->arg0 & 0xFF)     |
264                       (found->arg1 & 0xFF)<<8  |
265                       (found->arg2 & 0xFF)<<16 |
266                       (found->arg3 & 0xFF)<<24 ;
267        *cluster_xy = (x<<Y_WIDTH) + y;
268
269#if GIET_DEBUG_COPROC
270_printf("\n[GIET DEBUG COPROC] _sys_coproc_alloc() in cluster[%d,%d]\n"
271        "  coproc_info = %x / cluster_xy = %x\n",
272        x , y , *coproc_info , *cluster_xy );
273#endif
274        return 0;
275    }
276    else
277    {
278         _printf("\n[GIET_ERROR] in _sys_coproc_alloc(): no coprocessor "
279                 " with type %d available in cluster[%d,%d]\n",
280                 coproc_type , x , y );
281        return -1;
282    }
283}  // end _sys_coproc_alloc()
284
285//////////////////////////////////////////////////
286int _sys_coproc_release( unsigned int cluster_xy )
287{
288    // TODO checking coprocessor ownership...
289
290    // check cluster coordinates
291    unsigned int cx     = cluster_xy >> Y_WIDTH;
292    unsigned int cy     = cluster_xy & ((1<<Y_WIDTH)-1);
293    unsigned int procid = _get_procid();
294    unsigned int x      = procid >> (Y_WIDTH + P_WIDTH);
295    unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
296    if ( (x != cx) || (y != cy) )
297    {
298         _printf("\n[GIET_ERROR] in _sys_coproc_channel_init(): "
299                 "wrong cluster coordinates\n");
300         return -1;
301    }
302
303    // compute coprocessor global index
304    unsigned int coproc_id = x * Y_SIZE + y;
305
306    // release coprocessor
307    _simple_lock_release( &_coproc_lock[coproc_id] );
308
309#if GIET_DEBUG_COPROC
310_printf("\n[GIET DEBUG COPROC] _sys_coproc_release() in cluster[%d,%d]\n",
311        x, y );
312#endif
313
314    return 0;
315}  // end _sys_coproc_release()
316
317/////////////////////////////////////////////////////////////////
318int _sys_coproc_channel_init( unsigned int            cluster_xy,
319                              unsigned int            channel,
320                              giet_coproc_channel_t*  desc )
321{
322    // TODO checking coprocessor ownership...
323
324    // check cluster coordinates
325    unsigned int cx     = cluster_xy >> Y_WIDTH;
326    unsigned int cy     = cluster_xy & ((1<<Y_WIDTH)-1);
327    unsigned int procid = _get_procid();
328    unsigned int x      = procid >> (Y_WIDTH + P_WIDTH);
329    unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
330    if ( (x != cx) || (y != cy) )
331    {
332         _printf("\n[GIET_ERROR] in _sys_coproc_channel_init(): "
333                 "wrong cluster coordinates\n");
334         return -1;
335    }
336
337    // check channel mode
338    unsigned mode = desc->channel_mode;
339    if ( (mode != MODE_MWMR) && 
340         (mode != MODE_DMA_IRQ) && 
341         (mode != MODE_DMA_NO_IRQ) )
342    {
343         _printf("\n[GIET_ERROR] in _sys_coproc_channel_init():"
344                 " illegal mode\n");
345         return -1;
346    }
347
348    // get memory buffer size
349    unsigned int size = desc->buffer_size;
350 
[528]351    // physical addresses
[519]352    unsigned long long buffer_paddr;
353    unsigned int       buffer_lsb;
354    unsigned int       buffer_msb;
355    unsigned long long mwmr_paddr;
356    unsigned int       mwmr_lsb;
357    unsigned int       mwmr_msb;
358    unsigned long long lock_paddr;
359    unsigned int       lock_lsb;
360    unsigned int       lock_msb;
361
[528]362    unsigned int       flags;     // unused
363
[519]364    // compute memory buffer physical address
[528]365    buffer_paddr = _v2p_translate( desc->buffer_vaddr , &flags );
366    buffer_lsb   = (unsigned int)buffer_paddr;
367    buffer_msb   = (unsigned int)(buffer_paddr>>32); 
[519]368
369    // call MWMR_DMA driver
370    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_MODE, mode ); 
371    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_SIZE, size ); 
372    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_BUFFER_LSB, buffer_lsb ); 
373    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_BUFFER_MSB, buffer_msb ); 
374                       
375    if ( mode == MODE_MWMR )
376    {
[528]377        // compute MWMR descriptor physical address
378        mwmr_paddr = _v2p_translate( desc->mwmr_vaddr , &flags );
[519]379        mwmr_lsb = (unsigned int)mwmr_paddr;
380        mwmr_msb = (unsigned int)(mwmr_paddr>>32); 
381
[528]382        // call MWMR_DMA driver
383        _mwr_set_channel_register( cluster_xy, channel, CHANNEL_MWMR_LSB, mwmr_lsb ); 
384        _mwr_set_channel_register( cluster_xy, channel, CHANNEL_MWMR_MSB, mwmr_msb ); 
385
386        // compute lock physical address
387        lock_paddr = _v2p_translate( desc->lock_vaddr , &flags );
[519]388        lock_lsb = (unsigned int)lock_paddr;
389        lock_msb = (unsigned int)(lock_paddr>>32); 
390
391        // call MWMR_DMA driver
392        _mwr_set_channel_register( cluster_xy, channel, CHANNEL_LOCK_LSB, lock_lsb ); 
393        _mwr_set_channel_register( cluster_xy, channel, CHANNEL_LOCK_MSB, lock_msb ); 
394    }
395
396#if GIET_DEBUG_COPROC
397_printf("\n[GIET DEBUG COPROC] _sys_coproc_channel_init() in cluster[%d,%d]\n"
398        " channel =  %d / mode = %d / buffer_size = %d\n"
399        " buffer_paddr = %l / mwmr_paddr = %l / lock_paddr = %l\n",
400        x , y , channel , mode , size ,
401        buffer_paddr, mwmr_paddr, lock_paddr );
402#endif
403       
404    return 0;
405} // end _sys_coproc_channel_init()
406
407////////////////////////////////////////////////////////
408int _sys_coproc_channel_start( unsigned int  cluster_xy,
409                               unsigned int  channel )
410{
411    // TODO checking coprocessor ownership...
412
413    // check cluster coordinates
414    unsigned int cx     = cluster_xy >> Y_WIDTH;
415    unsigned int cy     = cluster_xy & ((1<<Y_WIDTH)-1);
416    unsigned int procid = _get_procid();
417    unsigned int x      = procid >> (Y_WIDTH + P_WIDTH);
418    unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
419    if ( (x != cx) || (y != cy) )
420    {
421         _printf("\n[GIET_ERROR] in _sys_coproc_channel_start():"
422                 " wrong coordinates\n");
423         return -1;
424    }
425 
426    // reset synchronisation variable
427    unsigned int coproc_id = (x * Y_SIZE) + y;
428    _coproc_done[coproc_id] = 0;
429
430    // call MWMR_DMA driver
431    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_RUNNING, 1 ); 
432
433#if GIET_DEBUG_COPROC
434_printf("\n[GIET DEBUG COPROC] _sys_coproc_channel_start() in cluster[%d,%d]"
435        " / channel = %d\n", x , y , channel );
436#endif
437
438    return 0;
439} // end _sys_coproc_channel_start()
440
441///////////////////////////////////////////////////////
442int _sys_coproc_channel_stop( unsigned int  cluster_xy,
443                              unsigned int  channel )
444{
445    // TODO checking coprocessor ownership...
446
447    // check cluster coordinates
448    unsigned int cx     = cluster_xy >> Y_WIDTH;
449    unsigned int cy     = cluster_xy & ((1<<Y_WIDTH)-1);
450    unsigned int procid = _get_procid();
451    unsigned int x      = procid >> (Y_WIDTH + P_WIDTH);
452    unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
453    if ( (x != cx) || (y != cy) )
454    {
455         _printf("\n[GIET_ERROR] in _sys_coproc_channel_stop(): wrong coordinates\n");
456         return -1;
457    }
458 
459    // call MWMR_DMA driver
460    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_RUNNING, 0 );
461
462#if GIET_DEBUG_COPROC
463_printf("\n[GIET DEBUG COPROC] _sys_coproc_channel_stop() in cluster[%d,%d]"
464        " / channel = %d\n", x , y , channel );
465#endif
466
467    return 0;
468} // end _sys_coproc_channel_stop()
469
470/////////////////////////////////////////////////////
471int _sys_coproc_completed( unsigned int  cluster_xy )
472{
473    // TODO checking coprocessor ownership...
474
475    // check cluster coordinates
476    unsigned int cx     = cluster_xy >> Y_WIDTH;
477    unsigned int cy     = cluster_xy & ((1<<Y_WIDTH)-1);
478    unsigned int procid = _get_procid();
479    unsigned int x      = procid >> (Y_WIDTH + P_WIDTH);
480    unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
481    if ( (x != cx) || (y != cy) )
482    {
483         _printf("\n[GIET_ERROR] in _sys_coproc_completed(): "
484                 "wrong cluster coordinates\n");
485         return -1;
486    }
487 
488    // polling the synchronisation variable
489    unsigned int coproc_id = (x * Y_SIZE) + y;
490    while ( ioread32( &_coproc_done[coproc_id]) == 0 ) asm volatile("nop");
491
492    _coproc_done[coproc_id] = 0;
493
494#if GIET_DEBUG_COPROC
495_printf("\n[GIET DEBUG COPROC] _sys_coproc_completed() in cluster[%d,%d]\n", 
496        x, y );
497#endif
498
499    return 0;
500} // end _sys_coproc_completed()
501
502
503//////////////////////////////////////////////////////////////////////////////
[440]504//             TTY related syscall handlers
[258]505//////////////////////////////////////////////////////////////////////////////
[440]506
507////////////////////
508int _sys_tty_alloc()
[258]509{
[440]510    // get a new TTY terminal index
[459]511    unsigned int channel = _atomic_increment( &_tty_channel_allocator, 1 );
[440]512
513    if ( channel >= NB_TTY_CHANNELS )
514    {
515        _printf("\n[GIET_ERROR] in _sys_tty_alloc() : not enough TTY channels\n");
516        return -1;
517    }
518    else
519    {
[449]520        _set_context_slot( CTX_TTY_ID, channel );
521        return 0;
[440]522    }
[258]523}
524
[440]525/////////////////////////////////////////////////
526int _sys_tty_write( const char*  buffer,   
527                    unsigned int length,    // number of characters
528                    unsigned int channel)   // channel index
529{
530    unsigned int  nwritten;
531
532    // compute and check tty channel
533    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
534    if( channel >= NB_TTY_CHANNELS ) return -1;
535
536    // write string to TTY channel
537    for (nwritten = 0; nwritten < length; nwritten++) 
538    {
539        // check tty's status
540        if ( _tty_get_register( channel, TTY_STATUS ) & 0x2 )  break;
541
542        // write one byte
543        if (buffer[nwritten] == '\n') 
544        {
545            _tty_set_register( channel, TTY_WRITE, (unsigned int)'\r' );
546        }
547        _tty_set_register( channel, TTY_WRITE, (unsigned int)buffer[nwritten] );
548    }
549   
550    return nwritten;
551}
552
553////////////////////////////////////////////////
554int _sys_tty_read( char*        buffer, 
555                   unsigned int length,    // unused
556                   unsigned int channel)   // channel index
557{
558    // compute and check tty channel
559    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
560    if( channel >= NB_TTY_CHANNELS ) return -1;
561
562    // read one character from TTY channel
563    if (_tty_rx_full[channel] == 0) 
564    {
565        return 0;
566    }
567    else 
568    {
569        *buffer = _tty_rx_buf[channel];
570        _tty_rx_full[channel] = 0;
571        return 1;
572    }
573}
574
575///////////////////////////////////////////
[494]576int _sys_tty_get_lock( unsigned int   channel,       // unused
[440]577                       unsigned int * save_sr_ptr )
578{
[494]579    // check tty channel
580    if( channel != 0 )  return 1;
[440]581
582    _it_disable( save_sr_ptr );
[494]583    _sqt_lock_acquire( &_tty0_sqt_lock );
[440]584    return 0;
585}
586
587///////////////////////////////////////////////
588int _sys_tty_release_lock( unsigned int   channel,
589                           unsigned int * save_sr_ptr )
590{
[494]591    // check tty channel
592    if( channel != 0 )  return 1;
[440]593
[494]594    _sqt_lock_release( &_tty0_sqt_lock );
[440]595    _it_restore( save_sr_ptr );
596    return 0;
597}
598
[428]599//////////////////////////////////////////////////////////////////////////////
[440]600//             TIM related syscall handlers
[428]601//////////////////////////////////////////////////////////////////////////////
[440]602
603////////////////////
604int _sys_tim_alloc()
[428]605{
[440]606    // get a new timer index
[459]607    unsigned int channel = _atomic_increment( &_tim_channel_allocator, 1 );
[440]608
609    if ( channel >= NB_TIM_CHANNELS )
610    {
611        _printf("\n[GIET_ERROR] in _sys_tim_alloc() : not enough TIM channels\n");
612        return -1;
613    }
614    else
615    {
[449]616        _set_context_slot( CTX_TIM_ID, channel );
617        return 0;
[440]618    }
619}
620
621/////////////////////////////////////////
622int _sys_tim_start( unsigned int period )
623{
624    // get timer index
625    unsigned int channel = _get_context_slot( CTX_TIM_ID );
626    if ( channel >= NB_TIM_CHANNELS )
627    {
628        _printf("\n[GIET_ERROR] in _sys_tim_start() : not enough TIM channels\n");
629        return -1;
630    }
631
632    // start timer
633    _timer_start( channel, period );
634
635    return 0;
636}
637
638///////////////////
639int _sys_tim_stop()
640{
641    // get timer index
642    unsigned int channel = _get_context_slot( CTX_TIM_ID );
643    if ( channel >= NB_TIM_CHANNELS )
644    {
645        _printf("\n[GIET_ERROR] in _sys_tim_stop() : illegal timer index\n");
646        return -1;
647    }
648
649    // stop timer
650    _timer_stop( channel );
651
652    return 0;
653}
654
655//////////////////////////////////////////////////////////////////////////////
656//             NIC related syscall handlers
657//////////////////////////////////////////////////////////////////////////////
658
[478]659#define NIC_CONTAINER_SIZE 4096
660
[494]661////////////////////////////////////////
662int _sys_nic_alloc( unsigned int is_rx,
663                    unsigned int xmax,
664                    unsigned int ymax )
[440]665{
[494]666    // check xmax / ymax parameters
667    if ( xmax > X_SIZE )
668    {
669        _printf("\n[GIET_ERROR] in _sys_nic_alloc() xmax argument too large\n");
670        return -1;
671    }
672    if ( ymax > Y_SIZE )
673    {
674        _printf("\n[GIET_ERROR] in _sys_nic_alloc() ymax argument too large\n");
675        return -1;
676    }
[459]677
[494]678    // get a NIC_RX or NIC_TX channel index
[449]679    unsigned int nic_channel;
680    unsigned int cma_channel;
[440]681
[459]682    if ( is_rx ) nic_channel = _atomic_increment( &_nic_rx_channel_allocator, 1 );
683    else         nic_channel = _atomic_increment( &_nic_tx_channel_allocator, 1 );
[449]684
685    if ( (nic_channel >= NB_NIC_CHANNELS) )
[440]686    {
[449]687        _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough NIC channels\n");
[440]688        return -1;
689    }
[449]690
691    // get a CMA channel index
[459]692    cma_channel = _atomic_increment( &_cma_channel_allocator, 1 );
[449]693
694    if ( cma_channel >= NB_CMA_CHANNELS )
695    {
696        _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough CMA channels\n");
697        return -1;
698    }
[459]699
[494]700#if GIET_DEBUG_NIC
701unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
702_printf("\n[GIET DEBUG NIC] Task %d enters sys_nic_alloc() at cycle %d\n"
703        " nic_channel = %d / cma_channel = %d\n"
704        thread , _get_proctime() , nic_channel , cma_channel );
705#endif
706
[449]707    // register nic_index and cma_index in task context
708    if ( is_rx )
709    {
710        _set_context_slot( CTX_NIC_RX_ID, nic_channel );
711        _set_context_slot( CTX_CMA_RX_ID, cma_channel );
712    }
[440]713    else
714    {
[449]715        _set_context_slot( CTX_NIC_TX_ID, nic_channel );
716        _set_context_slot( CTX_CMA_TX_ID, cma_channel );
[440]717    }
718
[494]719    // physical addresses to be registered in the CMA registers
[459]720    unsigned long long nic_chbuf_pbase;     // NIC chbuf physical address
721    unsigned long long ker_chbuf_pbase;     // kernel chbuf physical address
[449]722
[494]723    // allocate one kernel container per cluster in the (xmax / ymax) mesh
[528]724    unsigned int        cx;                 // cluster X coordinate
725    unsigned int        cy;                 // cluster Y coordinate
726    unsigned int        index;              // container index in chbuf
727    unsigned int        vaddr;              // virtual address
728    unsigned long long  cont_paddr;         // container physical address
[494]729
[528]730    unsigned int        flags;              // for _v2p_translate()
731
[494]732    for ( cx = 0 ; cx < xmax ; cx++ )
[478]733    {
[494]734        for ( cy = 0 ; cy < ymax ; cy++ )
[478]735        {
736            // compute index in chbuf
[494]737            index = (cx * ymax) + cy; 
[478]738
[494]739            // allocate the kernel container
[478]740            vaddr = (unsigned int)_remote_malloc( NIC_CONTAINER_SIZE, cx, cy );
741
[494]742            if ( vaddr == 0 )  // not enough kernel heap memory in cluster[cx,cy]
743            {
744                _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough kenel heap"
745                        " in cluster[%d,%d]\n", cx, cy );
746                return -1;
747            }
748
[478]749            // compute container physical address
[528]750            cont_paddr = _v2p_translate( vaddr , &flags );
[478]751
[494]752            // initialize chbuf entry
[478]753            if ( is_rx ) _nic_rx_chbuf[nic_channel].buffer[index].desc = cont_paddr;
754            else         _nic_tx_chbuf[nic_channel].buffer[index].desc = cont_paddr;
755
756#if GIET_DEBUG_NIC
757_printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_start()"
758        " allocates container in cluster[%d,%d] : vaddr = %x / paddr = %l\n",
759        thread , cx , cy , vaddr , cont_paddr );
760#endif
761        }
762    }
763
[494]764    // complete kernel chbuf initialisation
765    if ( is_rx )
766    {
767        _nic_rx_chbuf[nic_channel].xmax = xmax;
768        _nic_rx_chbuf[nic_channel].ymax = ymax;
769    }
770    else
771    {
772        _nic_tx_chbuf[nic_channel].xmax = xmax;
773        _nic_tx_chbuf[nic_channel].ymax = ymax;
774    }
775
[478]776    // compute the NIC chbuf descriptor physical address
[449]777    unsigned int offset;
[459]778    if ( is_rx ) offset = 0x4000;
[489]779    else         offset = 0x4080;
[459]780    nic_chbuf_pbase = (((unsigned long long)((X_IO << Y_WIDTH) + Y_IO))<<32) |
781                      (SEG_NIC_BASE + (nic_channel<<15) + offset);
[449]782
[459]783#if GIET_DEBUG_NIC
[478]784_printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_start()"
785        " get NIC chbuf : paddr = %l\n",
786        thread , nic_chbuf_pbase );
[459]787#endif
[449]788
789    // compute the kernel chbuf descriptor physical address
[459]790    if ( is_rx ) vaddr = (unsigned int)( &_nic_rx_chbuf[nic_channel] );
791    else         vaddr = (unsigned int)( &_nic_tx_chbuf[nic_channel] );
[440]792
[528]793    ker_chbuf_pbase = _v2p_translate( vaddr , &flags );
794
[459]795#if GIET_DEBUG_NIC
[478]796_printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_start()"
797        " get kernel chbuf : vaddr = %x / paddr = %l\n",
798        thread , vaddr , ker_chbuf_pbase );
[459]799#endif
[440]800
[459]801    // sync the kernel chbuf in L2 after write in L2
802    _mmc_sync( ker_chbuf_pbase, sizeof( nic_chbuf_t ) );
803
804    // initializes CMA registers defining the source & destination chbufs
805    if ( is_rx )               // NIC to kernel
806    {
807        _cma_set_register( cma_channel, CHBUF_SRC_DESC , (unsigned int)(nic_chbuf_pbase) );
808        _cma_set_register( cma_channel, CHBUF_SRC_EXT  , (unsigned int)(nic_chbuf_pbase>>32) );
809        _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, 2 );
810        _cma_set_register( cma_channel, CHBUF_DST_DESC , (unsigned int)(ker_chbuf_pbase) );
811        _cma_set_register( cma_channel, CHBUF_DST_EXT  , (unsigned int)(ker_chbuf_pbase>>32) );
[494]812        _cma_set_register( cma_channel, CHBUF_DST_NBUFS, xmax * ymax );
[459]813    }
814    else                      // kernel to NIC
815    {
816        _cma_set_register( cma_channel, CHBUF_SRC_DESC , (unsigned int)(ker_chbuf_pbase) );
817        _cma_set_register( cma_channel, CHBUF_SRC_EXT  , (unsigned int)(ker_chbuf_pbase>>32) );
[494]818        _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, xmax * ymax );
[459]819        _cma_set_register( cma_channel, CHBUF_DST_DESC , (unsigned int)(nic_chbuf_pbase) );
820        _cma_set_register( cma_channel, CHBUF_DST_EXT  , (unsigned int)(nic_chbuf_pbase>>32) );
821        _cma_set_register( cma_channel, CHBUF_DST_NBUFS, 2 );
822    }
823
[494]824#if GIET_DEBUG_NIC
825_printf("\n[GIET DEBUG NIC] Task %d exit _sys_nic_alloc() at cycle %d\n",
826        thread, _get_proctime() );
827#endif
828
829    return nic_channel;
830} // end _sys_nic_alloc()
831
832
833////////////////////////////////////////
834int _sys_nic_start( unsigned int is_rx,
835                    unsigned int channel )
836{
837    unsigned int nic_channel;
838    unsigned int cma_channel;
839
840    // get NIC channel index and CMA channel index from task context
841    if ( is_rx )
842    {
843        nic_channel = _get_context_slot( CTX_NIC_RX_ID );
844        cma_channel = _get_context_slot( CTX_CMA_RX_ID );
845    }
846    else
847    {
848        nic_channel = _get_context_slot( CTX_NIC_TX_ID );
849        cma_channel = _get_context_slot( CTX_CMA_TX_ID );
850    }
851
852#if GIET_DEBUG_NIC
853unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
854_printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_start() at cycle %d"
855        " get NIC channel = %d / CMA channel = %d\n",
856        thread, _get_proctime(), nic_channel, cma_channel );
857#endif
858
859    // check NIC and CMA channels index
860    if ( nic_channel != channel )
861    {
862        _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal NIC channel\n");
863        return -1;
864    }
865    if ( cma_channel >= NB_CMA_CHANNELS )
866    {
867        _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal CMA channel\n");
868        return -1;
869    }
870
[449]871    // start CMA transfer
[478]872    _cma_set_register( cma_channel, CHBUF_BUF_SIZE , NIC_CONTAINER_SIZE );
[505]873    _cma_set_register( cma_channel, CHBUF_PERIOD   , 0 );     // OUT_OF_ORDER
[449]874    _cma_set_register( cma_channel, CHBUF_RUN      , 1 );
875
876    // activates NIC channel
[459]877    _nic_channel_start( nic_channel, is_rx, GIET_NIC_MAC4, GIET_NIC_MAC2 ); 
878
879#if GIET_DEBUG_NIC
[478]880_printf("\n[GIET DEBUG NIC] Task %d exit _sys_nic_start() at cycle %d\n",
881        thread , _get_proctime() );
[459]882#endif
883
[449]884    return 0;
[505]885}  // end _sys_nic_start()
[449]886
[494]887
[449]888//////////////////////////////////////
889int _sys_nic_move( unsigned int is_rx,
[459]890                   unsigned int channel,
[449]891                   void*        buffer )
892{
893
[459]894#if GIET_DEBUG_NIC
895unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
[478]896_printf("\n[GIET DEBUG NIC] Task %d enters _sys_nic_move() at cycle %d\n",
897        thread , _get_proctime() );
[459]898#endif
899
[494]900    // check NIC channel index
901    if ( channel >= NB_NIC_CHANNELS )
902    {
903        _printf("\n[GIET_ERROR] in _sys_nic_move() : illegal NIC channel index\n");
904        return -1;
905    }
906
907    // get kernel chbuf virtual address
908    nic_chbuf_t* chbuf;
909    if ( is_rx )  chbuf = &_nic_rx_chbuf[channel];
910    else          chbuf = &_nic_tx_chbuf[channel];
911
912    // get xmax / ymax parameters
913    unsigned int xmax = chbuf->xmax;
914    unsigned int ymax = chbuf->ymax;
915
[478]916    // get cluster coordinates for the processor running the calling task
917    unsigned int  procid = _get_procid();
918    unsigned int  cx     = procid >> (Y_WIDTH + P_WIDTH);
919    unsigned int  cy     = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
920   
[494]921    // check processor coordinates / (xmax,ymax)
922    if ( cx >= xmax )
923    {
924        _printf("\n[GIET_ERROR] in _sys_nic_move() : processor X coordinate = %d"
925                " / xmax = %d\n", cx , xmax );
926        return -1;
927    }
928    if ( cy >= ymax )
929    {
930        _printf("\n[GIET_ERROR] in _sys_nic_move() : processor Y coordinate = %d"
931                " / ymax = %d\n", cy , ymax );
932        return -1;
933    }
934   
[459]935    unsigned long long user_buffer_paddr;    // user buffer physical address
936    unsigned long long kernel_buffer_paddr;  // kernel buffer physical address
937    unsigned long long kernel_chbuf_paddr;   // kernel chbuf physical address
[528]938    unsigned long long buffer_descriptor;    // kernel buffer descriptor
939    unsigned long long buffer_desc_paddr;    // kernel buffer descriptor paddr
[478]940    unsigned int       index;                // kernel buffer index in chbuf
[528]941    unsigned int       flags;                // for _v2P_translate
[459]942
943    // Compute user buffer physical address and check access rights
[528]944    user_buffer_paddr = _v2p_translate( (unsigned int)buffer , &flags );
[478]945
[440]946    if ( (flags & PTE_U) == 0 )
947    {
[449]948        _printf("\n[GIET ERROR] in _sys_nic_tx_move() : illegal buffer address\n");
[440]949        return -1;
950    }
951
[459]952#if GIET_DEBUG_NIC
[478]953_printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_move() get user buffer : paddr = %l\n",
954        thread, user_buffer_paddr );
[459]955#endif
[440]956
[459]957    // compute kernel chbuf physical address (required for sync)
[528]958    kernel_chbuf_paddr = _v2p_translate( (unsigned int)chbuf , &flags );
[459]959
[494]960    // poll local kernel container status until success
[478]961    while ( 1 )
[449]962    {
[478]963        // compute buffer index and buffer descriptor paddr
[494]964        index = (ymax * cx) + cy;
[478]965        buffer_desc_paddr = kernel_chbuf_paddr + (index<<6);
[459]966
[478]967        // inval buffer descriptor in L2 before read in L2
968        _mmc_inval( buffer_desc_paddr , 8 );
[528]969        buffer_descriptor = chbuf->buffer[index].desc;
[459]970
971#if GIET_DEBUG_NIC
[478]972_printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_move() read buffer descriptor %d\n"
973        " at cycle = %d / paddr = %l / buffer descriptor = %l\n",
[528]974        thread, index, _get_proctime(), buffer_desc_paddr, buffer_descriptor );
[459]975#endif
976
[478]977        // test buffer status and break if found
[528]978        if ( ( is_rx != 0 ) && (buffer_descriptor >> 63) == 1 )  break;
979        if ( ( is_rx == 0 ) && (buffer_descriptor >> 63) == 0 )  break;
[449]980    }
[459]981
982    // compute kernel buffer physical address
[528]983    kernel_buffer_paddr = buffer_descriptor & 0x0000FFFFFFFFFFFFULL;
[449]984   
[494]985    // move one container
986    if ( is_rx )              // RX transfer
[459]987    {
988        // inval kernel buffer in L2 before read in L2
[478]989        _mmc_inval( kernel_buffer_paddr, NIC_CONTAINER_SIZE );
[449]990
[459]991        // transfer data from kernel buffer to user buffer
992        _physical_memcpy( user_buffer_paddr, 
993                          kernel_buffer_paddr, 
[478]994                          NIC_CONTAINER_SIZE );
995#if GIET_DEBUG_NIC
996_printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_move() transfer "
997        "kernel buffer %l to user buffer %l at cycle %d\n",
998        thread , kernel_buffer_paddr , user_buffer_paddr , _get_proctime() );
999#endif
[449]1000
[459]1001    }
[494]1002    else                      // TX transfer
[459]1003    {
1004        // transfer data from user buffer to kernel buffer
1005        _physical_memcpy( kernel_buffer_paddr, 
1006                          user_buffer_paddr, 
[478]1007                          NIC_CONTAINER_SIZE );
[449]1008
[459]1009        // sync kernel buffer in L2 after write in L2
[478]1010        _mmc_sync( kernel_buffer_paddr, NIC_CONTAINER_SIZE );
1011
1012#if GIET_DEBUG_NIC
1013_printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_move() transfer "
1014        "user buffer %l to kernel buffer %l at cycle %d\n",
1015        thread , user_buffer_paddr , kernel_buffer_paddr , _get_proctime() );
1016#endif
1017
[459]1018    }
1019
[478]1020    // update kernel chbuf status
1021    if ( is_rx ) chbuf->buffer[index].desc = kernel_buffer_paddr & 0x0000FFFFFFFFFFFFULL;
1022    else         chbuf->buffer[index].desc = kernel_buffer_paddr | 0x8000000000000000ULL;
[459]1023
1024    // sync kernel chbuf in L2 after write in L2
[478]1025    _mmc_sync( kernel_chbuf_paddr + (index<<6) , 8 );
[459]1026
1027#if GIET_DEBUG_NIC
[478]1028_printf("\n[GIET DEBUG NIC] Task %d get buffer %d  and exit _sys_nic_move() at cycle %d\n",
1029        thread , index , _get_proctime() );
[459]1030#endif
1031
[440]1032    return 0;
[449]1033} // end _sys_nic_move()
[440]1034
[494]1035
[449]1036////////////////////////////////////////
[489]1037int _sys_nic_stop( unsigned int is_rx,
1038                   unsigned int channel )
[440]1039{
[449]1040    unsigned int nic_channel;
1041    unsigned int cma_channel;
[440]1042
[449]1043    // get NIC channel index and CMA channel index
1044    if ( is_rx )
[440]1045    {
[449]1046        nic_channel = _get_context_slot( CTX_NIC_RX_ID );
1047        cma_channel = _get_context_slot( CTX_CMA_RX_ID );
[440]1048    }
[449]1049    else
1050    {
1051        nic_channel = _get_context_slot( CTX_NIC_TX_ID );
1052        cma_channel = _get_context_slot( CTX_CMA_TX_ID );
1053    }
[440]1054
[494]1055    // check NIC and CMA channels index
[489]1056    if ( nic_channel != channel )
[440]1057    {
[494]1058        _printf("\n[GIET_ERROR] in _sys_nic_stop(): illegal NIC channel\n");
[440]1059        return -1;
1060    }
[449]1061    if ( cma_channel >= NB_CMA_CHANNELS )
[440]1062    {
[489]1063        _printf("\n[GIET_ERROR] in _sys_nic_stop(): illegal CMA channel\n");
[440]1064        return -1;
1065    }
1066
[449]1067    // desactivates the NIC channel
1068    _nic_channel_stop( nic_channel, is_rx );
[440]1069
[449]1070    // desactivates the CMA channel
[505]1071    _cma_set_register( cma_channel, CHBUF_RUN , 0 );
[449]1072
[440]1073    return 0;
[494]1074}  // end _sys_nic_stop()
[440]1075
[459]1076////////////////////////////////////////
[489]1077int _sys_nic_clear( unsigned int is_rx,
1078                    unsigned int channel )
[459]1079{
1080    unsigned int nic_channel;
1081
1082    // get NIC channel
1083    if ( is_rx )  nic_channel = _get_context_slot( CTX_NIC_RX_ID );
1084    else          nic_channel = _get_context_slot( CTX_NIC_TX_ID );
1085
[489]1086    if ( nic_channel != channel )
[459]1087    {
[489]1088        _printf("\n[GIET_ERROR] in _sys_nic_clear(): illegal NIC channel\n");
[459]1089        return -1;
1090    }
1091
1092    if ( is_rx )
1093    {
1094        _nic_set_global_register( NIC_G_NPKT_RX_G2S_RECEIVED       , 0 );
1095        _nic_set_global_register( NIC_G_NPKT_RX_DES_TOO_SMALL      , 0 );
1096        _nic_set_global_register( NIC_G_NPKT_RX_DES_TOO_BIG        , 0 );
1097        _nic_set_global_register( NIC_G_NPKT_RX_DES_MFIFO_FULL     , 0 );
1098        _nic_set_global_register( NIC_G_NPKT_RX_DES_CRC_FAIL       , 0 );
1099        _nic_set_global_register( NIC_G_NPKT_RX_DISPATCH_RECEIVED  , 0 );
1100        _nic_set_global_register( NIC_G_NPKT_RX_DISPATCH_BROADCAST , 0 );
1101        _nic_set_global_register( NIC_G_NPKT_RX_DISPATCH_DST_FAIL  , 0 );
1102        _nic_set_global_register( NIC_G_NPKT_RX_DISPATCH_CH_FULL   , 0 );
1103    } 
1104    else
1105    {
1106        _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_RECEIVED  , 0 );
1107        _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_TRANSMIT  , 0 );
1108        _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_TOO_BIG   , 0 );
1109        _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_TOO_SMALL , 0 );
1110        _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_SRC_FAIL  , 0 );
1111        _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_BYPASS    , 0 );
1112        _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_BROADCAST , 0 );
1113    }
1114    return 0;
[494]1115}  // en _sys_nic_clear()
[459]1116
1117////////////////////////////////////////
[489]1118int _sys_nic_stats( unsigned int is_rx,
1119                    unsigned int channel )
[459]1120{
1121    unsigned int nic_channel;
1122
1123    // get NIC channel
1124    if ( is_rx )  nic_channel = _get_context_slot( CTX_NIC_RX_ID );
1125    else          nic_channel = _get_context_slot( CTX_NIC_TX_ID );
1126
[489]1127    if ( nic_channel != channel )
[459]1128    {
[489]1129        _printf("\n[GIET_ERROR] in _sys_nic_stats(): illegal NIC channel\n");
[459]1130        return -1;
1131    }
1132
1133    if ( is_rx )
1134    {
1135        unsigned int received   = _nic_get_global_register( NIC_G_NPKT_RX_G2S_RECEIVED       );
1136        unsigned int too_small  = _nic_get_global_register( NIC_G_NPKT_RX_DES_TOO_SMALL      );
1137        unsigned int too_big    = _nic_get_global_register( NIC_G_NPKT_RX_DES_TOO_BIG        );
1138        unsigned int fifo_full  = _nic_get_global_register( NIC_G_NPKT_RX_DES_MFIFO_FULL     );
1139        unsigned int crc_fail   = _nic_get_global_register( NIC_G_NPKT_RX_DES_CRC_FAIL       );
1140        unsigned int broadcast  = _nic_get_global_register( NIC_G_NPKT_RX_DISPATCH_BROADCAST );
1141        unsigned int dst_fail   = _nic_get_global_register( NIC_G_NPKT_RX_DISPATCH_DST_FAIL  );
1142        unsigned int ch_full    = _nic_get_global_register( NIC_G_NPKT_RX_DISPATCH_CH_FULL   );
1143
1144        _printf("\n### Network Controller RX Statistics ###\n"
1145                "- packets received : %d\n"
1146                "- too small        : %d\n"
1147                "- too big          : %d\n"
1148                "- fifo full        : %d\n" 
1149                "- crc fail         : %d\n" 
1150                "- dst mac fail     : %d\n" 
1151                "- channel full     : %d\n" 
1152                "- broadcast        : %d\n",
1153                received,
1154                too_small,
1155                too_big,
1156                fifo_full,
1157                crc_fail,
1158                dst_fail,
1159                ch_full,
1160                broadcast );
1161    } 
1162    else
1163    {
1164        unsigned int received   = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_RECEIVED  );
1165        unsigned int too_big    = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_TOO_BIG   );
1166        unsigned int too_small  = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_TOO_SMALL );
1167        unsigned int src_fail   = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_SRC_FAIL  );
1168        unsigned int bypass     = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_BYPASS    );
1169        unsigned int broadcast  = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_BROADCAST );
1170
1171        _printf("\n### Network Controller TX Statistics ###\n"
1172                "- packets received : %d\n"
1173                "- too small        : %d\n"
1174                "- too big          : %d\n"
1175                "- src mac fail     : %d\n" 
1176                "- bypass           : %d\n" 
1177                "- broadcast        : %d\n",
1178                received,
1179                too_big,
1180                too_small,
1181                src_fail,
1182                bypass,
1183                broadcast );
1184    }
1185    return 0;
[494]1186}  // end _sys_nic_stats()
[459]1187
[440]1188/////////////////////////////////////////////////////////////////////////////////////////
1189//    FBF related syscall handlers
1190/////////////////////////////////////////////////////////////////////////////////////////
1191
1192/////////////////////////////////////////////
1193int _sys_fbf_sync_write( unsigned int offset,
1194                         void*        buffer,
1195                         unsigned int length )
1196{
1197    char* fbf_address = (char *)SEG_FBF_BASE + offset;
1198    memcpy( fbf_address, buffer, length);
1199
1200    return 0;
1201}
1202
1203/////////////////////////////////////////////
1204int _sys_fbf_sync_read(  unsigned int offset,
1205                         void*        buffer,
1206                         unsigned int length )
1207{
1208    char* fbf_address = (char *)SEG_FBF_BASE + offset;
1209    memcpy( buffer, fbf_address, length);
1210
1211    return 0;
1212}
1213
1214////////////////////////
1215int _sys_fbf_cma_alloc()
1216{
1217   // get a new CMA channel index
[459]1218    unsigned int channel = _atomic_increment( &_cma_channel_allocator, 1 );
[440]1219
1220    if ( channel >= NB_CMA_CHANNELS )
1221    {
1222        _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : not enough CMA channels\n");
1223        return -1;
1224    }
1225    else
1226    {
[449]1227        _set_context_slot( CTX_CMA_FB_ID, channel );
1228        return 0;
[440]1229    }
1230} // end sys_fbf_cma_alloc()
1231
1232////////////////////////////////////////////
1233int _sys_fbf_cma_start( void*        vbase0, 
1234                        void*        vbase1, 
1235                        unsigned int length ) 
1236{
1237#if NB_CMA_CHANNELS > 0
1238
1239    unsigned int       vaddr;           // virtual address
[528]1240    unsigned int       flags;           // for _v2p_translate()
[440]1241
1242    // get channel index
[449]1243    unsigned int channel = _get_context_slot( CTX_CMA_FB_ID );
[440]1244
1245    if ( channel >= NB_CMA_CHANNELS )
1246    {
1247        _printf("\n[GIET ERROR] in _fbf_cma_start() : CMA channel index too large\n");
1248        return -1;
1249    }
1250
1251#if GIET_DEBUG_FBF_CMA
1252_printf("\n[FBF_CMA DEBUG] enters _sys_fbf_cma_start()\n"
1253        " - channel      = %d\n"
1254        " - buf0   vbase = %x\n"
1255        " - buf1   vbase = %x\n"
1256        " - buffer size  = %x\n",
1257        channel,
1258        (unsigned int)vbase0,
1259        (unsigned int)vbase1,
1260        length );
1261#endif
1262
1263    // checking user buffers virtual addresses and length alignment
[528]1264    if ( ((unsigned int)vbase0 & 0x3) || 
1265         ((unsigned int)vbase1 & 0x3) || 
1266         (length & 0x3) ) 
[440]1267    {
[528]1268        _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer not aligned\n");
[440]1269        return -1;
1270    }
1271
1272    // compute frame buffer physical address and initialize _fbf_chbuf[channel]
[528]1273    vaddr = (unsigned int)SEG_FBF_BASE;
1274    _fbf_chbuf[channel].fbf.desc = _v2p_translate( vaddr , &flags );
[440]1275
[528]1276    // Compute user buffer 0 physical addresses and intialize _fbf_chbuf[channel]
1277    vaddr = (unsigned int)vbase0;
1278    _fbf_chbuf[channel].buf0.desc = _v2p_translate( vaddr , &flags );
[440]1279
1280    if ((flags & PTE_U) == 0) 
1281    {
[528]1282        _printf("\n[GIET ERROR] in _fbf_cma_start() : buf0 not in user space\n");
[440]1283        return -1;
1284    }
1285
[528]1286    // Compute user buffer 1 physical addresses and intialize _fbf_chbuf[channel]
1287    vaddr = (unsigned int)vbase1;
1288    _fbf_chbuf[channel].buf1.desc = _v2p_translate( vaddr , &flags );
[440]1289
1290    if ((flags & PTE_U) == 0) 
1291    {
[528]1292        _printf("\n[GIET ERROR] in _fbf_cma_start() : buf1 not in user space\n");
[440]1293        return -1;
1294    }
1295
1296    // initializes buffer length
1297    _fbf_chbuf[channel].length = length;
1298
[505]1299    // Compute and register physical adress of the fbf_chbuf descriptor
[528]1300    vaddr = (unsigned int)&_fbf_chbuf[channel];
1301    _fbf_chbuf_paddr[channel] = _v2p_translate( vaddr , &flags );
[440]1302 
1303    if ( USE_IOB )
1304    {
[505]1305        // SYNC request for fbf_chbuf descriptor
1306        _mmc_sync( _fbf_chbuf_paddr[channel] , sizeof( fbf_chbuf_t ) );
[440]1307    }
1308
1309#if GIET_DEBUG_FBF_CMA
1310_printf(" - fbf    pbase = %l\n"
1311        " - buf0   pbase = %l\n"
1312        " - buf1   pbase = %l\n"
1313        " - chbuf  pbase = %l\n",
[478]1314        _fbf_chbuf[channel].fbf.desc,
1315        _fbf_chbuf[channel].buf0.desc,
1316        _fbf_chbuf[channel].buf1.desc,
[505]1317        _fbf_chbuf_paddr[channel] );
[440]1318#endif
1319
[505]1320    // start CMA transfer
1321    unsigned long long paddr = _fbf_chbuf_paddr[channel];
1322    unsigned int src_chbuf_paddr_lsb = (unsigned int)(paddr & 0xFFFFFFFF);
1323    unsigned int src_chbuf_paddr_ext = (unsigned int)(paddr >> 32);
1324    unsigned int dst_chbuf_paddr_lsb = src_chbuf_paddr_lsb + 128;
1325    unsigned int dst_chbuf_paddr_ext = src_chbuf_paddr_ext;
1326
1327    _cma_set_register( channel, CHBUF_SRC_DESC , src_chbuf_paddr_lsb );
1328    _cma_set_register( channel, CHBUF_SRC_EXT  , src_chbuf_paddr_ext );
1329    _cma_set_register( channel, CHBUF_SRC_NBUFS, 2 );
1330    _cma_set_register( channel, CHBUF_DST_DESC , dst_chbuf_paddr_lsb );
1331    _cma_set_register( channel, CHBUF_DST_EXT  , dst_chbuf_paddr_ext );
1332    _cma_set_register( channel, CHBUF_DST_NBUFS, 1 );
1333    _cma_set_register( channel, CHBUF_BUF_SIZE , length );
1334    _cma_set_register( channel, CHBUF_PERIOD   , 300 );
1335    _cma_set_register( channel, CHBUF_RUN      , 1 );
1336
[440]1337    return 0;
1338
1339#else
1340
1341    _printf("\n[GIET ERROR] in _sys_fbf_cma_start() : NB_CMA_CHANNELS = 0\n");
1342    return -1;
1343
1344#endif
1345} // end _sys_fbf_cma_start()
1346
1347/////////////////////////////////////////////////////
1348int _sys_fbf_cma_display( unsigned int buffer_index )
1349{
1350#if NB_CMA_CHANNELS > 0
1351
[505]1352    volatile unsigned int full = 1;
[440]1353
1354    // get channel index
[449]1355    unsigned int channel = _get_context_slot( CTX_CMA_FB_ID );
[440]1356
1357    if ( channel >= NB_CMA_CHANNELS )
1358    {
[505]1359        _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : "
1360                "CMA channel index too large\n");
[440]1361        return -1;
1362    }
1363
[505]1364    // get fbf_chbuf descriptor pointer
1365    fbf_chbuf_t* pdesc = &_fbf_chbuf[channel];     
1366
[440]1367#if GIET_DEBUG_FBF_CMA
1368_printf("\n[FBF_CMA DEBUG] enters _sys_fb_cma_display()\n"
[505]1369        " - cma channel     = %d\n"
1370        " - buffer index    = %d\n"
1371        " - buf0_desc value = %l\n"
1372        " - buf1_desc value = %l\n"
1373        " - fbf_desc  value = %l\n",
1374        channel , buffer_index,
1375        _fbf_chbuf[channel].buf0.desc,
1376        _fbf_chbuf[channel].buf1.desc,
1377        _fbf_chbuf[channel].fbf.desc );
[440]1378#endif
1379
[478]1380    if ( buffer_index == 0 )    // user buffer 0
1381    {
[505]1382        // INVAL L1 and L2 cache copies of user buffer descriptor,
1383        // because it has been modified in RAM by the CMA component
1384        _dcache_buf_invalidate( (unsigned int)pdesc , sizeof(buffer_descriptor_t) );
1385        _mmc_inval( _fbf_chbuf_paddr[channel] , sizeof(buffer_descriptor_t) );
1386
[478]1387        // waiting user buffer released by the CMA component)
1388        while ( full )
1389        { 
[505]1390            full = (unsigned int)(pdesc->buf0.desc >> 63);
[440]1391        }
1392
[478]1393        // SYNC request for the user buffer, because
1394        // it will be read from XRAM by the CMA component
[505]1395        _mmc_sync( pdesc->buf0.desc , pdesc->length );
[440]1396
[505]1397        // set user buffer status
1398        pdesc->buf0.desc = pdesc->buf0.desc | 0x8000000000000000ULL;
[478]1399
[505]1400        // reset fbf buffer status
1401        pdesc->fbf.desc  = pdesc->fbf.desc  & 0x7FFFFFFFFFFFFFFFULL;
1402
1403        // SYNC request, because these buffer descriptors
1404        // will be read from XRAM by the CMA component
1405        _mmc_sync( _fbf_chbuf_paddr[channel] , sizeof(fbf_chbuf_t) );
[440]1406    }
[478]1407    else                        // user buffer 1
1408    {
[505]1409        // INVAL L1 and L2 cache copies of user buffer descriptor,
1410        // because it has been modified in RAM by the CMA component
1411        _dcache_buf_invalidate( (unsigned int)pdesc + 64, sizeof(buffer_descriptor_t) );
1412        _mmc_inval( _fbf_chbuf_paddr[channel] + 64, sizeof(buffer_descriptor_t) );
1413
[478]1414        // waiting user buffer released by the CMA component)
1415        while ( full )
1416        { 
[505]1417            full = (unsigned int)(pdesc->buf1.desc >> 63);
[478]1418        }
1419
[440]1420        // SYNC request for the user buffer, because
1421        // it will be read from XRAM by the CMA component
[505]1422        _mmc_sync( pdesc->buf1.desc , pdesc->length );
[440]1423
[505]1424        // set user buffer status
1425        pdesc->buf1.desc = pdesc->buf1.desc | 0x8000000000000000ULL;
[440]1426
[505]1427        // reset fbf buffer status
1428        pdesc->fbf.desc  = pdesc->fbf.desc  & 0x7FFFFFFFFFFFFFFFULL;
1429
1430        // SYNC request, because these buffer descriptors
1431        // will be read from XRAM by the CMA component
1432        _mmc_sync( _fbf_chbuf_paddr[channel] , sizeof(fbf_chbuf_t) );
[440]1433    }
1434
1435#if GIET_DEBUG_FBF_CMA
[505]1436_printf("\n[FBF_CMA DEBUG] exit _sys_fb_cma_display()\n"
1437        " - buf0_desc value = %l\n"
1438        " - buf1_desc value = %l\n"
1439        " - fbf_desc  value = %l\n",
[478]1440        _fbf_chbuf[channel].buf0.desc,
[505]1441        _fbf_chbuf[channel].buf1.desc,
1442        _fbf_chbuf[channel].fbf.desc );
[440]1443#endif
1444
1445    return 0;
1446
1447#else
1448
1449    _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : no CMA channel allocated\n");
1450    return -1;
1451
1452#endif
1453} // end _sys_fbf_cma_display()
1454
[478]1455
[440]1456///////////////////////
1457int _sys_fbf_cma_stop()
1458{
1459#if NB_CMA_CHANNELS > 0
1460
1461    // get channel index
[449]1462    unsigned int channel = _get_context_slot( CTX_CMA_FB_ID );
[440]1463
1464    if ( channel >= NB_CMA_CHANNELS )
1465    {
1466        _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : CMA channel index too large\n");
1467        return -1;
1468    }
1469
1470    // Desactivate CMA channel
[505]1471    _cma_set_register( channel, CHBUF_RUN, 0 );
[440]1472
1473    return 0;
1474
1475#else
1476
1477    _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : no CMA channel allocated\n");
1478    return -1;
1479
1480#endif
1481} // end _sys_fbf_cma_stop()
1482
1483
1484//////////////////////////////////////////////////////////////////////////////
1485//           Miscelaneous syscall handlers
1486//////////////////////////////////////////////////////////////////////////////
1487
1488///////////////
1489int _sys_ukn() 
1490{
1491    _printf("\n[GIET ERROR] Undefined System Call / EPC = %x\n", _get_epc() );
1492    return -1;
1493}
1494
1495////////////////////////////////////
1496int _sys_proc_xyp( unsigned int* x,
1497                   unsigned int* y,
1498                   unsigned int* p )
1499{
[428]1500    unsigned int gpid = _get_procid();  // global processor index from CPO register
1501
1502    *x = (gpid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1);
1503    *y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
1504    *p = gpid & ((1<<P_WIDTH)-1);
[440]1505
1506    return 0;
[428]1507}
[440]1508
1509//////////////////////////////////
1510int _sys_task_exit( char* string ) 
[258]1511{
[294]1512    unsigned int date       = _get_proctime();
[428]1513
1514    unsigned int gpid       = _get_procid();
1515    unsigned int cluster_xy = gpid >> P_WIDTH;
[294]1516    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
1517    unsigned int x          = cluster_xy >> Y_WIDTH;
[428]1518    unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
1519
[294]1520    unsigned int task_id    = _get_context_slot(CTX_LTID_ID);
[258]1521
[440]1522    // print exit message
[294]1523    _printf("\n[GIET] Exit task %d on processor[%d,%d,%d] at cycle %d"
1524            "\n       Cause : %s\n\n",
1525            task_id, x, y, lpid, date, string );
[258]1526
1527    // goes to sleeping state
1528    _set_context_slot(CTX_RUN_ID, 0);
1529
1530    // deschedule
[528]1531    _sys_context_switch();
[440]1532
1533    return 0;
[258]1534} 
1535
[528]1536/////////////////////////
1537int _sys_context_switch() 
[258]1538{
[440]1539    unsigned int save_sr;
[258]1540
[440]1541    _it_disable( &save_sr );
1542    _ctx_switch();
1543    _it_restore( &save_sr );
1544
1545    return 0;
[258]1546}
1547
[440]1548////////////////////////
1549int _sys_local_task_id()
[258]1550{
1551    return _get_context_slot(CTX_LTID_ID);
1552}
1553
[440]1554/////////////////////////
1555int _sys_global_task_id()
[258]1556{
1557    return _get_context_slot(CTX_GTID_ID);
1558}
1559
[440]1560////////////////////
1561int _sys_thread_id()
[267]1562{
1563    return _get_context_slot(CTX_TRDID_ID);
1564}
1565
[494]1566////////////////////////////////////////////
1567int _sys_procs_number( unsigned int* x_size,
1568                       unsigned int* y_size,
1569                       unsigned int* nprocs )
[258]1570{
[494]1571    mapping_header_t * header   = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
[440]1572    mapping_cluster_t * cluster = _get_cluster_base(header);
1573
[494]1574    unsigned int x;
1575    unsigned int y;
1576    unsigned int okmin = 1;
1577    unsigned int okmax = 1;
1578
1579    // compute max values
1580    unsigned int xmax  = header->x_size;
1581    unsigned int ymax  = header->y_size;
1582    unsigned int procs = cluster[0].procs;
1583
1584    // check the (ymax-1) lower rows
1585    for ( y = 0 ; y < ymax-1 ; y++ )
[440]1586    {
[494]1587        for ( x = 0 ; x < xmax ; x++ )
1588        {
1589            if (cluster[x*ymax+y].procs != procs ) okmin = 0;
1590        }
[440]1591    }
[494]1592
1593    // check the upper row
1594    for ( x = 0 ; x < xmax ; x++ )
[440]1595    {
[494]1596        if (cluster[x*ymax+ymax-1].procs != procs ) okmax = 0;
[440]1597    }
[494]1598
1599    // return values
1600    if ( okmin && okmax )
1601    {
1602        *x_size = xmax;
1603        *y_size = ymax;
1604        *nprocs = procs;
1605    }
1606    else if ( okmin )
1607    {
1608        *x_size = xmax;
1609        *y_size = ymax-1;
1610        *nprocs = procs;
1611    }
1612    else
1613    {
1614        *x_size = 0;
1615        *y_size = 0;
1616        *nprocs = 0;
1617    }
1618    return 0;
[440]1619}
1620
1621///////////////////////////////////////////////////////
[516]1622int _sys_vseg_get_vbase( char*             vspace_name, 
1623                         char*             vseg_name, 
[440]1624                         unsigned int*     vbase ) 
1625{
[322]1626    mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
[258]1627    mapping_vspace_t * vspace = _get_vspace_base(header);
[516]1628    mapping_vseg_t * vseg     = _get_vseg_base(header);
[258]1629
1630    unsigned int vspace_id;
[516]1631    unsigned int vseg_id;
[258]1632
1633    // scan vspaces
1634    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 
1635    {
1636        if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) 
1637        {
[516]1638            // scan vsegs
1639            for (vseg_id = vspace[vspace_id].vseg_offset; 
1640                 vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs); 
1641                 vseg_id++) 
[258]1642            {
[516]1643                if (_strncmp(vseg[vseg_id].name, vseg_name, 31) == 0) 
[258]1644                {
[516]1645                    *vbase = vseg[vseg_id].vbase;
[258]1646                    return 0;
1647                }
1648            } 
1649        }
1650    } 
[440]1651    return -1;    // not found
[258]1652}
1653
[440]1654/////////////////////////////////////////////////////////
[516]1655int _sys_vseg_get_length( char*         vspace_name, 
1656                          char*         vseg_name,
[440]1657                          unsigned int* length ) 
[258]1658{
[440]1659    mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
1660    mapping_vspace_t * vspace = _get_vspace_base(header);
[516]1661    mapping_vseg_t * vseg     = _get_vseg_base(header);
[258]1662
[440]1663    unsigned int vspace_id;
[516]1664    unsigned int vseg_id;
[440]1665
1666    // scan vspaces
1667    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 
[258]1668    {
[440]1669        if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) 
1670        {
[516]1671            // scan vsegs
1672            for (vseg_id = vspace[vspace_id].vseg_offset; 
1673                 vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs); 
1674                 vseg_id++) 
[440]1675            {
[516]1676                if (_strncmp(vseg[vseg_id].name, vseg_name, 31) == 0) 
[440]1677                {
[516]1678                    *length = vseg[vseg_id].length;
[440]1679                    return 0;
1680                }
1681            } 
1682        }
1683    } 
1684    return -1;    // not found
[258]1685}
1686
[440]1687////////////////////////////////////////
1688int _sys_xy_from_ptr( void*         ptr,
1689                      unsigned int* x,
1690                      unsigned int* y )
[396]1691{
1692    unsigned int flags;
[528]1693    unsigned long long paddr = _v2p_translate( (unsigned int)ptr , &flags );
[396]1694   
[528]1695    *x = (paddr>>36) & 0xF;
1696    *y = (paddr>>32) & 0xF;
[396]1697
1698    return 0;
1699}
1700
[440]1701/////////////////////////////////////////
1702int _sys_heap_info( unsigned int* vaddr, 
1703                    unsigned int* length,
1704                    unsigned int  x,
1705                    unsigned int  y ) 
[258]1706{
[440]1707    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
[516]1708    mapping_task_t *   task    = _get_task_base(header);
1709    mapping_vseg_t *   vseg    = _get_vseg_base(header);
1710    mapping_vspace_t * vspace  = _get_vspace_base(header);
[294]1711
[440]1712    unsigned int task_id;
1713    unsigned int vspace_id;
[516]1714    unsigned int vseg_id = 0xFFFFFFFF;
[258]1715
[516]1716    // searching the heap vseg
[440]1717    if ( (x < X_SIZE) && (y < Y_SIZE) )  // searching a task in cluster(x,y)
1718    {
1719        // get vspace global index
1720        vspace_id = _get_context_slot(CTX_VSID_ID);
1721
1722        // scan all tasks in vspace
[516]1723        unsigned int min = vspace[vspace_id].task_offset ;
1724        unsigned int max = min + vspace[vspace_id].tasks ;
[440]1725        for ( task_id = min ; task_id < max ; task_id++ )
1726        {
[516]1727            if ( task[task_id].clusterid == (x * Y_SIZE + y) )
[440]1728            {
[516]1729                vseg_id = task[task_id].heap_vseg_id;
1730                if ( vseg_id != 0xFFFFFFFF ) break;
[440]1731            }
1732        }
1733    }
1734    else                                // searching in the calling task
1735    {
1736        task_id = _get_context_slot(CTX_GTID_ID);
[516]1737        vseg_id = task[task_id].heap_vseg_id;
[440]1738    }
1739
[516]1740    // analysing the vseg_id
1741    if ( vseg_id != 0xFFFFFFFF ) 
[440]1742    {
[516]1743        *vaddr  = vseg[vseg_id].vbase;
1744        *length = vseg[vseg_id].length;
[440]1745        return 0;
1746    }
1747    else 
1748    {
1749        *vaddr  = 0;
1750        *length = 0;
1751        return -1;
1752    }
1753}  // end _sys_heap_info()
1754
1755
[258]1756// Local Variables:
1757// tab-width: 4
1758// c-basic-offset: 4
1759// c-file-offsets:((innamespace . 0)(inline-open . 0))
1760// indent-tabs-mode: nil
1761// End:
1762// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
1763
Note: See TracBrowser for help on using the repository browser.