Ignore:
Timestamp:
Nov 3, 2014, 11:03:55 AM (10 years ago)
Author:
alain
Message:

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/giet_kernel/sys_handler.c

    r428 r440  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    7 // The sys_handler.c and sys_handler.h files are part of the GIET-VM nano-kernel.
    8 // It define the syscall_vector[] (at the end of this file), as well as the
    9 // associated syscall handlers that are not related to peripherals.
    10 // The syscall handlers for peripherals are defined in the drivers.c file.
    11 ///////////////////////////////////////////////////////////////////////////////////
    127
    138#include <sys_handler.h>
     
    1611#include <ioc_driver.h>
    1712#include <nic_driver.h>
    18 #include <fbf_driver.h>
     13#include <mmc_driver.h>
     14#include <cma_driver.h>
    1915#include <ctx_handler.h>
    2016#include <fat32.h>
    2117#include <utils.h>
     18#include <kernel_utils.h>
    2219#include <vmem.h>
    2320#include <hard_config.h>
     
    2825# error: You must define SEG_BOOT_MAPPING_BASE in the hard_config.h file
    2926#endif
     27
     28////////////////////////////////////////////////////////////////////////////
     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;
    3037
    3138////////////////////////////////////////////////////////////////////////////
     
    3542const void * _syscall_vector[64] =
    3643{
    37     &_proc_xyp,            /* 0x00 */
    38     &_get_proctime,        /* 0x01 */
    39     &_tty_write,           /* 0x02 */
    40     &_tty_read,            /* 0x03 */
    41     &_timer_start,         /* 0x04 */
    42     &_timer_stop,          /* 0x05 */
    43     &_tty_get_lock,        /* 0x06 */
    44     &_tty_release_lock,    /* 0x07 */
    45     &_heap_info,           /* 0x08 */
    46     &_local_task_id,       /* 0x09 */
    47     &_global_task_id,      /* 0x0A */
    48     &_fb_cma_init,         /* 0x0B */
    49     &_fb_cma_write,        /* 0x0C */
    50     &_fb_cma_stop,         /* 0x0D */
    51     &_task_exit,           /* 0x0E */
    52     &_procs_number,        /* 0x0F */
    53 
    54     &_fb_sync_write,       /* 0x10 */
    55     &_fb_sync_read,        /* 0x11 */
    56     &_thread_id,           /* 0x12 */
    57     &_sys_ukn,             /* 0x13 */
    58     &_sys_ukn,             /* 0x14 */
    59     &_sys_ukn,             /* 0x15 */
    60     &_sys_ukn,             /* 0x16 */
    61     &_sys_ukn,             /* 0x17 */
    62     &_sys_ukn,             /* 0x18 */   
    63     &_context_switch,      /* 0x19 */
    64     &_vobj_get_vbase,      /* 0x1A */
    65     &_get_xy_from_ptr,     /* 0x1B */
    66     &_nic_cma_start,       /* 0x1C */
    67     &_nic_cma_stop,        /* 0x1D */
    68     &_nic_sync_read,       /* 0x1E */
    69     &_nic_sync_write,      /* 0x1F */
    70 
    71     &_fat_user_open,       /* 0x20 */
    72     &_fat_user_read,       /* 0x21 */
    73     &_fat_user_write,      /* 0x22 */
    74     &_fat_user_lseek,      /* 0x23 */
    75     &_fat_fstat,           /* 0x24 */
    76     &_fat_close,           /* 0x25 */
    77     &_sys_ukn,             /* 0x26 */
    78     &_sys_ukn,             /* 0x27 */
    79     &_sys_ukn,             /* 0x28 */
    80     &_sys_ukn,             /* 0x29 */
    81     &_sys_ukn,             /* 0x2A */
    82     &_sys_ukn,             /* 0x2B */
    83     &_sys_ukn,             /* 0x2C */
    84     &_sys_ukn,             /* 0x2D */
    85     &_sys_ukn,             /* 0x2E */
    86     &_sys_ukn,             /* 0x2F */
    87 
    88     &_sys_ukn,             /* 0x30 */
    89     &_sys_ukn,             /* 0x31 */
    90     &_sys_ukn,             /* 0x32 */
    91     &_sys_ukn,             /* 0x33 */
    92     &_sys_ukn,             /* 0x34 */
    93     &_sys_ukn,             /* 0x35 */
    94     &_sys_ukn,             /* 0x36 */
    95     &_sys_ukn,             /* 0x37 */
    96     &_sys_ukn,             /* 0x38 */   
    97     &_sys_ukn,             /* 0x39 */
    98     &_sys_ukn,             /* 0x3A */
    99     &_sys_ukn,             /* 0x3B */
    100     &_sys_ukn,             /* 0x3C */
    101     &_sys_ukn,             /* 0x3D */
    102     &_sys_ukn,             /* 0x3E */
    103     &_sys_ukn,             /* 0x3F */
     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 */
     60
     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 */
     77
     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 */
     94
     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 */
    104111};
    105112
    106113//////////////////////////////////////////////////////////////////////////////
    107 // function executed in case of undefined syscall
     114//             TTY related syscall handlers
    108115//////////////////////////////////////////////////////////////////////////////
    109 void _sys_ukn()
    110 {
    111     _printf("\n\n[GIET ERROR] Undefined System Call / EPC = %x\n", _get_epc() );
    112     _exit();
     116
     117////////////////////
     118int _sys_tty_alloc()
     119{
     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;
     143}
     144
     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;
    113219}
    114220
    115221//////////////////////////////////////////////////////////////////////////////
    116 // This function returns the processor (x,y,p) identifiers.
     222//             TIM related syscall handlers
    117223//////////////////////////////////////////////////////////////////////////////
    118 void _proc_xyp( unsigned int* x,
    119                 unsigned int* y,
    120                 unsigned int* p )
     224
     225////////////////////
     226int _sys_tim_alloc()
     227{
     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 )
    121748{
    122749    unsigned int gpid = _get_procid();  // global processor index from CPO register
     
    125752    *y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
    126753    *p = gpid & ((1<<P_WIDTH)-1);
    127 }
    128 ////////////////////////////////////////////////////////////////////////////
    129 // Task suicide... after printing a death message.
    130 ////////////////////////////////////////////////////////////////////////////
    131 void _task_exit( char* string )
     754
     755    return 0;
     756}
     757
     758//////////////////////////////////
     759int _sys_task_exit( char* string )
    132760{
    133761    unsigned int date       = _get_proctime();
     
    141769    unsigned int task_id    = _get_context_slot(CTX_LTID_ID);
    142770
    143     // print death message
     771    // print exit message
    144772    _printf("\n[GIET] Exit task %d on processor[%d,%d,%d] at cycle %d"
    145773            "\n       Cause : %s\n\n",
     
    151779    // deschedule
    152780    _context_switch();
     781
     782    return 0;
    153783}
    154784
    155 //////////////////////////////////////////////////////////////////////////////
    156 // returns in buffer argument the number of processors in the cluster
    157 // specified by the cluster_id argument.
    158 //////////////////////////////////////////////////////////////////////////////
    159 unsigned int _procs_number(unsigned int  cluster_id,
    160                            unsigned int* buffer)
     785//////////////////////
     786int _context_switch()
     787{
     788    unsigned int save_sr;
     789
     790    _it_disable( &save_sr );
     791    _ctx_switch();
     792    _it_restore( &save_sr );
     793
     794    return 0;
     795}
     796
     797////////////////////////
     798int _sys_local_task_id()
     799{
     800    return _get_context_slot(CTX_LTID_ID);
     801}
     802
     803/////////////////////////
     804int _sys_global_task_id()
     805{
     806    return _get_context_slot(CTX_GTID_ID);
     807}
     808
     809////////////////////
     810int _sys_thread_id()
     811{
     812    return _get_context_slot(CTX_TRDID_ID);
     813}
     814
     815//////////////////////////////////////
     816int _sys_procs_number( unsigned int  x,
     817                       unsigned int  y,
     818                       unsigned int* number )
    161819{
    162820    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
    163821    mapping_cluster_t * cluster = _get_cluster_base(header);
    164822
    165     if ( cluster_id < X_SIZE * Y_SIZE )
    166     {
    167         *buffer = cluster[cluster_id].procs;
     823    if ( (x < X_SIZE) && (y < Y_SIZE) )
     824    {
     825        *number = cluster[(x*Y_SIZE)+y].procs;
    168826        return 0;
    169827    }
    170828    else
    171829    {
    172         return 1;
    173     }
    174 }
    175 
    176 /////////////////////////////////////////////////////////////////////////////
    177 // Returns current task local index.
    178 /////////////////////////////////////////////////////////////////////////////
    179 unsigned int _local_task_id()
    180 {
    181     return _get_context_slot(CTX_LTID_ID);
    182 }
    183 
    184 /////////////////////////////////////////////////////////////////////////////
    185 // Returns current task global index.
    186 /////////////////////////////////////////////////////////////////////////////
    187 unsigned int _global_task_id()
    188 {
    189     return _get_context_slot(CTX_GTID_ID);
    190 }
    191 
    192 /////////////////////////////////////////////////////////////////////////////
    193 // Returns current thread index.
    194 /////////////////////////////////////////////////////////////////////////////
    195 unsigned int _thread_id()
    196 {
    197     return _get_context_slot(CTX_TRDID_ID);
    198 }
    199 
    200 /////////////////////////////////////////////////////////////////////////////
    201 // This function writes in res_vobj a pointer on a vobj
    202 // identified by the (vspace_name / vobj_name ) couple.
    203 // returns 0 if success, >0 if not found
    204 /////////////////////////////////////////////////////////////////////////////
    205 int _get_vobj( char*             vspace_name,
    206                char*             vobj_name,
    207                mapping_vobj_t**  res_vobj )
     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 )
    208839{
    209840    mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     
    226857                if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0)
    227858                {
    228                     *res_vobj = &vobj[vobj_id];
     859                    *vbase = vobj[vobj_id].vbase;
    229860                    return 0;
    230861                }
     
    232863        }
    233864    }
    234     return 1;    //not found
    235 }
    236 
    237 /////////////////////////////////////////////////////////////////////////////
    238 // This function writes in vobj_vbase the virtual base address of a vobj
    239 // identified by the (vspace_name / vobj_name ) couple.
    240 // returns 0 if success, >0 if not found
    241 /////////////////////////////////////////////////////////////////////////////
    242 unsigned int _vobj_get_vbase( char*         vspace_name,
    243                               char*         vobj_name,
    244                               unsigned int* vobj_vbase )
    245 {
    246     mapping_vobj_t* res_vobj;
    247     unsigned int    ret;
    248     if ((ret = _get_vobj(vspace_name, vobj_name, &res_vobj)))
    249     {
    250         return ret;
    251     }
    252     *vobj_vbase = res_vobj->vbase;
    253     return 0;
    254 }
    255 
    256 /////////////////////////////////////////////////////////////////////////////
    257 // This function writes in vobj_length the length of a vobj
    258 // identified by the (vspace_name / vobj_name ) couple.
    259 // returns 0 if success, >0 if not found
    260 /////////////////////////////////////////////////////////////////////////////
    261 unsigned int _vobj_get_length( char*         vspace_name,
    262                                char*         vobj_name,
    263                                unsigned int* vobj_length )
    264 {
    265     mapping_vobj_t * res_vobj;
    266     unsigned int ret;
    267     if ((ret = _get_vobj(vspace_name, vobj_name, &res_vobj)))
    268     {
    269         return ret;
    270     }
    271     *vobj_length = res_vobj->length;
    272     return 0;
    273 }
    274 
    275 /////////////////////////////////////////////////////////////////////////////
    276 // This function returns in the (x,y) arguments the coordinates of the
    277 // where is mapped the ptr virtual address. It use the _get_context_slot()
    278 // function to get the calling task page table, and uses the _v2p_translate()
    279 // function to obtain the physical address.
    280 // returns 0 if success, > 0 if ptr not mapped in the calling task vspace.
    281 /////////////////////////////////////////////////////////////////////////////
    282 
    283 unsigned int _get_xy_from_ptr( void*         ptr,
    284                                unsigned int* px,
    285                                unsigned int* py )
     865    return -1;    // not found
     866}
     867
     868/////////////////////////////////////////////////////////
     869int _sys_vobj_get_length( char*         vspace_name,
     870                          char*         vobj_name,
     871                          unsigned int* length )
     872{
     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);
     876
     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++)
     882    {
     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
     899}
     900
     901////////////////////////////////////////
     902int _sys_xy_from_ptr( void*         ptr,
     903                      unsigned int* x,
     904                      unsigned int* y )
    286905{
    287906    unsigned int ret;
     
    294913
    295914    // compute the physical address
    296     if ( (ret = _v2p_translate( pt, vpn, &ppn, &flags )) )
    297     {
    298         return ret;
    299     }
    300 
    301     *px = (ppn>>24) & 0xF;
    302     *py = (ppn>>20) & 0xF;
    303     return 0;
    304 }
    305 
    306 ////////////////////////////////////////////////////////////////////////////
    307 // This sysrem function deschedule the requestint task.
    308 // It mask interrupts before calling the _ctx_switch, and restore it
    309 // when the task is rescheduled.
    310 ////////////////////////////////////////////////////////////////////////////
    311 void _context_switch()
    312 {
    313     unsigned int save_sr;
    314 
    315     _it_disable( &save_sr );
    316     _ctx_switch();
    317     _it_restore( &save_sr );
    318 }
     915    if ( (ret = _v2p_translate( pt, vpn, &ppn, &flags )) ) return -1;
     916
     917    *x = (ppn>>24) & 0xF;
     918    *y = (ppn>>20) & 0xF;
     919    return 0;
     920}
     921
     922/////////////////////////////////////////
     923int _sys_heap_info( unsigned int* vaddr,
     924                    unsigned int* length,
     925                    unsigned int  x,
     926                    unsigned int  y )
     927{
     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);
     932
     933    unsigned int task_id;
     934    unsigned int vspace_id;
     935    unsigned int vobj_id = 0xFFFFFFFF;
     936
     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
    319976
    320977// Local Variables:
Note: See TracChangeset for help on using the changeset viewer.