Ignore:
Timestamp:
Jun 27, 2017, 2:07:55 PM (5 years ago)
Author:
max@…
Message:

empty out the x86 drivers

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/hal/x86_64/drivers/soclib_nic.c

    r75 r76  
    3434#include <soclib_nic.h>
    3535
    36 ///////////////////////////////////////
    3736void soclib_nic_init( chdev_t * chdev )
    3837{
    39     uint32_t    i;
    40     kmem_req_t  req;
    41    
    42     // get hardware device cluster and local pointer
    43     cxy_t      nic_cxy  = GET_CXY( chdev->base );
    44     uint32_t * nic_ptr  = (uint32_t *)GET_PTR( chdev->base );
    4538
    46     // initialize Soclib NIC global registers
    47     hal_remote_sw( XPTR( nic_cxy , &nic_ptr + NIC_G_BC_ENABLE ) , 0 );
    48     hal_remote_sw( XPTR( nic_cxy , &nic_ptr + NIC_G_RUN       ) , 0 );
     39}
    4940
    50     // allocate memory for chbuf descriptor (one page)
    51     assert( (sizeof(nic_chbuf_t) <= CONFIG_PPM_PAGE_SIZE ) , __FUNCTION__ ,
    52             "chbuf descriptor exceeds one page" );
    53 
    54     req.type   = KMEM_PAGE;
    55     req.size   = 0;
    56     req.flags  = AF_KERNEL;
    57 
    58     nic_chbuf_t * chbuf = (nic_chbuf_t *)kmem_alloc( &req );
    59 
    60     assert( (chbuf != NULL) , __FUNCTION__ ,
    61              "cannot allocate chbuf descriptor" );
    62 
    63     // initialise chbuf state
    64     chbuf->cont_id  = 0;
    65     chbuf->pkt_id   = 0;
    66     chbuf->word_id  = 34;
    67    
    68     // allocate containers (one page per container)
    69     // and complete chbuf descriptor initialization
    70     assert( (CONFIG_PPM_PAGE_SIZE == 4096) , __FUNCTION__ ,
    71             "chbuf container must be 4 Kbytes" );
    72 
    73     for( i = 0 ; i < CONFIG_NIC_CHBUF_DEPTH ; i++ )
    74     {
    75         uint32_t * container = (uint32_t *)kmem_alloc( &req );   
    76 
    77         assert( (container != NULL) , __FUNCTION__ ,
    78                 "cannot allocate container" );
    79        
    80         chbuf->cont[i] = container;
    81         chbuf->full[i] = (paddr_t)XPTR( local_cxy , container );
    82     }
    83 } // end soclib_nic_init()
    84 
    85 
    86 //////////////////////////////////////////////////////////////////
    8741void __attribute__ ((noinline)) soclib_nic_cmd( xptr_t thread_xp )
    8842{
    89     uint32_t       cmd;          // command type   
    90     char         * buffer;       // pointer on command buffer   
    91     uint32_t       length;       // Ethernet packet length
    92     xptr_t         dev_xp;       // extended pointer on NIC device
    93     nic_chbuf_t  * chbuf;        // pointer on chbuf descriptor
    94     uint32_t       cont_id;      // index of current container in chbuf
    95     uint32_t       pkt_id;       // index of current packet in container
    96     uint32_t       word_id;      // index of first word of current packet in container
    97     uint32_t     * container;    // pointer on container (array of uint32_t)
    98     uint16_t     * header;       // pointer on container header (array of uint16_t)
    99     uint32_t       npackets;     // number of packets in current container
    10043
    101     // get local pointer for client thread
    102     thread_t * thread_ptr = (thread_t *)GET_PTR( thread_xp );
     44}
    10345
    104     // get command arguments
    105     cmd    = thread_ptr->command.nic.cmd;
    106     buffer = thread_ptr->command.nic.buffer;
    107     length = thread_ptr->command.nic.length;
    108     dev_xp = thread_ptr->command.nic.dev_xp;
    109 
    110     // get local pointer for device
    111     chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
    112 
    113     // get chbuf descriptor pointer
    114     chbuf = (nic_chbuf_t *)dev_ptr->ext.nic.queue;
    115 
    116     // analyse command type
    117     switch( cmd )
    118     {
    119         /////////////////////////////////////////////////////////////////////////////
    120         case NIC_CMD_READ:   // transfer one packet from RX queue to command buffer
    121         {
    122             // get current container index
    123             cont_id = chbuf->cont_id;
    124            
    125             if( chbuf->full[cont_id] == 0 )  // container empty
    126             {
    127                 printk("PANIC in %s : read an empty container\n", __FUNCTION__ );
    128                 hal_core_sleep();
    129             }
    130 
    131             // get pointer on container and header
    132             container = chbuf->cont[cont_id];
    133             header    = (uint16_t *)container;
    134 
    135             // get  expected packet index and first word index in container
    136             pkt_id  = chbuf->pkt_id;
    137             word_id = chbuf->word_id;
    138 
    139             // get packet length and number of packets from container header
    140             length    = header[pkt_id + 2];
    141             npackets  = header[0];
    142 
    143             if( pkt_id >= npackets )  // packet index too large
    144             {
    145                 printk("PANIC in %s : read a non readable container\n", __FUNCTION__ );
    146                 hal_core_sleep();
    147             }
    148 
    149             // move the packet from container to buffer
    150             memcpy( buffer , container + word_id , length );
    151 
    152             // update current packet index and first word index
    153             chbuf->pkt_id  = pkt_id + 1;
    154             if( length & 0x3 ) chbuf->word_id = word_id + (length>>2) + 1;
    155             else               chbuf->word_id = word_id + (length>>2);
    156         }
    157         break;    // end READ
    158            
    159         //////////////////////////////////////////////////////////////////////////
    160         case NIC_CMD_WRITE:  // move one packet from command buffer to TX queue
    161         {
    162             // get current TX container indexes
    163             cont_id = chbuf->cont_id;
    164             pkt_id  = chbuf->pkt_id;
    165             word_id = chbuf->word_id;
    166 
    167             if( chbuf->full[cont_id] != 0 )  // container full
    168             {
    169                 printk("PANIC in %s : write to a full container\n", __FUNCTION__ );
    170                 hal_core_sleep();
    171             }
    172 
    173             // get pointer on container and header
    174             container = chbuf->cont[cont_id];
    175             header    = (uint16_t *)container;
    176 
    177             if( length > ((1024 - word_id)<<2) )  // packet length too large
    178             {
    179                 printk("PANIC in %s : write to a non writable container\n", __FUNCTION__ );
    180                 hal_core_sleep();
    181             }
    182 
    183             // update packet length in container header
    184             header[pkt_id + 2] = (uint16_t)length;
    185 
    186             // move the packet from buffer to container
    187             memcpy( container + word_id , buffer , length );
    188 
    189             // update current packet index and first word index
    190             chbuf->pkt_id  = pkt_id + 1;
    191             if( length & 0x3 ) chbuf->word_id = word_id + (length>>2) + 1;
    192             else               chbuf->word_id = word_id + (length>>2);
    193         }
    194         break;  // end WRITE
    195 
    196         ////////////////////////////////////////////////////////////////////////////
    197         case NIC_CMD_WRITABLE:  // analyse chbuf status / update status if required
    198         {
    199             // get current container state
    200             cont_id = chbuf->cont_id;
    201             word_id = chbuf->word_id;
    202 
    203             // compute current container writable
    204             bool_t ok = ( chbuf->full[cont_id] == 0 ) &&
    205                         ( length <= ((1024 - word_id)<<2) );
    206 
    207             if( ok )                // current container writable
    208             {
    209                 // return chbuf writable
    210                 thread_ptr->command.nic.status = true;
    211             }
    212             else                    // current container not writable
    213             {
    214                 // release current container
    215                 chbuf->full[cont_id] = 1;
    216 
    217                 // check next container
    218                 cont_id = (cont_id + 1) % CONFIG_NIC_CHBUF_DEPTH;
    219 
    220                 if( chbuf->full[cont_id] == 0 ) // next container empty
    221                 {
    222                     // update chbuf status
    223                     chbuf->word_id = 34;
    224                     chbuf->cont_id = cont_id;
    225                     chbuf->pkt_id  = 0;
    226                      
    227                     // return chbuf writable
    228                     thread_ptr->command.nic.status = true;
    229                 }
    230                 else                            // next container full     
    231                 {
    232                     // return chbuf non writable
    233                     thread_ptr->command.nic.status = false;
    234                 }
    235             }
    236         }
    237         break;  // end WRITABLE
    238 
    239         /////////////////////////////////////////////////////////////////////////////
    240         case NIC_CMD_READABLE:  // analyse chbuf status / update status if required
    241         {
    242             // get current container state
    243             cont_id  = chbuf->cont_id;
    244             pkt_id   = chbuf->pkt_id;
    245             npackets = chbuf->cont[cont_id][0] & 0x0000FFFF;
    246            
    247             // compute current container readable
    248             bool_t ok = ( chbuf->full[cont_id] == 1 ) &&
    249                         ( pkt_id < npackets );
    250 
    251             if( ok )                    // current container readable
    252             {
    253                 // return chbuf readable     
    254                 thread_ptr->command.nic.status = true;
    255             }
    256             else                        // current container non readable
    257             {
    258                 // release current container
    259                 chbuf->full[cont_id] = 0;
    260 
    261                 // check next container
    262                 cont_id = (cont_id + 1) % CONFIG_NIC_CHBUF_DEPTH;
    263 
    264                 if( chbuf->full[cont_id] == 1 ) // next container full
    265                 {
    266                     // update chbuf status
    267                     chbuf->word_id = 34;
    268                     chbuf->cont_id = cont_id;
    269                     chbuf->pkt_id  = 0;
    270                      
    271                     // return chbuf readable
    272                     thread_ptr->command.nic.status = true;
    273                 }
    274                 else                            // next container empty   
    275                 {
    276                     // return chbuf non readable
    277                     thread_ptr->command.nic.status = false;
    278                 }
    279             }
    280    
    281         }
    282         break;  // end READABLE
    283     }
    284 } // end soclib_nic_cmd()
    285 
    286 
    287 /////////////////////////////////////////////////////////////////
    28846void __attribute__ ((noinline)) soclib_nic_isr( chdev_t * chdev )
    28947{
    290     // get base, size, channel, is_rx from NIC channel device NIC
    291     xptr_t     base    = chdev->base;
    292     uint32_t   channel = chdev->channel;
    293     bool_t     is_rx   = chdev->is_rx;
    29448
    295     // get NIC peripheral cluster and local pointer
    296     cxy_t      cxy_nic = GET_CXY( base );
    297     uint32_t * ptr_nic = (uint32_t *)GET_PTR( base );
     49}
    29850
    299     // compute local pointer on status register
    300     uint32_t * offset;
    301     if( is_rx ) offset = ptr_nic + (NIC_CHANNEL_SPAN * (channel + 1)) + NIC_RX_STATUS;
    302     else        offset = ptr_nic + (NIC_CHANNEL_SPAN * (channel + 1)) + NIC_TX_STATUS;
    303 
    304     // read NIC channel status and acknowledge IRQ
    305     uint32_t status = hal_remote_lw( XPTR( cxy_nic , offset ) );
    306 
    307     if( status != 0 ) hal_core_sleep("%s : illegal address\n", __FUNCTION__ );
    308    
    309     // unblock server thread
    310     thread_t * server = chdev->server;
    311     thread_unblock( XPTR( local_cxy , server ) , THREAD_BLOCKED_IO );
    312 
    313 } // end soclib_nic_isr()
    314 
    315 
    316 
Note: See TracChangeset for help on using the changeset viewer.