Ignore:
Timestamp:
Nov 11, 2014, 4:14:55 PM (10 years ago)
Author:
alain
Message:

Introducing the CMA_RX, CMA_TX, NIC_RX, NIC_TX slots in the task context.
This allows an user task to have a private NIC channel and a private CMA channel.

File:
1 edited

Legend:

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

    r440 r449  
    2626#endif
    2727
     28#if !defined(NB_TTY_CHANNELS)
     29# error: You must define NB_TTY_CHANNELS in the hard_config.h file
     30#endif
     31
     32#if !defined(NB_TIM_CHANNELS)
     33# error: You must define NB_TIM_CHANNELS in the hard_config.h file
     34#endif
     35
     36#if !defined(NB_NIC_CHANNELS)
     37# error: You must define NB_NIC_CHANNELS in the hard_config.h file
     38#endif
     39
     40#if !defined(NB_CMA_CHANNELS)
     41# error: You must define NB_CMA_CHANNELS in the hard_config.h file
     42#endif
     43
     44#if !defined(GIET_NIC_CHBUF_NBUFS)
     45# error: You must define GIET_NIC_CHBUF_NBUFS in the giet_config.h file
     46#endif
     47
     48#if !defined(GIET_NIC_CHBUF_SIZE)
     49# error: You must define GIET_NIC_CHBUF_SIZE in the giet_config.h file
     50#endif
     51
     52#if !defined(GIET_NIC_CHBUF_TIMEOUT)
     53# error: You must define GIET_NIC_CHBUF_TIMEOUT in the giet_config.h file
     54#endif
     55
     56
    2857////////////////////////////////////////////////////////////////////////////
    2958//     Channel allocators for peripherals
     
    3463unsigned int _tim_channel_allocator = 0;
    3564unsigned int _cma_channel_allocator = 0;
    36 unsigned int _nic_channel_allocator = 0;
     65unsigned int _nic_rx_channel_allocator = 0;
     66unsigned int _nic_tx_channel_allocator = 0;
     67
     68
     69////////////////////////////////////////////////////////////////////////////
     70//     NIC_RX and NIC_TX chbuf arrays
     71////////////////////////////////////////////////////////////////////////////
     72
     73nic_chbuf_t  _nic_rx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(8)));
     74nic_chbuf_t  _nic_tx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(8)));
     75
    3776
    3877////////////////////////////////////////////////////////////////////////////
     
    72111    &_sys_vobj_get_length,  /* 0x1B */
    73112    &_sys_xy_from_ptr,      /* 0x1C */
    74     &_sys_nic_alloc,        /* 0x1D */
    75     &_sys_nic_sync_send,    /* 0x1E */
    76     &_sys_nic_sync_receive, /* 0x1F */
     113    &_sys_ukn,              /* 0x1D */
     114    &_sys_ukn,              /* 0x1E */
     115    &_sys_ukn,              /* 0x1F */
    77116
    78117    &_fat_user_open,        /* 0x20 */
     
    93132    &_sys_ukn,              /* 0x2F */
    94133
    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 */
     134    &_sys_nic_alloc,        /* 0x30 */
     135    &_sys_nic_alloc,        /* 0x31 */
     136    &_sys_nic_start,        /* 0x32 */
     137    &_sys_nic_start,        /* 0x33 */
     138    &_sys_nic_move,         /* 0x34 */
     139    &_sys_nic_move,         /* 0x35 */
     140    &_sys_nic_stop,         /* 0x36 */
     141    &_sys_nic_stop,         /* 0x37 */
    103142    &_sys_ukn,              /* 0x38 */   
    104143    &_sys_ukn,              /* 0x39 */
     
    119158{
    120159    // get a new TTY terminal index
    121     unsigned int channel = _tty_channel_allocator;
     160    unsigned int channel = _atomic_increment( &_tty_channel_allocator );
    122161    unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
    123162    unsigned int vspace  = _get_context_slot( CTX_VSID_ID );
     
    132171        _printf("\n[GIET WARNING] TTY channel %d allocated "
    133172                " 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;
     173        _set_context_slot( CTX_TTY_ID, channel );
     174        return 0;
     175    }
    143176}
    144177
     
    227260{
    228261    // get a new timer index
    229     unsigned int channel = _tim_channel_allocator;
     262    unsigned int channel = _atomic_increment(&_tim_channel_allocator);
    230263    unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
    231264    unsigned int vspace  = _get_context_slot( CTX_VSID_ID );
     
    240273        _printf("\n[GIET WARNING] TIM channel %d allocated "
    241274                " 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;
     275        _set_context_slot( CTX_TIM_ID, channel );
     276        return 0;
     277    }
    251278}
    252279
     
    289316//////////////////////////////////////////////////////////////////////////////
    290317
    291 ////////////////////
    292 int _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;
     318///////////////////////////////////////////
     319int _sys_nic_alloc( unsigned int is_rx )
     320{
     321    unsigned int nic_channel;
     322    unsigned int cma_channel;
     323
     324    // get a NIC_RX or NIC_TX channel index
     325    if ( is_rx ) nic_channel = _atomic_increment(&_nic_rx_channel_allocator);
     326    else         nic_channel = _atomic_increment(&_nic_tx_channel_allocator);
     327
     328    if ( (nic_channel >= NB_NIC_CHANNELS) )
     329    {
     330        _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough NIC channels\n");
     331        return -1;
     332    }
     333
     334    // get a CMA channel index
     335    cma_channel = _atomic_increment(&_cma_channel_allocator);
     336
     337    if ( cma_channel >= NB_CMA_CHANNELS )
     338    {
     339        _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough CMA channels\n");
     340        return -1;
     341    }
     342   
     343    // register nic_index and cma_index in task context
     344    if ( is_rx )
     345    {
     346        _set_context_slot( CTX_NIC_RX_ID, nic_channel );
     347        _set_context_slot( CTX_CMA_RX_ID, cma_channel );
    303348    }
    304349    else
    305350    {
    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 ////////////////////////////////////
    320 int _sys_nic_sync_send( void* vbuf )
    321 {
     351        _set_context_slot( CTX_NIC_TX_ID, nic_channel );
     352        _set_context_slot( CTX_CMA_TX_ID, cma_channel );
     353    }
     354
     355#if GIET_DEBUG_NIC
     356unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
     357unsigned int vspace  = _get_context_slot( CTX_VSID_ID );
     358_printf("\n[GIET DEBUG_NIC] NIC channel %d and CMA channel %d"
     359        " allocated to task %d in vspace %d\n",
     360        nic_channel, cma_channel, thread, vspace );
     361#endif
     362
     363    return 0;
     364}
     365
     366////////////////////////////////////////
     367int _sys_nic_start( unsigned int is_rx,
     368                    unsigned int mac4,
     369                    unsigned int mac2 )
     370{
     371    unsigned int nic_channel;
     372    unsigned int cma_channel;
     373
     374    // get NIC channel index and CMA channel index
     375    if ( is_rx )
     376    {
     377        nic_channel = _get_context_slot( CTX_NIC_RX_ID );
     378        cma_channel = _get_context_slot( CTX_CMA_RX_ID );
     379    }
     380    else
     381    {
     382        nic_channel = _get_context_slot( CTX_NIC_TX_ID );
     383        cma_channel = _get_context_slot( CTX_CMA_TX_ID );
     384    }
     385
     386    if ( nic_channel >= NB_NIC_CHANNELS )
     387    {
     388        _printf("\n[GIET_ERROR] in _sys_nic_start(): NIC channel not allocated\n");
     389        return -1;
     390    }
     391    if ( cma_channel >= NB_CMA_CHANNELS )
     392    {
     393        _printf("\n[GIET_ERROR] in _sys_nic_start(): CMA channel not allocated\n");
     394        return -1;
     395    }
     396
     397    unsigned int nic_chbuf_lsb;     // 32 LSB bits of the NIC chbuf physical address
     398    unsigned int nic_chbuf_msb;     // 16 MSB bits of the NIC chbuf physical address
     399    unsigned int ker_chbuf_lsb;     // 32 LSB bits of the kernel chbuf physical address
     400    unsigned int ker_chbuf_msb;     // 16 MSB bits of the kernel chbuf physical address
     401
     402    // get the NIC chbuf descriptor physical address
     403    unsigned int offset;
     404    if ( is_rx ) offset = 0x1000;
     405    else         offset = 0x1010;
     406    nic_chbuf_lsb = SEG_NIC_BASE + (nic_channel * NIC_CHANNEL_SPAN) + offset;
     407    nic_chbuf_msb = (X_IO << Y_WIDTH) + Y_IO;
     408
     409    // get the kernel chbuf descriptor physical address
     410    unsigned int ker_chbuf_vaddr;
     411    if ( is_rx ) ker_chbuf_vaddr = (unsigned int)( &_nic_rx_chbuf[nic_channel] );
     412    else         ker_chbuf_vaddr = (unsigned int)( &_nic_tx_chbuf[nic_channel] );
     413
     414    // compute the kernel chbuf descriptor physical address
    322415    unsigned int ppn;
    323416    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 );
     417    unsigned int ptab  = _get_context_slot(CTX_PTAB_ID);
     418    unsigned int ko    = _v2p_translate( (page_table_t*)ptab,
     419                                          ker_chbuf_vaddr,
     420                                          &ppn,
     421                                          &flags );
     422    if ( ko )
     423    {
     424        _puts("\n[GIET ERROR] in _nic_cma_start_receive() : kernel buffer unmapped\n");
     425        return -1;
     426    }
     427
     428    ker_chbuf_lsb = (ppn << 12) | (ker_chbuf_vaddr & 0x00000FFF);
     429    ker_chbuf_msb = ppn >> 20;
     430
     431    // initializes CMA registers defining the source chbuf (NIc)
     432    _cma_set_register( cma_channel, CHBUF_SRC_DESC , nic_chbuf_lsb );
     433    _cma_set_register( cma_channel, CHBUF_DST_EXT  , nic_chbuf_msb );
     434    _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, 2 );
     435
     436    // initializes CMA registers defining the destination chbuf (kernel)
     437    _cma_set_register( cma_channel, CHBUF_DST_DESC , ker_chbuf_lsb );
     438    _cma_set_register( cma_channel, CHBUF_DST_EXT  , ker_chbuf_msb );
     439    _cma_set_register( cma_channel, CHBUF_DST_NBUFS, GIET_NIC_CHBUF_NBUFS );
     440
     441    // start CMA transfer
     442    _cma_set_register( cma_channel, CHBUF_BUF_SIZE , 4096 );
     443    _cma_set_register( cma_channel, CHBUF_PERIOD   , 300 );
     444    _cma_set_register( cma_channel, CHBUF_RUN      , 1 );
     445
     446    // activates NIC channel
     447    _nic_channel_start( nic_channel, is_rx, mac4, mac2 );
     448    return 0;
     449}
     450
     451//////////////////////////////////////
     452int _sys_nic_move( unsigned int is_rx,
     453                   void*        buffer )
     454{
     455    unsigned long long user_paddr;    // user buffer physical address
     456    unsigned long long kernel_paddr;  // kernel buffer physical address
    336457
    337458    // 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 ///////////////////////////////////////
    360 int _sys_nic_sync_receive( void* vbuf )
    361 {
    362459    unsigned int ppn;
    363460    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 );
     461    unsigned int vaddr = (unsigned int)buffer;
     462    unsigned int user_ptab = _get_context_slot( CTX_PTAB_ID );
     463    unsigned int ko = _v2p_translate( (page_table_t*)user_ptab,
     464                                       vaddr,
     465                                       &ppn,
     466                                       &flags );
     467    if ( ko )
     468    {
     469        _printf("\n[GIET ERROR] in _sys_nic_tx_move() : user buffer unmapped\n");
     470        return -1;
     471    }
     472    if ( (flags & PTE_U) == 0 )
     473    {
     474        _printf("\n[GIET ERROR] in _sys_nic_tx_move() : illegal buffer address\n");
     475        return -1;
     476    }
     477    user_paddr = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF);
     478
     479    // get NIC channel index, to get pointer on NIC_TX chbuf pointer
     480    unsigned int channel;
     481    if ( is_rx ) channel = _get_context_slot( CTX_NIC_RX_ID );
     482    else         channel = _get_context_slot( CTX_NIC_TX_ID );
     483
    368484    if ( channel >= NB_NIC_CHANNELS )
    369485    {
    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 );
     486        _printf("\n[GIET_ERROR] in _sys_nic_move() : illegal NIC channel index\n");
     487        return -1;
     488    }
     489
     490    nic_chbuf_t* chbuf;
     491    if ( is_rx ) chbuf = &_nic_rx_chbuf[channel];
     492    else         chbuf = &_nic_tx_chbuf[channel];
     493
     494    // polling on the chbuf status
     495    volatile unsigned long long desc;
     496    unsigned int full;
     497    unsigned int ok      = 0;
     498    unsigned int index   = chbuf->index;
     499    unsigned int timeout = GIET_NIC_CHBUF_TIMEOUT;
     500    while( ok == 0 )
     501    {
     502        desc  = chbuf->buffer[index];
     503        full  =  desc >> 63;
     504        if ( (is_rx && full) || ((is_rx == 0) && (full == 0)) )  // success
     505        {
     506            ok = 1;
     507        }
     508        else                                                   // retry
     509        {
     510            timeout--;
     511        }
     512        if ( timeout == 0 )
     513        {
     514            _printf("\n[GIET_ERROR] in _sys_ni_move() : timeout\n");
     515            return -1;
     516        }
     517    }
     518    kernel_paddr = desc & 0x0000FFFFFFFFFFFFULL;
     519   
     520    // move one container using, a physical_memcpy
     521    if ( is_rx ) _physical_memcpy( user_paddr,
     522                                   kernel_paddr,
     523                                   GIET_NIC_CHBUF_SIZE );
     524
     525    else         _physical_memcpy( kernel_paddr,
     526                                   user_paddr,
     527                                   GIET_NIC_CHBUF_SIZE );
     528
     529    // update chbuf status and index
     530    if ( is_rx ) chbuf->buffer[index] = desc & 0x0000FFFFFFFFFFFFULL;
     531    else         chbuf->buffer[index] = desc | 0x8000000000000000ULL;
     532    if ( index == (GIET_NIC_CHBUF_NBUFS - 1) ) chbuf->index = 0;
     533    else                                       chbuf->index = index + 1;
     534
     535    return 0;
     536} // end _sys_nic_move()
     537
     538////////////////////////////////////////
     539int _sys_nic_stop( unsigned int is_rx )
     540{
     541    unsigned int nic_channel;
     542    unsigned int cma_channel;
     543
     544    // get NIC channel index and CMA channel index
     545    if ( is_rx )
     546    {
     547        nic_channel = _get_context_slot( CTX_NIC_RX_ID );
     548        cma_channel = _get_context_slot( CTX_CMA_RX_ID );
     549    }
     550    else
     551    {
     552        nic_channel = _get_context_slot( CTX_NIC_TX_ID );
     553        cma_channel = _get_context_slot( CTX_CMA_TX_ID );
     554    }
     555
     556    if ( nic_channel >= NB_NIC_CHANNELS )
     557    {
     558        _printf("\n[GIET_ERROR] in _sys_nic_start(): NIC channel not allocated\n");
     559        return -1;
     560    }
     561    if ( cma_channel >= NB_CMA_CHANNELS )
     562    {
     563        _printf("\n[GIET_ERROR] in _sys_nic_start(): CMA channel not allocated\n");
     564        return -1;
     565    }
     566
     567    // desactivates the NIC channel
     568    _nic_channel_stop( nic_channel, is_rx );
     569
     570    // desactivates the CMA channel
     571    _cma_channel_stop( cma_channel );
    395572
    396573    return 0;
     
    434611int _sys_fbf_cma_alloc()
    435612{
    436 #if NB_CMA_CHANNELS > 0
    437 
    438613   // get a new CMA channel index
    439     unsigned int channel = _cma_channel_allocator;
     614    unsigned int channel = _atomic_increment( &_cma_channel_allocator );
    440615    unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
    441616    unsigned int vspace  = _get_context_slot( CTX_VSID_ID );
     
    450625        _printf("\n[GIET WARNING] FBF_CMA channel %d allocated "
    451626                " 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
     627        _set_context_slot( CTX_CMA_FB_ID, channel );
     628        return 0;
     629    }
    468630} // end sys_fbf_cma_alloc()
    469631
     
    483645
    484646    // get channel index
    485     unsigned int channel = _get_context_slot( CTX_FBCMA_ID );
     647    unsigned int channel = _get_context_slot( CTX_CMA_FB_ID );
    486648
    487649    if ( channel >= NB_CMA_CHANNELS )
     
    603765
    604766    // call CMA driver to start transfer
    605     _cma_start_channel( channel,
     767    _cma_channel_start( channel,
    606768                        chbuf_paddr,
    607769                        2,
     
    628790
    629791    // get channel index
    630     unsigned int channel = _get_context_slot( CTX_FBCMA_ID );
     792    unsigned int channel = _get_context_slot( CTX_CMA_FB_ID );
    631793
    632794    if ( channel >= NB_CMA_CHANNELS )
     
    709871
    710872    // get channel index
    711     unsigned int channel = _get_context_slot( CTX_FBCMA_ID );
     873    unsigned int channel = _get_context_slot( CTX_CMA_FB_ID );
    712874
    713875    if ( channel >= NB_CMA_CHANNELS )
     
    718880
    719881    // Desactivate CMA channel
    720     _cma_stop_channel( channel );
     882    _cma_channel_stop( channel );
    721883
    722884    return 0;
Note: See TracChangeset for help on using the changeset viewer.