Ignore:
Timestamp:
Nov 3, 2014, 10:53:00 AM (10 years ago)
Author:
alain
Message:

Introducing dynamic allocation of peripheral channel(TTY, NIC, TIM, CMA)
Removint the ICU driver : ICU component not supported anymore.
Removing the FBF driver.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/giet_drivers/nic_driver.c

    r333 r437  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    7 // The nic_driver.c and nic_driver.h files are part ot the GIET-VM nano-kernel.
    8 // This driver supports the vci_multi_nic component.
    9 //
    10 // It can exist only one network controller in the architecture, but this
    11 // component supports several channels.
    12 //
    13 // It can be accessed directly by software with memcpy(),
    14 // or it can be accessed through the vci_chbuf_dma component:
    15 // 
    16 // The '_nic_sync_write' and '_nic_sync_read' functions use a memcpy strategy to
    17 // implement the transfer between a data buffer (user space) and the NIC
    18 // buffer (kernel space). They are blocking until completion of the transfer.
    19 //
    20 // The _nic_cma_*_init() and _nic_cma_stop() functions use the VciChbufDma component
    21 // to transfer a flow of packets from the NIC RX hard chbuf (two containers)
    22 // to an user RX chbuf (two containers), and to transfer another flow of packets
    23 // from an user TX chbuf (two containers) to the NIC TX chbuf (two containers).
    24 // One NIC channel and two CMA channels must be allocated to the task
    25 // in the mapping_info data structure.
    26 //
    27 // The SEG_NIC_BASE address must be defined in the hard_config.h file.
    28 //////////////////////////////////////////////////////////////////////////////////
    297
    308#include <giet_config.h>
    319#include <nic_driver.h>
     10#include <cma_driver.h>
    3211#include <utils.h>
     12#include <ctx_handler.h>
     13#include <vmem.h>
    3314
    3415#if !defined(GIET_USE_IOMMU)
     
    4425#endif
    4526
     27#if !defined(X_IO)
     28# error: You must define X_IO in the hard_config.h file
     29#endif
     30
     31#if !defined(Y_IO)
     32# error: You must define Y_IO in the hard_config.h file
     33#endif
     34
    4635#if ( NB_NIC_CHANNELS > 8 )
    4736# error: NB_NIC_CHANNELS cannot be larger than 8
     
    6049#endif
    6150
     51#if !defined( GIET_CHBUF_NBUFS )
     52# error: You must define GIET_CHBUF_NBUFS in the giet_config.h file
     53#endif
     54
    6255#define in_unckdata __attribute__((section (".unckdata")))
    6356
    6457///////////////////////////////////////////////////////////////////////////////
    65 // This low_level function returns the value contained in register (index).
    66 ///////////////////////////////////////////////////////////////////////////////
    67 unsigned int _nic_get_register( unsigned int channel,
    68                                 unsigned int index )
     58// This low_level function returns the value contained in a channel register.
     59///////////////////////////////////////////////////////////////////////////////
     60unsigned int _nic_get_channel_register( unsigned int channel,
     61                                        unsigned int index )
    6962{
    7063    unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE +
     
    7467
    7568///////////////////////////////////////////////////////////////////////////////
    76 // This low-level function set a new value in register (index).
    77 ///////////////////////////////////////////////////////////////////////////////
    78 void _nic_set_register( unsigned int channel,
    79                         unsigned int index,
    80                         unsigned int value )
     69// This low-level function set a new value in a channel register.
     70///////////////////////////////////////////////////////////////////////////////
     71void _nic_set_channel_register( unsigned int channel,
     72                                unsigned int index,
     73                                unsigned int value )
    8174{
    8275    unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE +
     
    8578}
    8679
    87 //////////////////////////////////////////////////////////////////////////////////
    88 // Transfer data from an memory buffer to the NIC device using a memcpy.
    89 // - buffer : base address of the memory buffer.
    90 // - length : number of bytes to be transfered.
    91 //////////////////////////////////////////////////////////////////////////////////
    92 unsigned int _nic_sync_write( const void*    buffer,
    93                               unsigned int   length )
    94 {
    95     _printf("[GIET ERROR] _nic_sync_write function not implemented / cycle %d\n",
    96             _get_proctime() );
    97     _exit();
    98 
    99     return 0;
    100 }
    101 //////////////////////////////////////////////////////////////////////////////////
    102 // Transfer data from the NIC device to a memory buffer using a memcpy.
    103 // - buffer : base address of the memory buffer.
    104 // - length : number of bytes to be transfered.
    105 //////////////////////////////////////////////////////////////////////////////////
    106 unsigned int _nic_sync_read( const void*    buffer,
    107                              unsigned int   length )
    108 {
    109     _printf("[GIET ERROR] _nic_sync_read function not implemented / cycle %d\n",
    110             _get_proctime() );
    111     _exit();
    112 
    113     return 0;
    114 }
    115 //////////////////////////////////////////////////////////////////////////////////
    116 // Returns 0 if success, > 0 if error.
    117 //////////////////////////////////////////////////////////////////////////////////
    118 unsigned int _nic_cma_start( )
    119 {
    120     _printf("[GIET ERROR] _nic_cma_start() not implemented / cycle %d\n",
    121             _get_proctime() );
    122     _exit();
    123 
    124     return 0;
    125 }
    126 //////////////////////////////////////////////////////////////////////////////////
    127 // Returns 0 if success, > 0 if error.
    128 //////////////////////////////////////////////////////////////////////////////////
    129 unsigned int _nic_cma_stop()
    130 {
    131     _printf("[GIET ERROR] _nic_cma_stop() not implemented / cycle %d\n",
    132             _get_proctime() );
    133     _exit();
    134 
    135     return 0;
    136 }
    137 
    138 //////////////////////////////////////////////////////////////////////////////////
    139 // This ISR handles IRQx from a NIC RX channeL
    140 //////////////////////////////////////////////////////////////////////////////////
     80///////////////////////////////////////////////////////////////////////////////
     81// This low_level function returns the value contained in a global register.
     82///////////////////////////////////////////////////////////////////////////////
     83unsigned int _nic_get_global_register( unsigned int index )
     84{
     85    unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE +
     86                           NIC_CHANNEL_SPAN * NB_NIC_CHANNELS + index;
     87    return _io_extended_read( vaddr );
     88}
     89
     90///////////////////////////////////////////////////////////////////////////////
     91// This low-level function set a new value in a global register.
     92///////////////////////////////////////////////////////////////////////////////
     93void _nic_set_global_register( unsigned int index,
     94                               unsigned int value )
     95{
     96    unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE +
     97                           NIC_CHANNEL_SPAN * NB_NIC_CHANNELS + index;
     98    _io_extended_write( vaddr, value );
     99}
     100
     101////////////////////////////////////////////
     102int _nic_global_init( unsigned int channels,
     103                      unsigned int vis,
     104                      unsigned int bc_enable,
     105                      unsigned int bypass_enable )
     106{
     107    _nic_set_global_register( NIC_G_VIS          , vis );
     108    _nic_set_global_register( NIC_G_NB_CHAN      , channels );
     109    _nic_set_global_register( NIC_G_BC_ENABLE    , bc_enable );
     110    _nic_set_global_register( NIC_G_BYPASS_ENABLE, bypass_enable );
     111    _nic_set_global_register( NIC_G_ON           , 1 );
     112
     113    return 0;
     114}
     115
     116////////////////////////////////////////////
     117int _nic_channel_init( unsigned int index,
     118                       unsigned int mac4,
     119                       unsigned int mac2 )
     120{
     121    unsigned int base     = SEG_NIC_BASE;
     122    unsigned int extend   = (X_IO << Y_WIDTH) + Y_IO;
     123
     124    _nic_set_channel_register( index, NIC_RX_DESC_LO_0 + 4096, base );
     125    _nic_set_channel_register( index, NIC_RX_DESC_LO_1 + 4096, base + 0x1000 );
     126    _nic_set_channel_register( index, NIC_TX_DESC_LO_0 + 4096, base + 0x2000 );
     127    _nic_set_channel_register( index, NIC_TX_DESC_LO_1 + 4096, base + 0x3000 );
     128
     129    _nic_set_channel_register( index, NIC_RX_DESC_HI_0       , extend );
     130    _nic_set_channel_register( index, NIC_RX_DESC_HI_1       , extend );
     131    _nic_set_channel_register( index, NIC_TX_DESC_HI_0       , extend );
     132    _nic_set_channel_register( index, NIC_TX_DESC_HI_1       , extend );
     133
     134    _nic_set_channel_register( index, NIC_MAC_4              , mac4 );
     135    _nic_set_channel_register( index, NIC_MAC_2              , mac2 );
     136   
     137    _nic_set_channel_register( index, NIC_RX_RUN             , 1 );
     138    _nic_set_channel_register( index, NIC_TX_RUN             , 1 );
     139
     140    return 0;
     141}
     142
     143/////////////////////////////////////////////////////////////////////////////////////
     144//             Synchronous access functions
     145/////////////////////////////////////////////////////////////////////////////////////
     146
     147///////////////////////////////////////////////
     148int _nic_sync_send( unsigned int        channel,
     149                    unsigned long long  user_paddr )
     150{
     151    unsigned long long nic_paddr;   // nic buffer physical address
     152    unsigned int       done = 0;
     153    unsigned int       lsb;
     154    unsigned int       msb;
     155
     156    if ( channel >= NB_NIC_CHANNELS )
     157    {
     158        _puts("[GIET ERROR] in _timer_sync_send()\n");
     159        return -1;
     160    }
     161
     162    // poll the NIC buffers
     163    while ( done == 0 )
     164    {
     165        // test availability of NIC TX buffer 0
     166        lsb  = _nic_get_channel_register( channel, NIC_TX_DESC_LO_0 );
     167        msb  = _nic_get_channel_register( channel, NIC_TX_DESC_HI_0 );
     168        if ( (msb & 0x80000000) == 0 )
     169        {
     170            msb  = msb & 0x0000FFFF;
     171            done = 1;
     172            continue;
     173        }
     174
     175        // test availability of NIC TX buffer 1
     176        lsb  = _nic_get_channel_register( channel, NIC_TX_DESC_LO_1 );
     177        msb  = _nic_get_channel_register( channel, NIC_TX_DESC_HI_1 );
     178        if ( (msb & 0x80000000) == 0 )
     179        {
     180            msb  = msb & 0x0000FFFF;
     181            done = 1;
     182            continue;
     183        }
     184
     185        // random delay (average value: 380 cycle)
     186        _random_wait( 8 );
     187    }
     188
     189    // make the transfer
     190    nic_paddr = (unsigned long long)lsb + (((unsigned long long)msb) << 32);
     191
     192    _physical_memcpy( nic_paddr , user_paddr, 4096 );
     193
     194    return 0;
     195}
     196
     197///////////////////////////////////////////////////
     198int _nic_sync_receive( unsigned int        channel,
     199                       unsigned long long  user_paddr )
     200{
     201    unsigned long long nic_paddr;   // nic  buffer physical address
     202    unsigned int       done = 0;
     203    unsigned int       lsb;
     204    unsigned int       msb;
     205
     206    if ( channel >= NB_NIC_CHANNELS )
     207    {
     208        _puts("[GIET ERROR] in _timer_sync_receive()\n");
     209        return -1;
     210    }
     211
     212    // polling the NIC buffers
     213    while ( done == 0 )
     214    {
     215        // test availability of NIC RX buffer 0
     216        lsb  = _nic_get_channel_register( channel, NIC_RX_DESC_LO_0 );
     217        msb  = _nic_get_channel_register( channel, NIC_RX_DESC_HI_0 );
     218        if ( (msb & 0x80000000) == 1 )
     219        {
     220            msb  = msb & 0x0000FFFF;
     221            done = 1;
     222            continue;
     223        }
     224
     225        // test availability of NIC RX buffer 1
     226        lsb  = _nic_get_channel_register( channel, NIC_RX_DESC_LO_1 );
     227        msb  = _nic_get_channel_register( channel, NIC_RX_DESC_HI_1 );
     228        if ( (msb & 0x80000000) == 1 )
     229        {
     230            msb  = msb & 0x0000FFFF;
     231            done = 1;
     232            continue;
     233        }
     234
     235        // random delay (average value: 380 cycle)
     236        _random_wait( 8 );
     237    }
     238
     239    // make the transfer
     240    nic_paddr = (unsigned long long)lsb + (((unsigned long long)msb) << 32);
     241
     242    _physical_memcpy( user_paddr, nic_paddr , 4096 );
     243
     244    return 0;
     245}
     246
     247/////////////////////////////////////////////////////////////////////////////////////
     248//             CMA access functions
     249/////////////////////////////////////////////////////////////////////////////////////
     250
     251//////////////////////////////////////////////////////////////
     252int _nic_cma_receive( unsigned int  nic_channel,
     253                      unsigned int  cma_channel,
     254                      nic_chbuf_t*  kernel_chbuf )
     255                             
     256{
     257    unsigned int nic_chbuf_lsb;     // 32 LSB bits of the NIC chbuf physical address
     258    unsigned int nic_chbuf_msb;     // 16 MSB bits of the NIC chbuf physical address
     259    unsigned int mem_chbuf_lsb;     // 32 LSB bits of the kernel chbuf physical address
     260    unsigned int mem_chbuf_msb;     // 16 MSB bits of the kernel chbuf physical address
     261
     262    unsigned int ppn;
     263    unsigned int flags;
     264
     265    // checking parameters
     266    if ( nic_channel >= NB_NIC_CHANNELS )
     267    {
     268        _puts("[GIET ERROR] in _nic_cma_start_receive() : nic_channel index too large\n");
     269        return -1;
     270    }
     271    if ( cma_channel >= NB_CMA_CHANNELS )
     272    {
     273        _puts("[GIET ERROR] in _nic_cma_start_receive() : cma_channel index too large\n");
     274        return -1;
     275    }
     276
     277    // get the NIC_RX chbuf descriptor physical address
     278    nic_chbuf_lsb = SEG_NIC_BASE + (nic_channel * NIC_CHANNEL_SPAN) + 0x1000;
     279    nic_chbuf_msb = (X_IO << Y_WIDTH) + Y_IO;
     280
     281    // compute the kernel chbuf physical address
     282    unsigned int ptab  = _get_context_slot(CTX_PTAB_ID);
     283    unsigned int vaddr = (unsigned int)kernel_chbuf;
     284    unsigned int ko    = _v2p_translate( (page_table_t*)ptab,
     285                                          vaddr,
     286                                          &ppn,
     287                                          &flags );
     288    if ( ko )
     289    {
     290        _puts("\n[GIET ERROR] in _nic_cma_start_receive() : kernel buffer unmapped\n");
     291        return -1;
     292    }
     293
     294    mem_chbuf_lsb = (ppn << 12) | (vaddr & 0x00000FFF);
     295    mem_chbuf_msb = ppn >> 20;
     296
     297    // initializes CMA registers defining the source chbuf (NIC_RX)
     298    _cma_set_register( cma_channel, CHBUF_SRC_DESC , nic_chbuf_lsb );
     299    _cma_set_register( cma_channel, CHBUF_DST_EXT  , nic_chbuf_msb );
     300    _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, 2 );
     301
     302    // initializes CMA registers defining the destination chbuf (kernel memory)
     303    _cma_set_register( cma_channel, CHBUF_DST_DESC , mem_chbuf_lsb );
     304    _cma_set_register( cma_channel, CHBUF_DST_EXT  , mem_chbuf_msb );
     305    _cma_set_register( cma_channel, CHBUF_DST_NBUFS, GIET_CHBUF_NBUFS );
     306
     307    // set buffer size, polling period, and start
     308    _cma_set_register( cma_channel, CHBUF_BUF_SIZE , 4096 );
     309    _cma_set_register( cma_channel, CHBUF_PERIOD   , 300 );
     310    _cma_set_register( cma_channel, CHBUF_RUN      , 1 );
     311
     312    return 0;
     313}
     314
     315//////////////////////////////////////////////////////////
     316int _nic_cma_send( unsigned int  nic_channel,
     317                   unsigned int  cma_channel,
     318                   nic_chbuf_t*  kernel_chbuf )
     319{
     320    unsigned int nic_chbuf_lsb;     // 32 LSB bits of the NIC chbuf physical address
     321    unsigned int nic_chbuf_msb;     // 16 MSB bits of the NIC chbuf physical address
     322    unsigned int mem_chbuf_lsb;     // 32 LSB bits of the kernel chbuf physical address
     323    unsigned int mem_chbuf_msb;     // 16 MSB bits of the kernel chbuf physical address
     324
     325    unsigned int ppn;
     326    unsigned int flags;
     327
     328    // checking parameters
     329    if ( nic_channel >= NB_NIC_CHANNELS )
     330    {
     331        _puts("[GIET ERROR] in _nic_cma_start_send() : nic_channel index too large\n");
     332        return -1;
     333    }
     334    if ( cma_channel >= NB_CMA_CHANNELS )
     335    {
     336        _puts("[GIET ERROR] in _nic_cma_start_send() : cma_channel index too large\n");
     337        return -1;
     338    }
     339
     340    // get the NIC_TX chbuf descriptor physical address
     341    nic_chbuf_lsb = SEG_NIC_BASE + (nic_channel * NIC_CHANNEL_SPAN) + 0x1010;
     342    nic_chbuf_msb = (X_IO << Y_WIDTH) + Y_IO;
     343
     344    // compute the kernel chbuf physical address
     345    unsigned int ptab  = _get_context_slot(CTX_PTAB_ID);
     346    unsigned int vaddr = (unsigned int)kernel_chbuf;
     347    unsigned int ko    = _v2p_translate( (page_table_t*)ptab,
     348                                          vaddr,
     349                                          &ppn,
     350                                          &flags );
     351    if ( ko )
     352    {
     353        _puts("\n[GIET ERROR] in _nic_cma_start_send() : kernel buffer unmapped\n");
     354        return -1;
     355    }
     356
     357    mem_chbuf_lsb = (ppn << 12) | (vaddr & 0x00000FFF);
     358    mem_chbuf_msb = ppn >> 20;
     359
     360    // initializes CMA registers defining the source chbuf (kernel memory)
     361    _cma_set_register( cma_channel, CHBUF_SRC_DESC , mem_chbuf_lsb );
     362    _cma_set_register( cma_channel, CHBUF_DST_EXT  , mem_chbuf_msb );
     363    _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, GIET_CHBUF_NBUFS );
     364
     365    // initializes CMA registers defining the destination chbuf (NIC_TX)
     366    _cma_set_register( cma_channel, CHBUF_DST_DESC , nic_chbuf_lsb );
     367    _cma_set_register( cma_channel, CHBUF_DST_EXT  , nic_chbuf_msb );
     368    _cma_set_register( cma_channel, CHBUF_DST_NBUFS, 2 );
     369
     370    // set buffer size, polling period, and start
     371    _cma_set_register( cma_channel, CHBUF_BUF_SIZE , 4096 );
     372    _cma_set_register( cma_channel, CHBUF_PERIOD   , 300 );
     373    _cma_set_register( cma_channel, CHBUF_RUN      , 1 );
     374
     375    return 0;
     376}
     377
     378////////////////////////////////////////////////////////////////////////////////////////////
     379//            Interrupt Service Routines
     380////////////////////////////////////////////////////////////////////////////////////////////
     381
     382////////////////////////////////////////
    141383void _nic_rx_isr( unsigned int irq_type,
    142384                  unsigned int irq_id,
    143385                  unsigned int channel )
    144386{
    145     _printf("[GIET ERROR] _nic_rx_isr() not implemented / cycle %d\n",
    146             _get_proctime() );
    147     _exit();
    148 }
    149 
    150 //////////////////////////////////////////////////////////////////////////////////
    151 // This ISR handles IRQx from a NIC RX channeL
    152 //////////////////////////////////////////////////////////////////////////////////
     387    _puts("[NIC WARNING] RX buffers are full for NIC channel ");
     388    _putd( channel );
     389    _puts("\n");
     390}
     391
     392////////////////////////////////////////
    153393void _nic_tx_isr( unsigned int irq_type,
    154394                  unsigned int irq_id,
    155395                  unsigned int channel )
    156396{
    157     _printf("[GIET ERROR] _nic_tx_isr() not implemented / cycle %d\n",
    158             _get_proctime() );
    159     _exit();
     397    _puts("[NIC WARNING] TX buffers are full for NIC channel ");
     398    _putd( channel );
     399    _puts("\n");
    160400}
    161401
Note: See TracChangeset for help on using the changeset viewer.