Changeset 459


Ignore:
Timestamp:
Dec 5, 2014, 3:51:22 PM (9 years ago)
Author:
alain
Message:

Removing the kernel_utils.c/kernel_utils.h file.
Introducing new functions in sys_handler.c/sys_handler.h to handle NIC related system calls.

Location:
soft/giet_vm/giet_kernel
Files:
2 deleted
6 edited

Legend:

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

    r440 r459  
    99#include <giet_config.h>
    1010#include <utils.h>
    11 #include <kernel_utils.h>
     11#include <tty0.h>
    1212#include <xcu_driver.h>
    1313
  • soft/giet_vm/giet_kernel/exc_handler.c

    r440 r459  
    1010#include <sys_handler.h>
    1111#include <utils.h>
    12 #include <kernel_utils.h>
     12#include <tty0.h>
    1313
    1414///////////////////////////////////////////////////////////////////////////////////
  • soft/giet_vm/giet_kernel/irq_handler.c

    r440 r459  
    2121#include <mapping_info.h>
    2222#include <utils.h>
    23 #include <kernel_utils.h>
     23#include <tty0.h>
    2424
    2525#if NB_TIM_CHANNELS
  • soft/giet_vm/giet_kernel/kernel_init.c

    r449 r459  
    1111#include <hard_config.h>
    1212#include <utils.h>
    13 #include <kernel_utils.h>
     13#include <tty0.h>
    1414#include <fat32.h>
    1515#include <xcu_driver.h>
     16#include <ioc_driver.h>
    1617#include <ctx_handler.h>
    1718#include <irq_handler.h>
     
    107108    // This initialisation is done sequencially by each processor
    108109    while( cpid != kernel_init_barrier ) asm volatile ( "nop" );
     110
     111    // Step 0 : Processor[0,0,0] initialises the kernel FAT
     112    if ( gpid == 0 ) _fat_init( IOC_BOOT_MODE );
    109113
    110114    // Step 1 : each processor get its scheduler virtual address from CP0_SCHED register
  • soft/giet_vm/giet_kernel/sys_handler.c

    r449 r459  
    1616#include <fat32.h>
    1717#include <utils.h>
    18 #include <kernel_utils.h>
     18#include <tty0.h>
    1919#include <vmem.h>
    2020#include <hard_config.h>
     
    3030#endif
    3131
     32#if (NB_TTY_CHANNELS < 1)
     33# error: NB_TTY_CHANNELS cannot be smaller than 1!
     34#endif
     35
    3236#if !defined(NB_TIM_CHANNELS)
    3337# error: You must define NB_TIM_CHANNELS in the hard_config.h file
     
    4246#endif
    4347
    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
     48#if !defined(GIET_NIC_NBUFS)
     49# error: You must define GIET_NIC_NBUFS in the giet_config.h file
     50#endif
     51
     52#if !defined(GIET_NIC_BUFSIZE)
     53# error: You must define GIET_NIC_BUFSIZE in the giet_config.h file
     54#endif
     55
     56#if !defined(GIET_NIC_TIMEOUT)
     57# error: You must define GIET_NIC_TIMEOUT in the giet_config.h file
     58#endif
     59
     60#if !defined(GIET_NO_HARD_CC)
     61# error: You must define GIET_NO_HARD_CC in the giet_config.h file
    5462#endif
    5563
     
    6674unsigned int _nic_tx_channel_allocator = 0;
    6775
    68 
    6976////////////////////////////////////////////////////////////////////////////
    70 //     NIC_RX and NIC_TX chbuf arrays
     77//     NIC_RX and NIC_TX chbuf arrays and associated containers arrays
    7178////////////////////////////////////////////////////////////////////////////
    7279
    73 nic_chbuf_t  _nic_rx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(8)));
    74 nic_chbuf_t  _nic_tx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(8)));
    75 
     80spin_lock_t  _nic_rx_lock[NB_NIC_CHANNELS]  __attribute__((aligned(64)));
     81
     82spin_lock_t  _nic_tx_lock[NB_NIC_CHANNELS]  __attribute__((aligned(64)));
     83
     84nic_chbuf_t  _nic_rx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64)));
     85
     86nic_chbuf_t  _nic_tx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64)));
     87
     88unsigned char _nic_rx_cont[GIET_NIC_BUFSIZE]
     89                         [GIET_NIC_NBUFS]
     90                         [NB_NIC_CHANNELS] __attribute__((aligned(64)));
     91
     92unsigned char _nic_tx_cont[GIET_NIC_BUFSIZE]
     93                         [GIET_NIC_NBUFS]
     94                         [NB_NIC_CHANNELS] __attribute__((aligned(64)));
    7695
    7796////////////////////////////////////////////////////////////////////////////
     
    133152
    134153    &_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 */
     154    &_sys_nic_start,        /* 0x31 */
     155    &_sys_nic_move,         /* 0x32 */
     156    &_sys_nic_stop,         /* 0x33 */
     157    &_sys_nic_stats,        /* 0x34 */
     158    &_sys_nic_clear,        /* 0x35 */
     159    &_sys_ukn,              /* 0x36 */
     160    &_sys_ukn,              /* 0x37 */
    142161    &_sys_ukn,              /* 0x38 */   
    143162    &_sys_ukn,              /* 0x39 */
     
    150169};
    151170
     171
    152172//////////////////////////////////////////////////////////////////////////////
    153173//             TTY related syscall handlers
     
    158178{
    159179    // get a new TTY terminal index
    160     unsigned int channel = _atomic_increment( &_tty_channel_allocator );
     180    unsigned int channel = _atomic_increment( &_tty_channel_allocator, 1 );
    161181    unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
    162182    unsigned int vspace  = _get_context_slot( CTX_VSID_ID );
     
    235255
    236256    _it_disable( save_sr_ptr );
    237     _get_lock( &_tty_lock[channel] );
     257    _simple_lock_acquire( &_tty_tx_lock[channel] );
    238258    return 0;
    239259}
     
    247267    if( channel >= NB_TTY_CHANNELS ) return -1;
    248268
    249     _release_lock( &_tty_lock[channel] );
     269    _simple_lock_release( &_tty_tx_lock[channel] );
    250270    _it_restore( save_sr_ptr );
    251271    return 0;
     
    260280{
    261281    // get a new timer index
    262     unsigned int channel = _atomic_increment(&_tim_channel_allocator);
     282    unsigned int channel = _atomic_increment( &_tim_channel_allocator, 1 );
    263283    unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
    264284    unsigned int vspace  = _get_context_slot( CTX_VSID_ID );
     
    319339int _sys_nic_alloc( unsigned int is_rx )
    320340{
    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 );
    348     }
    349     else
    350     {
    351         _set_context_slot( CTX_NIC_TX_ID, nic_channel );
    352         _set_context_slot( CTX_CMA_TX_ID, cma_channel );
    353     }
    354341
    355342#if GIET_DEBUG_NIC
    356343unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
    357344unsigned 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 ////////////////////////////////////////
    367 int _sys_nic_start( unsigned int is_rx,
    368                     unsigned int mac4,
    369                     unsigned int mac2 )
    370 {
     345_printf("\n[GIET DEBUG NIC] Task %d in vspace %d enters sys_nic_alloc()\n",
     346        thread, vspace );
     347#endif
     348
    371349    unsigned int nic_channel;
    372350    unsigned int cma_channel;
    373351
     352    // get a NIC_RX or NIC_TX channel index
     353    if ( is_rx ) nic_channel = _atomic_increment( &_nic_rx_channel_allocator, 1 );
     354    else         nic_channel = _atomic_increment( &_nic_tx_channel_allocator, 1 );
     355
     356    if ( (nic_channel >= NB_NIC_CHANNELS) )
     357    {
     358        _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough NIC channels\n");
     359        return -1;
     360    }
     361
     362    // get a CMA channel index
     363    cma_channel = _atomic_increment( &_cma_channel_allocator, 1 );
     364
     365    if ( cma_channel >= NB_CMA_CHANNELS )
     366    {
     367        _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough CMA channels\n");
     368        return -1;
     369    }
     370
     371    // register nic_index and cma_index in task context
     372    if ( is_rx )
     373    {
     374        _set_context_slot( CTX_NIC_RX_ID, nic_channel );
     375        _set_context_slot( CTX_CMA_RX_ID, cma_channel );
     376    }
     377    else
     378    {
     379        _set_context_slot( CTX_NIC_TX_ID, nic_channel );
     380        _set_context_slot( CTX_CMA_TX_ID, cma_channel );
     381    }
     382
     383#if GIET_DEBUG_NIC
     384_printf("\n[GIET DEBUG NIC] Task %d in vspace %d exit _sys_nic_alloc() : "
     385        "NIC channel = %d / CMA channel = %d\n",
     386        thread, vspace, nic_channel, cma_channel );
     387#endif
     388
     389    return nic_channel;
     390} // end _sys_nic_alloc()
     391
     392////////////////////////////////////////
     393int _sys_nic_start( unsigned int is_rx )
     394{
     395
     396#if GIET_DEBUG_NIC
     397unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
     398unsigned int vspace  = _get_context_slot( CTX_VSID_ID );
     399_printf("\n[GIET DEBUG NIC] Task %d of vspace %d enters _sys_nic_start()\n",
     400        thread, vspace );
     401#endif
     402
     403    unsigned int nic_channel;
     404    unsigned int cma_channel;
     405
    374406    // get NIC channel index and CMA channel index
    375407    if ( is_rx )
     
    384416    }
    385417
     418#if GIET_DEBUG_NIC
     419_printf("\n[GIET DEBUG NIC] Task %d of vspace %d in _sys_nic_start()"
     420        " get NIC channel = %d / CMA channel = %d\n",
     421        thread, vspace, nic_channel, cma_channel );
     422#endif
     423
    386424    if ( nic_channel >= NB_NIC_CHANNELS )
    387425    {
     
    395433    }
    396434
    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
     435    unsigned long long nic_chbuf_pbase;     // NIC chbuf physical address
     436    unsigned long long ker_chbuf_pbase;     // kernel chbuf physical address
     437    unsigned long long ker_cont_pbase;      // kernel container array physical address
     438
     439    // These variables are used for V2P translation
     440    unsigned int       ptab  = _get_context_slot(CTX_PTAB_ID);
     441    unsigned int       ppn;
     442    unsigned int       flags;
     443    unsigned int       ko;
     444    unsigned int       vaddr;
    401445
    402446    // get the NIC chbuf descriptor physical address
    403447    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] );
     448    if ( is_rx ) offset = 0x4000;
     449    else         offset = 0x4010;
     450    nic_chbuf_pbase = (((unsigned long long)((X_IO << Y_WIDTH) + Y_IO))<<32) |
     451                      (SEG_NIC_BASE + (nic_channel<<15) + offset);
     452
     453#if GIET_DEBUG_NIC
     454_printf("\n[GIET DEBUG NIC] Task %d of vspace %d in _sys_nic_start()"
     455        " get NIC chbuf paddr = %l\n",
     456        thread, vspace, nic_chbuf_pbase );
     457#endif
    413458
    414459    // compute the kernel chbuf descriptor physical address
    415     unsigned int ppn;
    416     unsigned int flags;
    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 );
     460    if ( is_rx ) vaddr = (unsigned int)( &_nic_rx_chbuf[nic_channel] );
     461    else         vaddr = (unsigned int)( &_nic_tx_chbuf[nic_channel] );
     462    ko    = _v2p_translate( (page_table_t*)ptab,
     463                            vaddr>>12,
     464                            &ppn,
     465                            &flags );
    422466    if ( ko )
    423467    {
    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 );
     468        _puts("\n[GIET ERROR] in _sys_nic_start() : kernel chbuf unmapped\n");
     469        return -1;
     470    }
     471    ker_chbuf_pbase = (((unsigned long long)ppn) << 12) | (vaddr & 0x00000FFF);
     472
     473#if GIET_DEBUG_NIC
     474_printf("\n[GIET DEBUG NIC] Task %d of vspace %d in _sys_nic_start()"
     475        " get kernel chbuf paddr = %l\n",
     476        thread, vspace, ker_chbuf_pbase );
     477#endif
     478
     479    // compute the container array physical address
     480    if ( is_rx ) vaddr = ((unsigned int)&_nic_rx_cont[0][0][nic_channel]);
     481    else         vaddr = ((unsigned int)&_nic_tx_cont[0][0][nic_channel]);
     482    ko = _v2p_translate( (page_table_t*)ptab,
     483                         vaddr>>12,
     484                         &ppn,
     485                         &flags );
     486    if ( ko )
     487    {
     488        _puts("\n[GIET ERROR] in _sys_nic_start() : containers array unmapped\n");
     489        return -1;
     490    }
     491    ker_cont_pbase = (((unsigned long long)ppn) << 12) | (vaddr & 0x00000FFF);
     492
     493#if GIET_DEBUG_NIC
     494_printf("\n[GIET DEBUG NIC] Task %d of vspace %d in _sys_nic_start()"
     495        " get kernel containers array paddr = %l\n",
     496        thread, vspace, ker_cont_pbase );
     497#endif
     498
     499    // initializes the kernel chbuf descriptor
     500    unsigned int index;
     501    if ( is_rx )
     502    {
     503        _lock_init( &_nic_rx_lock[nic_channel] );
     504        _nic_rx_chbuf[nic_channel].index = 0;
     505        for( index = 0 ; index < GIET_NIC_NBUFS ; index++ )
     506        {
     507            _nic_rx_chbuf[nic_channel].buffer[index] = ker_cont_pbase + (index<<12);
     508        }
     509    }
     510    else
     511    {
     512        _lock_init( &_nic_tx_lock[nic_channel] );
     513        _nic_tx_chbuf[nic_channel].index = 0;
     514        for( index = 0 ; index < GIET_NIC_NBUFS ; index++ )
     515        {
     516            _nic_tx_chbuf[nic_channel].buffer[index] = ker_cont_pbase + (index<<12);
     517        }
     518    }
     519
     520    // sync the kernel chbuf in L2 after write in L2
     521    _mmc_sync( ker_chbuf_pbase, sizeof( nic_chbuf_t ) );
     522
     523    // initializes CMA registers defining the source & destination chbufs
     524    if ( is_rx )               // NIC to kernel
     525    {
     526        _cma_set_register( cma_channel, CHBUF_SRC_DESC , (unsigned int)(nic_chbuf_pbase) );
     527        _cma_set_register( cma_channel, CHBUF_SRC_EXT  , (unsigned int)(nic_chbuf_pbase>>32) );
     528        _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, 2 );
     529        _cma_set_register( cma_channel, CHBUF_DST_DESC , (unsigned int)(ker_chbuf_pbase) );
     530        _cma_set_register( cma_channel, CHBUF_DST_EXT  , (unsigned int)(ker_chbuf_pbase>>32) );
     531        _cma_set_register( cma_channel, CHBUF_DST_NBUFS, GIET_NIC_NBUFS );
     532    }
     533    else                      // kernel to NIC
     534    {
     535        _cma_set_register( cma_channel, CHBUF_SRC_DESC , (unsigned int)(ker_chbuf_pbase) );
     536        _cma_set_register( cma_channel, CHBUF_SRC_EXT  , (unsigned int)(ker_chbuf_pbase>>32) );
     537        _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, GIET_NIC_NBUFS );
     538        _cma_set_register( cma_channel, CHBUF_DST_DESC , (unsigned int)(nic_chbuf_pbase) );
     539        _cma_set_register( cma_channel, CHBUF_DST_EXT  , (unsigned int)(nic_chbuf_pbase>>32) );
     540        _cma_set_register( cma_channel, CHBUF_DST_NBUFS, 2 );
     541    }
    440542
    441543    // start CMA transfer
     
    445547
    446548    // activates NIC channel
    447     _nic_channel_start( nic_channel, is_rx, mac4, mac2 );
    448     return 0;
    449 }
     549    _nic_channel_start( nic_channel, is_rx, GIET_NIC_MAC4, GIET_NIC_MAC2 );
     550
     551#if GIET_DEBUG_NIC
     552_printf("\n[GIET DEBUG NIC] Task %d of vspace %d exit _sys_nic_start()\n",
     553        thread, vspace );
     554#endif
     555
     556    return 0;
     557}  // end sys_nic_start()
    450558
    451559//////////////////////////////////////
    452560int _sys_nic_move( unsigned int is_rx,
     561                   unsigned int channel,
    453562                   void*        buffer )
    454563{
    455     unsigned long long user_paddr;    // user buffer physical address
    456     unsigned long long kernel_paddr;  // kernel buffer physical address
    457 
    458     // Compute user buffer physical address and check access rights
     564
     565#if GIET_DEBUG_NIC
     566unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
     567unsigned int vspace  = _get_context_slot( CTX_VSID_ID );
     568_printf("\n[GIET DEBUG NIC] Task %d of vspace %d enters _sys_nic_move()\n",
     569        thread, vspace );
     570#endif
     571
     572    unsigned long long user_buffer_paddr;    // user buffer physical address
     573    unsigned long long kernel_buffer_paddr;  // kernel buffer physical address
     574    unsigned long long kernel_chbuf_paddr;   // kernel chbuf physical address
     575    unsigned long long kernel_buffer_desc;   // kernel buffer descriptor
     576
     577    // The following variables are used for V2P translation
     578    unsigned int ptab = _get_context_slot( CTX_PTAB_ID );
    459579    unsigned int ppn;
    460580    unsigned int flags;
    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 );
     581    unsigned int vaddr;
     582    unsigned int ko;
     583
     584    // Compute user buffer physical address and check access rights
     585    vaddr = (unsigned int)buffer;
     586    ko = _v2p_translate( (page_table_t*)ptab,
     587                          vaddr>>12,
     588                          &ppn,
     589                          &flags );
    467590    if ( ko )
    468591    {
    469         _printf("\n[GIET ERROR] in _sys_nic_tx_move() : user buffer unmapped\n");
     592        _printf("\n[GIET ERROR] in _sys_nic_move() : user buffer unmapped\n");
    470593        return -1;
    471594    }
     
    475598        return -1;
    476599    }
    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 
     600    user_buffer_paddr = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF);
     601
     602#if GIET_DEBUG_NIC
     603_printf("\n[GIET DEBUG NIC] Task %d of vspace %d in _sys_nic_move()"
     604        " get user buffer paddr = %l\n",
     605        thread, vspace, user_buffer_paddr );
     606#endif
     607
     608    // check NIC channel index
    484609    if ( channel >= NB_NIC_CHANNELS )
    485610    {
     
    488613    }
    489614
     615    // get kernel chbuf and lock addresses
    490616    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;
     617    spin_lock_t* lock;
     618
     619    if ( is_rx )
     620    {
     621        chbuf = &_nic_rx_chbuf[channel];
     622        lock  = &_nic_rx_lock[channel];
     623    }
     624    else
     625    {
     626        chbuf = &_nic_tx_chbuf[channel];
     627        lock  = &_nic_tx_lock[channel];
     628    }
     629
     630    // compute kernel chbuf physical address (required for sync)
     631    vaddr = (unsigned int)chbuf;
     632    ko = _v2p_translate( (page_table_t*)ptab,
     633                          vaddr>>12,
     634                          &ppn,
     635                          &flags );
     636    if ( ko )
     637    {
     638        _printf("\n[GIET ERROR] in _sys_nic_move() : kernel chbuf unmapped\n");
     639        return -1;
     640    }
     641    kernel_chbuf_paddr = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF);
     642
     643    // get the lock protecting the chbuf
     644    _lock_acquire( lock );
     645
     646    // polling on the kernel chbuf status
    496647    unsigned int full;
    497648    unsigned int ok      = 0;
    498649    unsigned int index   = chbuf->index;
    499     unsigned int timeout = GIET_NIC_CHBUF_TIMEOUT;
     650    unsigned int timeout = GIET_NIC_TIMEOUT;
    500651    while( ok == 0 )
    501652    {
    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         }
     653        // inval kernel chbuf in L2 before read in L2
     654        _mmc_inval( kernel_chbuf_paddr, sizeof( nic_chbuf_t ) );
     655
     656        // get kernel buffer descriptor
     657        kernel_buffer_desc = chbuf->buffer[index];
     658
     659#if GIET_DEBUG_NIC
     660_printf("\n[GIET DEBUG NIC] Task %d of vspace %d in _sys_nic_move()"
     661        " poll kernel container descriptor = %l\n",
     662        thread, vspace, kernel_buffer_desc );
     663#endif
     664
     665        full  =  kernel_buffer_desc >> 63;
     666        if ( (is_rx && full) || ((is_rx == 0) && (full == 0)) )  ok = 1;
     667        else                                                     timeout--;
     668
    512669        if ( timeout == 0 )
    513670        {
    514             _printf("\n[GIET_ERROR] in _sys_ni_move() : timeout\n");
     671            _printf("\n[GIET_ERROR] in _sys_nic_move() : timeout\n");
    515672            return -1;
    516673        }
    517674    }
    518     kernel_paddr = desc & 0x0000FFFFFFFFFFFFULL;
     675
     676    // compute kernel buffer physical address
     677    kernel_buffer_paddr = kernel_buffer_desc & 0x0000FFFFFFFFFFFFULL;
    519678   
    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;
     679    // move one container, using a physical_memcpy
     680    // We must maintain L2/L3 cache coherence
     681    if ( is_rx )
     682    {
     683        // inval kernel buffer in L2 before read in L2
     684        _mmc_inval( kernel_buffer_paddr, GIET_NIC_BUFSIZE );
     685
     686        // transfer data from kernel buffer to user buffer
     687        _physical_memcpy( user_buffer_paddr,
     688                          kernel_buffer_paddr,
     689                          GIET_NIC_BUFSIZE );
     690
     691    }
     692    else
     693    {
     694        // transfer data from user buffer to kernel buffer
     695        _physical_memcpy( kernel_buffer_paddr,
     696                          user_buffer_paddr,
     697                          GIET_NIC_BUFSIZE );
     698
     699        // sync kernel buffer in L2 after write in L2
     700        _mmc_sync( kernel_buffer_paddr, GIET_NIC_BUFSIZE );
     701    }
     702
     703    // update kernel chbuf status and index
     704    if ( is_rx ) chbuf->buffer[index] = kernel_buffer_paddr & 0x0000FFFFFFFFFFFFULL;
     705    else         chbuf->buffer[index] = kernel_buffer_paddr | 0x8000000000000000ULL;
     706
     707    if ( index == (GIET_NIC_NBUFS - 1) ) chbuf->index = 0;
     708    else                                 chbuf->index = index + 1;
     709
     710    // sync kernel chbuf in L2 after write in L2
     711    _mmc_sync( kernel_chbuf_paddr, sizeof( nic_chbuf_t ) );
     712
     713    // release the lock protecting the chbuf
     714    _lock_release( lock );
     715   
     716#if GIET_DEBUG_NIC
     717_printf("\n[GIET DEBUG NIC] Task %d of vspace %d exit _sys_nic_move()\n",
     718        thread, vspace );
     719#endif
    534720
    535721    return 0;
     
    571757    _cma_channel_stop( cma_channel );
    572758
     759    return 0;
     760}
     761
     762////////////////////////////////////////
     763int _sys_nic_clear( unsigned int is_rx )
     764{
     765    unsigned int nic_channel;
     766
     767    // get NIC channel
     768    if ( is_rx )  nic_channel = _get_context_slot( CTX_NIC_RX_ID );
     769    else          nic_channel = _get_context_slot( CTX_NIC_TX_ID );
     770
     771    if ( nic_channel >= NB_NIC_CHANNELS )
     772    {
     773        _printf("\n[GIET_ERROR] in _sys_nic_start(): NIC channel not allocated\n");
     774        return -1;
     775    }
     776
     777    if ( is_rx )
     778    {
     779        _nic_set_global_register( NIC_G_NPKT_RX_G2S_RECEIVED       , 0 );
     780        _nic_set_global_register( NIC_G_NPKT_RX_DES_TOO_SMALL      , 0 );
     781        _nic_set_global_register( NIC_G_NPKT_RX_DES_TOO_BIG        , 0 );
     782        _nic_set_global_register( NIC_G_NPKT_RX_DES_MFIFO_FULL     , 0 );
     783        _nic_set_global_register( NIC_G_NPKT_RX_DES_CRC_FAIL       , 0 );
     784        _nic_set_global_register( NIC_G_NPKT_RX_DISPATCH_RECEIVED  , 0 );
     785        _nic_set_global_register( NIC_G_NPKT_RX_DISPATCH_BROADCAST , 0 );
     786        _nic_set_global_register( NIC_G_NPKT_RX_DISPATCH_DST_FAIL  , 0 );
     787        _nic_set_global_register( NIC_G_NPKT_RX_DISPATCH_CH_FULL   , 0 );
     788    }
     789    else
     790    {
     791        _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_RECEIVED  , 0 );
     792        _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_TRANSMIT  , 0 );
     793        _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_TOO_BIG   , 0 );
     794        _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_TOO_SMALL , 0 );
     795        _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_SRC_FAIL  , 0 );
     796        _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_BYPASS    , 0 );
     797        _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_BROADCAST , 0 );
     798    }
     799    return 0;
     800}
     801
     802////////////////////////////////////////
     803int _sys_nic_stats( unsigned int is_rx )
     804{
     805    unsigned int nic_channel;
     806
     807    // get NIC channel
     808    if ( is_rx )  nic_channel = _get_context_slot( CTX_NIC_RX_ID );
     809    else          nic_channel = _get_context_slot( CTX_NIC_TX_ID );
     810
     811    if ( nic_channel >= NB_NIC_CHANNELS )
     812    {
     813        _printf("\n[GIET_ERROR] in _sys_nic_start(): NIC channel not allocated\n");
     814        return -1;
     815    }
     816
     817    if ( is_rx )
     818    {
     819        unsigned int received   = _nic_get_global_register( NIC_G_NPKT_RX_G2S_RECEIVED       );
     820        unsigned int too_small  = _nic_get_global_register( NIC_G_NPKT_RX_DES_TOO_SMALL      );
     821        unsigned int too_big    = _nic_get_global_register( NIC_G_NPKT_RX_DES_TOO_BIG        );
     822        unsigned int fifo_full  = _nic_get_global_register( NIC_G_NPKT_RX_DES_MFIFO_FULL     );
     823        unsigned int crc_fail   = _nic_get_global_register( NIC_G_NPKT_RX_DES_CRC_FAIL       );
     824        unsigned int transmit   = _nic_get_global_register( NIC_G_NPKT_RX_DISPATCH_RECEIVED  );
     825        unsigned int broadcast  = _nic_get_global_register( NIC_G_NPKT_RX_DISPATCH_BROADCAST );
     826        unsigned int dst_fail   = _nic_get_global_register( NIC_G_NPKT_RX_DISPATCH_DST_FAIL  );
     827        unsigned int ch_full    = _nic_get_global_register( NIC_G_NPKT_RX_DISPATCH_CH_FULL   );
     828
     829        _printf("\n### Network Controller RX Statistics ###\n"
     830                "- packets received : %d\n"
     831                "- packets transmit : %d\n"
     832                "- too small        : %d\n"
     833                "- too big          : %d\n"
     834                "- fifo full        : %d\n"
     835                "- crc fail         : %d\n"
     836                "- dst mac fail     : %d\n"
     837                "- channel full     : %d\n"
     838                "- broadcast        : %d\n",
     839                received,
     840                transmit,
     841                too_small,
     842                too_big,
     843                fifo_full,
     844                crc_fail,
     845                dst_fail,
     846                ch_full,
     847                broadcast );
     848    }
     849    else
     850    {
     851        unsigned int received   = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_RECEIVED  );
     852        unsigned int transmit   = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_TRANSMIT  );
     853        unsigned int too_big    = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_TOO_BIG   );
     854        unsigned int too_small  = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_TOO_SMALL );
     855        unsigned int src_fail   = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_SRC_FAIL  );
     856        unsigned int bypass     = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_BYPASS    );
     857        unsigned int broadcast  = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_BROADCAST );
     858
     859        _printf("\n### Network Controller TX Statistics ###\n"
     860                "- packets received : %d\n"
     861                "- packets transmit : %d\n"
     862                "- too small        : %d\n"
     863                "- too big          : %d\n"
     864                "- src mac fail     : %d\n"
     865                "- bypass           : %d\n"
     866                "- broadcast        : %d\n",
     867                received,
     868                transmit,
     869                too_big,
     870                too_small,
     871                src_fail,
     872                bypass,
     873                broadcast );
     874    }
    573875    return 0;
    574876}
     
    612914{
    613915   // get a new CMA channel index
    614     unsigned int channel = _atomic_increment( &_cma_channel_allocator );
     916    unsigned int channel = _atomic_increment( &_cma_channel_allocator, 1 );
    615917    unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
    616918    unsigned int vspace  = _get_context_slot( CTX_VSID_ID );
  • soft/giet_vm/giet_kernel/sys_handler.h

    r449 r459  
    1313#define _SYS_HANDLER_H
    1414
    15 #include <mapping_info.h>
    16 #include <giet_config.h>
     15#include "giet_config.h"
     16#include "locks.h"
     17
     18#if !defined ( GIET_NIC_NBUFS )
     19# error: You must define GIET_NIC_NBUFS in the giet_config.h file
     20#endif
     21
     22#if !defined ( GIET_NIC_NFAKE )
     23# error: You must define GIET_NIC_NFAKE in the giet_config.h file
     24#endif
     25
     26#if !defined ( GIET_NIC_BUFSIZE )
     27# error: You must define GIET_NIC_BUFSIZE in the giet_config.h file
     28#endif
     29
     30#if !defined ( GIET_NIC_TIMEOUT )
     31# error: You must define GIET_NIC_TIMEOUT in the giet_config.h file
     32#endif
     33
     34#if !defined ( GIET_NIC_MAC4 )
     35# error: You must define GIET_NIC_MAC4 in the giet_config.h file
     36#endif
     37
     38#if !defined ( GIET_NIC_MAC2 )
     39# error: You must define GIET_NIC_MAC2 in the giet_config.h file
     40#endif
     41
     42#if ( (GIET_NIC_NBUFS + GIET_NIC_NFAKE) % 8 )
     43#error: GIET_NIC_NBUFS + GIET_NIC_NFAKE must be multiple of 8 for alignment
     44#endif
    1745
    1846///////////////////////////////////////////////////////////////////////////////////
     
    2351
    2452///////////////////////////////////////////////////////////////////////////////////
    25 // This structure is used by the vci_chbuf_dma component to transfer a stream
     53// This structure is used by the CMA component to move a stream
    2654// of images from two buffers in user space to the frame buffer in kernel space.
    27 // It contains two chbuf descriptors
     55// it must be 64 bytes aligned.
     56// It contains two chbuf arrays:
    2857// - The SRC chbuf contains two buffers (buf0 & buf1), that can be in user space.
    2958// - The DST cbuf contains one single buffer (fbf), that is the frame buffer.
     59// - The length field define the buffer size (bytes)
    3060///////////////////////////////////////////////////////////////////////////////////
    3161
    3262typedef struct fbf_chbuf_s
    3363{
    34     unsigned long long  buf0;     // physical address + status for user buffer 0
    35     unsigned long long  buf1;     // physical address + status for user buffer 1
    36     unsigned long long  fbf;      // physical address + status for user buffer 0
    37     unsigned int        length;   // buffer length (bytes)
    38     unsigned int        padding;  // 8 bytes alignment
     64    unsigned long long  buf0;        // physical address + status for user buffer 0
     65    unsigned long long  buf1;        // physical address + status for user buffer 1
     66    unsigned long long  fbf;         // physical address + status for user buffer 0
     67    unsigned int        length;      // buffer length (bytes)
     68    unsigned int        padding[9];  // 64 bytes alignment
    3969} fbf_chbuf_t;   
    4070
    4171//////////////////////////////////////////////////////////////////////////////////
    42 // This structure define the generic chained buffer used by the vci_chbuf_dma
    43 // component to move a stream of containers to or from the vci_multi_nic component.
     72// This structure is used by the CMA component to move a stream
     73// of packet containers between the NIC component an a chbuf containing
     74// a variable number of buffers in kernel space.
    4475// The same structure is used for both TX or RX transfers.
     76// It must be 64 bytes aligned.
    4577// The single buffer size and the number of buffers must be defined by the
    46 // GIET_NIC_CHBUF_SIZE and GIET_NIC_CHBUF_NBUFS parameters in giet_config.h.
    47 // - The buffer array is the chbuf descriptor, shared by the vci_chbuf_dma,
    48 //   and by the kernel.
    49 // - The index field is only used by the kernel. It define the currently pointed
     78// GIET_NIC_BUFSIZE and GIET_NIC_NBUFS parameters in giet_config.h.
     79// - The buffer array implements the chbuf, and is concurently accessed
     80//   by the CMA component and by the kernel code.
     81// - The lock must be taken by the kernel code, because several user tasks
     82//   can concurently try to consume buffers in the chbuf.
     83// - The index is only used by the kernel, and define the currently pointed
    5084//   buffer for read (RX transfer) or write (TX transfer).
    5185//////////////////////////////////////////////////////////////////////////////////
     
    5387typedef struct nic_chbuf_s
    5488{
    55     unsigned long long  buffer[GIET_NIC_CHBUF_NBUFS];      // chbuf descriptor
    56     unsigned int        index;                             // current buffer index
    57     unsigned int        padding;                           // 8 bytes alignment
     89    unsigned long long  buffer[GIET_NIC_NBUFS];  // Kernel CHBUF
     90    unsigned long long  unused[GIET_NIC_NFAKE];  // padding for 64 bytes alignment
     91    unsigned int        index;                   // current buffer index
     92    unsigned int        padding[15];             // padding for 64 bytes alignment
    5893} nic_chbuf_t;
    5994
     
    95130int _sys_nic_alloc( unsigned int is_rx );
    96131
    97 int _sys_nic_start( unsigned int is_rx,
    98                     unsigned int mac4,
    99                     unsigned int mac2 );
     132int _sys_nic_start( unsigned int is_rx );
    100133
    101134int _sys_nic_move( unsigned int is_rx,
     135                   unsigned int nic_channel,
    102136                   void*        buffer );
    103137
    104138int _sys_nic_stop( unsigned int is_rx );
     139
     140int _sys_nic_clear( unsigned int is_rx );
     141
     142int _sys_nic_stats( unsigned int is_rx );
    105143
    106144//////////////////////////////////////////////////////////////////////////////
Note: See TracChangeset for help on using the changeset viewer.