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

Last change on this file since 442 was 440, checked in by alain, 10 years ago

Introducing dynamic allocation of peripheral channels (NIC, TTY, CMA, TIM)
Intoducing a kernel function for all system calls: No more direct call
to the peripheral drivers.

  • Property svn:executable set to *
File size: 28.4 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>
14#include <cma_driver.h>
[258]15#include <ctx_handler.h>
16#include <fat32.h>
17#include <utils.h>
[440]18#include <kernel_utils.h>
[396]19#include <vmem.h>
[322]20#include <hard_config.h>
[258]21#include <giet_config.h>
22#include <mapping_info.h>
23
[322]24#if !defined(SEG_BOOT_MAPPING_BASE)
25# error: You must define SEG_BOOT_MAPPING_BASE in the hard_config.h file
26#endif
27
[258]28////////////////////////////////////////////////////////////////////////////
[440]29//     Channel allocators for peripherals
30//     (TTY[0] is reserved for kernel)
31////////////////////////////////////////////////////////////////////////////
32
33unsigned int _tty_channel_allocator = 1;
34unsigned int _tim_channel_allocator = 0;
35unsigned int _cma_channel_allocator = 0;
36unsigned int _nic_channel_allocator = 0;
37
38////////////////////////////////////////////////////////////////////////////
[258]39//    Initialize the syscall vector with syscall handlers
40// Note: This array must be synchronised with the define in file stdio.h
41////////////////////////////////////////////////////////////////////////////
42const void * _syscall_vector[64] = 
43{
[440]44    &_sys_proc_xyp,         /* 0x00 */
45    &_get_proctime,         /* 0x01 */
46    &_sys_tty_write,        /* 0x02 */
47    &_sys_tty_read,         /* 0x03 */
48    &_sys_tty_alloc,        /* 0x04 */
49    &_sys_tty_get_lock,     /* 0x05 */
50    &_sys_tty_release_lock, /* 0x06 */
51    &_sys_heap_info,        /* 0x07 */
52    &_sys_local_task_id,    /* 0x08 */
53    &_sys_global_task_id,   /* 0x09 */ 
54    &_sys_fbf_cma_alloc,    /* 0x0A */
55    &_sys_fbf_cma_start,    /* 0x0B */
56    &_sys_fbf_cma_display,  /* 0x0C */
57    &_sys_fbf_cma_stop,     /* 0x0D */
58    &_sys_task_exit,        /* 0x0E */
59    &_sys_procs_number,     /* 0x0F */
[258]60
[440]61    &_sys_fbf_sync_write,   /* 0x10 */
62    &_sys_fbf_sync_read,    /* 0x11 */
63    &_sys_thread_id,        /* 0x12 */
64    &_sys_ukn,              /* 0x13 */
65    &_sys_tim_alloc,        /* 0x14 */
66    &_sys_tim_start,        /* 0x15 */ 
67    &_sys_tim_stop,         /* 0x16 */
68    &_sys_ukn,              /* 0x17 */
69    &_sys_ukn,              /* 0x18 */   
70    &_context_switch,       /* 0x19 */
71    &_sys_vobj_get_vbase,   /* 0x1A */
72    &_sys_vobj_get_length,  /* 0x1B */
73    &_sys_xy_from_ptr,      /* 0x1C */
74    &_sys_nic_alloc,        /* 0x1D */
75    &_sys_nic_sync_send,    /* 0x1E */
76    &_sys_nic_sync_receive, /* 0x1F */
[258]77
[440]78    &_fat_user_open,        /* 0x20 */
79    &_fat_user_read,        /* 0x21 */
80    &_fat_user_write,       /* 0x22 */
81    &_fat_user_lseek,       /* 0x23 */
82    &_fat_fstat,            /* 0x24 */
83    &_fat_close,            /* 0x25 */
84    &_sys_ukn,              /* 0x26 */
85    &_sys_ukn,              /* 0x27 */
86    &_sys_ukn,              /* 0x28 */
87    &_sys_ukn,              /* 0x29 */
88    &_sys_ukn,              /* 0x2A */
89    &_sys_ukn,              /* 0x2B */
90    &_sys_ukn,              /* 0x2C */
91    &_sys_ukn,              /* 0x2D */
92    &_sys_ukn,              /* 0x2E */
93    &_sys_ukn,              /* 0x2F */
[258]94
[440]95    &_sys_ukn,              /* 0x30 */
96    &_sys_ukn,              /* 0x31 */
97    &_sys_ukn,              /* 0x32 */
98    &_sys_ukn,              /* 0x33 */
99    &_sys_ukn,              /* 0x34 */
100    &_sys_ukn,              /* 0x35 */ 
101    &_sys_ukn,              /* 0x36 */
102    &_sys_ukn,              /* 0x37 */
103    &_sys_ukn,              /* 0x38 */   
104    &_sys_ukn,              /* 0x39 */
105    &_sys_ukn,              /* 0x3A */
106    &_sys_ukn,              /* 0x3B */
107    &_sys_ukn,              /* 0x3C */
108    &_sys_ukn,              /* 0x3D */
109    &_sys_ukn,              /* 0x3E */
110    &_sys_ukn,              /* 0x3F */
[258]111};
112
113//////////////////////////////////////////////////////////////////////////////
[440]114//             TTY related syscall handlers
[258]115//////////////////////////////////////////////////////////////////////////////
[440]116
117////////////////////
118int _sys_tty_alloc()
[258]119{
[440]120    // get a new TTY terminal index
121    unsigned int channel = _tty_channel_allocator;
122    unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
123    unsigned int vspace  = _get_context_slot( CTX_VSID_ID );
124
125    if ( channel >= NB_TTY_CHANNELS )
126    {
127        _printf("\n[GIET_ERROR] in _sys_tty_alloc() : not enough TTY channels\n");
128        return -1;
129    }
130    else
131    {
132        _printf("\n[GIET WARNING] TTY channel %d allocated "
133                " to thread %d in vspace %d\n", channel, thread, vspace );
134    }
135
136    // register timer index in task context
137    _set_context_slot( CTX_TTY_ID, _tty_channel_allocator );
138
139    // update timer allocator
140    _tty_channel_allocator++;
141
142    return 0;
[258]143}
144
[440]145/////////////////////////////////////////////////
146int _sys_tty_write( const char*  buffer,   
147                    unsigned int length,    // number of characters
148                    unsigned int channel)   // channel index
149{
150    unsigned int  nwritten;
151
152    // compute and check tty channel
153    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
154    if( channel >= NB_TTY_CHANNELS ) return -1;
155
156    // write string to TTY channel
157    for (nwritten = 0; nwritten < length; nwritten++) 
158    {
159        // check tty's status
160        if ( _tty_get_register( channel, TTY_STATUS ) & 0x2 )  break;
161
162        // write one byte
163        if (buffer[nwritten] == '\n') 
164        {
165            _tty_set_register( channel, TTY_WRITE, (unsigned int)'\r' );
166        }
167        _tty_set_register( channel, TTY_WRITE, (unsigned int)buffer[nwritten] );
168    }
169   
170    return nwritten;
171}
172
173////////////////////////////////////////////////
174int _sys_tty_read( char*        buffer, 
175                   unsigned int length,    // unused
176                   unsigned int channel)   // channel index
177{
178    // compute and check tty channel
179    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
180    if( channel >= NB_TTY_CHANNELS ) return -1;
181
182    // read one character from TTY channel
183    if (_tty_rx_full[channel] == 0) 
184    {
185        return 0;
186    }
187    else 
188    {
189        *buffer = _tty_rx_buf[channel];
190        _tty_rx_full[channel] = 0;
191        return 1;
192    }
193}
194
195///////////////////////////////////////////
196int _sys_tty_get_lock( unsigned int   channel,
197                       unsigned int * save_sr_ptr )
198{
199    // compute and check tty channel
200    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
201    if( channel >= NB_TTY_CHANNELS ) return -1;
202
203    _it_disable( save_sr_ptr );
204    _get_lock( &_tty_lock[channel] );
205    return 0;
206}
207
208///////////////////////////////////////////////
209int _sys_tty_release_lock( unsigned int   channel,
210                           unsigned int * save_sr_ptr )
211{
212    // compute and check tty channel
213    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
214    if( channel >= NB_TTY_CHANNELS ) return -1;
215
216    _release_lock( &_tty_lock[channel] );
217    _it_restore( save_sr_ptr );
218    return 0;
219}
220
[428]221//////////////////////////////////////////////////////////////////////////////
[440]222//             TIM related syscall handlers
[428]223//////////////////////////////////////////////////////////////////////////////
[440]224
225////////////////////
226int _sys_tim_alloc()
[428]227{
[440]228    // get a new timer index
229    unsigned int channel = _tim_channel_allocator;
230    unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
231    unsigned int vspace  = _get_context_slot( CTX_VSID_ID );
232
233    if ( channel >= NB_TIM_CHANNELS )
234    {
235        _printf("\n[GIET_ERROR] in _sys_tim_alloc() : not enough TIM channels\n");
236        return -1;
237    }
238    else
239    {
240        _printf("\n[GIET WARNING] TIM channel %d allocated "
241                " to thread %d in vspace %d\n", channel, thread, vspace );
242    }
243
244    // register timer index in task context
245    _set_context_slot( CTX_TIM_ID, channel );
246
247    // update timer allocator
248    _tim_channel_allocator++;
249
250    return 0;
251}
252
253/////////////////////////////////////////
254int _sys_tim_start( unsigned int period )
255{
256    // get timer index
257    unsigned int channel = _get_context_slot( CTX_TIM_ID );
258    if ( channel >= NB_TIM_CHANNELS )
259    {
260        _printf("\n[GIET_ERROR] in _sys_tim_start() : not enough TIM channels\n");
261        return -1;
262    }
263
264    // start timer
265    _timer_start( channel, period );
266
267    return 0;
268}
269
270///////////////////
271int _sys_tim_stop()
272{
273    // get timer index
274    unsigned int channel = _get_context_slot( CTX_TIM_ID );
275    if ( channel >= NB_TIM_CHANNELS )
276    {
277        _printf("\n[GIET_ERROR] in _sys_tim_stop() : illegal timer index\n");
278        return -1;
279    }
280
281    // stop timer
282    _timer_stop( channel );
283
284    return 0;
285}
286
287//////////////////////////////////////////////////////////////////////////////
288//             NIC related syscall handlers
289//////////////////////////////////////////////////////////////////////////////
290
291////////////////////
292int _sys_nic_alloc()
293{
294    // get a new NIC channel index
295    unsigned int channel = _nic_channel_allocator;
296    unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
297    unsigned int vspace  = _get_context_slot( CTX_VSID_ID );
298
299    if ( channel >= NB_NIC_CHANNELS )
300    {
301        _printf("\n[GIET_ERROR] in _sys_nic_alloc() : not enough NIC channels\n");
302        return -1;
303    }
304    else
305    {
306        _printf("\n[GIET WARNING] NIC channel %d allocated "
307                " to thread %d in vspace %d\n", channel, thread, vspace );
308    }
309
310    // register channel index in task context
311    _set_context_slot( CTX_NIC_ID, channel );
312
313    // update NIC channel allocator
314    _nic_channel_allocator++;
315
316    return 0;
317}
318
319////////////////////////////////////
320int _sys_nic_sync_send( void* vbuf )
321{
322    unsigned int ppn;
323    unsigned int flags;
324    unsigned int vaddr = (unsigned int)vbuf;
325
326    // get NIC channel index
327    unsigned int channel = _get_context_slot( CTX_NIC_ID );
328    if ( channel >= NB_NIC_CHANNELS )
329    {
330        _printf("\n[GIET_ERROR] in _sys_nic_sync_send() : illegal NIC channel index\n");
331        return -1;
332    }
333
334    // get page table pointer
335    unsigned int user_ptab = _get_context_slot( CTX_PTAB_ID );
336
337    // Compute user buffer physical address and check access rights
338    unsigned int ko = _v2p_translate( (page_table_t*)user_ptab,
339                                      vaddr,
340                                      &ppn,
341                                      &flags );
342    if ( ko )
343    {
344        _printf("\n[GIET ERROR] in _sys_nic_sync_send() : user buffer unmapped\n");
345        return -1;
346    }
347    if ( (flags & PTE_U) == 0 )
348    {
349        _printf("\n[GIET ERROR] in _sys_nic_sync_send() : illegal buffer address\n");
350        return -1;
351    }
352    unsigned long long pbuf = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF);
353
354    _nic_sync_send( channel, pbuf );
355
356    return 0;
357}
358
359///////////////////////////////////////
360int _sys_nic_sync_receive( void* vbuf )
361{
362    unsigned int ppn;
363    unsigned int flags;
364    unsigned int vaddr = (unsigned int)vbuf;
365
366    // get NIC channel index
367    unsigned int channel = _get_context_slot( CTX_NIC_ID );
368    if ( channel >= NB_NIC_CHANNELS )
369    {
370        _printf("\n[GIET_ERROR] in _sys_nic_sync_send() : illegal NIC channel index\n");
371        return -1;
372    }
373
374    // get page table pointer
375    unsigned int user_ptab = _get_context_slot( CTX_PTAB_ID );
376
377    // Compute user buffer physical address and check access rights
378    unsigned int ko = _v2p_translate( (page_table_t*)user_ptab,
379                                      vaddr,
380                                      &ppn,
381                                      &flags );
382    if ( ko )
383    {
384        _printf("\n[GIET ERROR] in _sys_nic_sync_send() : user buffer unmapped\n");
385        return -1;
386    }
387    if ( (flags & PTE_U) == 0 )
388    {
389        _printf("\n[GIET ERROR] in _sys_nic_sync_send() : illegal buffer address\n");
390        return -1;
391    }
392    unsigned long long pbuf = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF);
393
394    _nic_sync_receive( channel, pbuf );
395
396    return 0;
397}
398
399/////////////////////////////////////////////////////////////////////////////////////////
400//    FBF related syscall handlers
401/////////////////////////////////////////////////////////////////////////////////////////
402
403// Array of fbf_chbuf descriptors, indexed by the CMA channel index.
404__attribute__((section (".unckdata")))
405volatile fbf_chbuf_t _fbf_chbuf[NB_CMA_CHANNELS] __attribute__((aligned(32)));
406
407// Physical addresses of these fbf_chbuf descriptors (required for L2 cache sync)
408__attribute__((section (".unckdata")))
409unsigned long long _fbf_chbuf_paddr[NB_CMA_CHANNELS];
410
411/////////////////////////////////////////////
412int _sys_fbf_sync_write( unsigned int offset,
413                         void*        buffer,
414                         unsigned int length )
415{
416    char* fbf_address = (char *)SEG_FBF_BASE + offset;
417    memcpy( fbf_address, buffer, length);
418
419    return 0;
420}
421
422/////////////////////////////////////////////
423int _sys_fbf_sync_read(  unsigned int offset,
424                         void*        buffer,
425                         unsigned int length )
426{
427    char* fbf_address = (char *)SEG_FBF_BASE + offset;
428    memcpy( buffer, fbf_address, length);
429
430    return 0;
431}
432
433////////////////////////
434int _sys_fbf_cma_alloc()
435{
436#if NB_CMA_CHANNELS > 0
437
438   // get a new CMA channel index
439    unsigned int channel = _cma_channel_allocator;
440    unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
441    unsigned int vspace  = _get_context_slot( CTX_VSID_ID );
442
443    if ( channel >= NB_CMA_CHANNELS )
444    {
445        _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : not enough CMA channels\n");
446        return -1;
447    }
448    else
449    {
450        _printf("\n[GIET WARNING] FBF_CMA channel %d allocated "
451                " to thread %d in vspace %d\n", channel, thread, vspace );
452    }
453
454    // register channel index in task context
455    _set_context_slot( CTX_FBCMA_ID, channel );
456
457    // update CMA channel allocator
458    _cma_channel_allocator++;
459
460    return 0;
461
462#else
463
464    _printf("\n[GIET ERROR] in _fb_cma_start() : NB_CMA_CHANNELS = 0\n");
465    return -1;
466
467#endif
468} // end sys_fbf_cma_alloc()
469
470////////////////////////////////////////////
471int _sys_fbf_cma_start( void*        vbase0, 
472                        void*        vbase1, 
473                        unsigned int length ) 
474{
475#if NB_CMA_CHANNELS > 0
476
477    unsigned int       ptab;            // page table virtual address
478    unsigned int       ko;              // unsuccessfull V2P translation
479    unsigned int       vaddr;           // virtual address
480    unsigned int       flags;           // protection flags
481    unsigned int       ppn;             // physical page number
482    unsigned long long chbuf_paddr;     // physical address of source chbuf descriptor
483
484    // get channel index
485    unsigned int channel = _get_context_slot( CTX_FBCMA_ID );
486
487    if ( channel >= NB_CMA_CHANNELS )
488    {
489        _printf("\n[GIET ERROR] in _fbf_cma_start() : CMA channel index too large\n");
490        return -1;
491    }
492
493#if GIET_DEBUG_FBF_CMA
494_printf("\n[FBF_CMA DEBUG] enters _sys_fbf_cma_start()\n"
495        " - channel      = %d\n"
496        " - buf0   vbase = %x\n"
497        " - buf1   vbase = %x\n"
498        " - buffer size  = %x\n",
499        channel,
500        (unsigned int)vbase0,
501        (unsigned int)vbase1,
502        length );
503#endif
504
505    // checking user buffers virtual addresses and length alignment
506    if ( ((unsigned int)vbase0 & 0x3) || ((unsigned int)vbase1 & 0x3) || (length & 0x3) ) 
507    {
508        _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer not word aligned\n");
509        return -1;
510    }
511
512    // get page table virtual address
513    ptab = _get_context_slot(CTX_PTAB_ID);
514
515    // compute frame buffer physical address and initialize _fbf_chbuf[channel]
516    vaddr = ((unsigned int)SEG_FBF_BASE);
517    ko    = _v2p_translate( (page_table_t*) ptab, 
518                            (vaddr >> 12),
519                            &ppn, 
520                            &flags );
521    if (ko) 
522    {
523        _printf("\n[GIET ERROR] in _fb_cma_start() : frame buffer unmapped\n");
524        return -1;
525    }
526
527    _fbf_chbuf[channel].fbf    = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF);
528
529    // Compute user buffer 0 physical addresses and intialize _fbf_chbuf[channel]
530    vaddr = (unsigned int)vbase0; 
531    ko = _v2p_translate( (page_table_t*) ptab, 
532                         (vaddr >> 12),
533                         &ppn, 
534                         &flags );
535    if (ko) 
536    {
537        _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 0 unmapped\n");
538        return -1;
539    } 
540    if ((flags & PTE_U) == 0) 
541    {
542        _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 0 not in user space\n");
543        return -1;
544    }
545
546    _fbf_chbuf[channel].buf0 = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF);
547
548    // Compute user buffer 1 physical addresses and intialize _fbf_chbuf[channel]
549    vaddr = (unsigned int)vbase1; 
550    ko = _v2p_translate( (page_table_t*) ptab, 
551                         (vaddr >> 12),
552                         &ppn, 
553                         &flags );
554    if (ko) 
555    {
556        _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 1 unmapped\n");
557        return -1;
558    } 
559    if ((flags & PTE_U) == 0) 
560    {
561        _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 1 not in user space\n");
562        return -1;
563    }
564
565    _fbf_chbuf[channel].buf1 = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF);
566
567    // initializes buffer length
568    _fbf_chbuf[channel].length = length;
569
570    // Compute and register physical adress of the chbuf descriptor
571    vaddr = (unsigned int)(&_fbf_chbuf[channel]);
572    ko = _v2p_translate( (page_table_t*) ptab, 
573                         (vaddr >> 12),
574                         &ppn, 
575                         &flags );
576    if (ko) 
577    {
578        _printf("\n[GIET ERROR] in _fbf_cma_start() : chbuf descriptor unmapped\n");
579        return -1;
580    }
581 
582    chbuf_paddr = (((paddr_t)ppn) << 12) | (vaddr & 0x00000FFF);
583
584    _fbf_chbuf_paddr[channel] = chbuf_paddr;
585
586
587    if ( USE_IOB )
588    {
589        // SYNC request for channel descriptor
590        _mmc_sync( chbuf_paddr, 32 );
591    }
592
593#if GIET_DEBUG_FBF_CMA
594_printf(" - fbf    pbase = %l\n"
595        " - buf0   pbase = %l\n"
596        " - buf1   pbase = %l\n"
597        " - chbuf  pbase = %l\n",
598        _fbf_chbuf[channel].fbf,
599        _fbf_chbuf[channel].buf0,
600        _fbf_chbuf[channel].buf1,
601        chbuf_paddr );
602#endif
603
604    // call CMA driver to start transfer
605    _cma_start_channel( channel, 
606                        chbuf_paddr,
607                        2,
608                        chbuf_paddr + 16,
609                        1,
610                        length );
611    return 0;
612
613#else
614
615    _printf("\n[GIET ERROR] in _sys_fbf_cma_start() : NB_CMA_CHANNELS = 0\n");
616    return -1;
617
618#endif
619} // end _sys_fbf_cma_start()
620
621/////////////////////////////////////////////////////
622int _sys_fbf_cma_display( unsigned int buffer_index )
623{
624#if NB_CMA_CHANNELS > 0
625
626    volatile paddr_t buf_paddr;
627    unsigned int     full = 1;
628
629    // get channel index
630    unsigned int channel = _get_context_slot( CTX_FBCMA_ID );
631
632    if ( channel >= NB_CMA_CHANNELS )
633    {
634        _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : CMA channel index too large\n");
635        return -1;
636    }
637
638#if GIET_DEBUG_FBF_CMA
639_printf("\n[FBF_CMA DEBUG] enters _sys_fb_cma_display()\n"
640        " - channel      = %d\n"
641        " - buffer       = %d\n",
642        channel, buffer_index );
643#endif
644
645    // waiting user buffer empty
646    while ( full )
647    { 
648        if ( USE_IOB )
649        {
650            // INVAL L1 cache for the chbuf descriptor,
651            _dcache_buf_invalidate( (unsigned int)&_fbf_chbuf[channel], 32 );
652
653            // INVAL L2 cache for the chbuf descriptor,
654            _mmc_inval( _fbf_chbuf_paddr[channel], 32 );
655        }
656
657        // read user buffer descriptor
658        if ( buffer_index == 0 ) buf_paddr = _fbf_chbuf[channel].buf0;
659        else                     buf_paddr = _fbf_chbuf[channel].buf1;
660
661        full = ( (unsigned int)(buf_paddr>>63) );
662    }
663
664    if ( USE_IOB )
665    {
666        // SYNC request for the user buffer, because
667        // it will be read from XRAM by the CMA component
668        _mmc_sync( buf_paddr, _fbf_chbuf[channel].length );
669    }
670
671    // set user buffer status
672    if ( buffer_index == 0 ) _fbf_chbuf[channel].buf0 = buf_paddr | 0x8000000000000000ULL;
673    else                     _fbf_chbuf[channel].buf1 = buf_paddr | 0x8000000000000000ULL;
674
675    // reset fbf buffer status
676    _fbf_chbuf[channel].fbf  = _fbf_chbuf[channel].fbf & 0x7FFFFFFFFFFFFFFFULL;
677
678    if ( USE_IOB )
679    {
680        // SYNC request for the channel descriptor, because
681        // it will be read from XRAM by the CMA component
682        _mmc_sync( _fbf_chbuf_paddr[channel], 32 );
683    }
684
685#if GIET_DEBUG_FBF_CMA
686_printf(" - fbf    pbase = %l\n"
687        " - buf0   pbase = %l\n"
688        " - buf1   pbase = %l\n",
689        _fbf_chbuf[channel].fbf,
690        _fbf_chbuf[channel].buf0,
691        _fbf_chbuf[channel].buf1 );
692#endif
693
694
695    return 0;
696
697#else
698
699    _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : no CMA channel allocated\n");
700    return -1;
701
702#endif
703} // end _sys_fbf_cma_display()
704
705///////////////////////
706int _sys_fbf_cma_stop()
707{
708#if NB_CMA_CHANNELS > 0
709
710    // get channel index
711    unsigned int channel = _get_context_slot( CTX_FBCMA_ID );
712
713    if ( channel >= NB_CMA_CHANNELS )
714    {
715        _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : CMA channel index too large\n");
716        return -1;
717    }
718
719    // Desactivate CMA channel
720    _cma_stop_channel( channel );
721
722    return 0;
723
724#else
725
726    _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : no CMA channel allocated\n");
727    return -1;
728
729#endif
730} // end _sys_fbf_cma_stop()
731
732
733//////////////////////////////////////////////////////////////////////////////
734//           Miscelaneous syscall handlers
735//////////////////////////////////////////////////////////////////////////////
736
737///////////////
738int _sys_ukn() 
739{
740    _printf("\n[GIET ERROR] Undefined System Call / EPC = %x\n", _get_epc() );
741    return -1;
742}
743
744////////////////////////////////////
745int _sys_proc_xyp( unsigned int* x,
746                   unsigned int* y,
747                   unsigned int* p )
748{
[428]749    unsigned int gpid = _get_procid();  // global processor index from CPO register
750
751    *x = (gpid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1);
752    *y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
753    *p = gpid & ((1<<P_WIDTH)-1);
[440]754
755    return 0;
[428]756}
[440]757
758//////////////////////////////////
759int _sys_task_exit( char* string ) 
[258]760{
[294]761    unsigned int date       = _get_proctime();
[428]762
763    unsigned int gpid       = _get_procid();
764    unsigned int cluster_xy = gpid >> P_WIDTH;
[294]765    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
766    unsigned int x          = cluster_xy >> Y_WIDTH;
[428]767    unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
768
[294]769    unsigned int task_id    = _get_context_slot(CTX_LTID_ID);
[258]770
[440]771    // print exit message
[294]772    _printf("\n[GIET] Exit task %d on processor[%d,%d,%d] at cycle %d"
773            "\n       Cause : %s\n\n",
774            task_id, x, y, lpid, date, string );
[258]775
776    // goes to sleeping state
777    _set_context_slot(CTX_RUN_ID, 0);
778
779    // deschedule
780    _context_switch();
[440]781
782    return 0;
[258]783} 
784
[440]785//////////////////////
786int _context_switch() 
[258]787{
[440]788    unsigned int save_sr;
[258]789
[440]790    _it_disable( &save_sr );
791    _ctx_switch();
792    _it_restore( &save_sr );
793
794    return 0;
[258]795}
796
[440]797////////////////////////
798int _sys_local_task_id()
[258]799{
800    return _get_context_slot(CTX_LTID_ID);
801}
802
[440]803/////////////////////////
804int _sys_global_task_id()
[258]805{
806    return _get_context_slot(CTX_GTID_ID);
807}
808
[440]809////////////////////
810int _sys_thread_id()
[267]811{
812    return _get_context_slot(CTX_TRDID_ID);
813}
814
[440]815//////////////////////////////////////
816int _sys_procs_number( unsigned int  x, 
817                       unsigned int  y, 
818                       unsigned int* number )
[258]819{
[440]820    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
821    mapping_cluster_t * cluster = _get_cluster_base(header);
822
823    if ( (x < X_SIZE) && (y < Y_SIZE) )
824    {
825        *number = cluster[(x*Y_SIZE)+y].procs;
826        return 0;
827    }
828    else 
829    {
830        _printf("\n[GIET ERROR] in _sys_procs_number() : illegal (x,y) coordinates\n" );
831        return -1;
832    }
833}
834
835///////////////////////////////////////////////////////
836int _sys_vobj_get_vbase( char*             vspace_name, 
837                         char*             vobj_name, 
838                         unsigned int*     vbase ) 
839{
[322]840    mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
[258]841    mapping_vspace_t * vspace = _get_vspace_base(header);
842    mapping_vobj_t * vobj     = _get_vobj_base(header);
843
844    unsigned int vspace_id;
845    unsigned int vobj_id;
846
847    // scan vspaces
848    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 
849    {
850        if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) 
851        {
852            // scan vobjs
853            for (vobj_id = vspace[vspace_id].vobj_offset; 
854                 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs); 
855                 vobj_id++) 
856            {
857                if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0) 
858                {
[440]859                    *vbase = vobj[vobj_id].vbase;
[258]860                    return 0;
861                }
862            } 
863        }
864    } 
[440]865    return -1;    // not found
[258]866}
867
[440]868/////////////////////////////////////////////////////////
869int _sys_vobj_get_length( char*         vspace_name, 
870                          char*         vobj_name,
871                          unsigned int* length ) 
[258]872{
[440]873    mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
874    mapping_vspace_t * vspace = _get_vspace_base(header);
875    mapping_vobj_t * vobj     = _get_vobj_base(header);
[258]876
[440]877    unsigned int vspace_id;
878    unsigned int vobj_id;
879
880    // scan vspaces
881    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 
[258]882    {
[440]883        if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) 
884        {
885            // scan vobjs
886            for (vobj_id = vspace[vspace_id].vobj_offset; 
887                 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs); 
888                 vobj_id++) 
889            {
890                if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0) 
891                {
892                    *length = vobj[vobj_id].length;
893                    return 0;
894                }
895            } 
896        }
897    } 
898    return -1;    // not found
[258]899}
900
[440]901////////////////////////////////////////
902int _sys_xy_from_ptr( void*         ptr,
903                      unsigned int* x,
904                      unsigned int* y )
[396]905{
906    unsigned int ret;
907    unsigned int ppn;
908    unsigned int flags;
909    unsigned int vpn  = (((unsigned int)ptr)>>12);
910   
911    // get the page table pointer
912    page_table_t* pt = (page_table_t*)_get_context_slot( CTX_PTAB_ID ); 
913
914    // compute the physical address
[440]915    if ( (ret = _v2p_translate( pt, vpn, &ppn, &flags )) ) return -1;
[396]916
[440]917    *x = (ppn>>24) & 0xF;
918    *y = (ppn>>20) & 0xF;
[396]919    return 0;
920}
921
[440]922/////////////////////////////////////////
923int _sys_heap_info( unsigned int* vaddr, 
924                    unsigned int* length,
925                    unsigned int  x,
926                    unsigned int  y ) 
[258]927{
[440]928    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
929    mapping_task_t *   tasks   = _get_task_base(header);
930    mapping_vobj_t *   vobjs   = _get_vobj_base(header);
931    mapping_vspace_t * vspaces = _get_vspace_base(header);
[294]932
[440]933    unsigned int task_id;
934    unsigned int vspace_id;
935    unsigned int vobj_id = 0xFFFFFFFF;
[258]936
[440]937    // searching the heap vobj_id
938    if ( (x < X_SIZE) && (y < Y_SIZE) )  // searching a task in cluster(x,y)
939    {
940        // get vspace global index
941        vspace_id = _get_context_slot(CTX_VSID_ID);
942
943        // scan all tasks in vspace
944        unsigned int min = vspaces[vspace_id].task_offset ;
945        unsigned int max = min + vspaces[vspace_id].tasks ;
946        for ( task_id = min ; task_id < max ; task_id++ )
947        {
948            if ( tasks[task_id].clusterid == (x * Y_SIZE + y) )
949            {
950                vobj_id = tasks[task_id].heap_vobj_id;
951                if ( vobj_id != 0xFFFFFFFF ) break;
952            }
953        }
954    }
955    else                                // searching in the calling task
956    {
957        task_id = _get_context_slot(CTX_GTID_ID);
958        vobj_id = tasks[task_id].heap_vobj_id;
959    }
960
961    // analysing the vobj_id
962    if ( vobj_id != 0xFFFFFFFF ) 
963    {
964        *vaddr  = vobjs[vobj_id].vbase;
965        *length = vobjs[vobj_id].length;
966        return 0;
967    }
968    else 
969    {
970        *vaddr  = 0;
971        *length = 0;
972        return -1;
973    }
974}  // end _sys_heap_info()
975
976
[258]977// Local Variables:
978// tab-width: 4
979// c-basic-offset: 4
980// c-file-offsets:((innamespace . 0)(inline-open . 0))
981// indent-tabs-mode: nil
982// End:
983// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
984
Note: See TracBrowser for help on using the repository browser.