Ignore:
Timestamp:
Feb 8, 2015, 12:50:23 PM (10 years ago)
Author:
alain
Message:

Introduce a fully parallel procedure for the kernel initialisation.

File:
1 edited

Legend:

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

    r489 r494  
    6565////////////////////////////////////////////////////////////////////////////
    6666
     67__attribute__((section(".kdata")))
    6768unsigned int _tty_channel_allocator    = 1;
     69
     70__attribute__((section(".kdata")))
    6871unsigned int _tim_channel_allocator    = 0;
     72
     73__attribute__((section(".kdata")))
    6974unsigned int _cma_channel_allocator    = 0;
     75
     76__attribute__((section(".kdata")))
    7077unsigned int _nic_rx_channel_allocator = 0;
     78
     79__attribute__((section(".kdata")))
    7180unsigned int _nic_tx_channel_allocator = 0;
     81
     82////////////////////////////////////////////////////////////////////////////
     83// These global variables is defined in tty0.c and tty_driver.c files.
     84////////////////////////////////////////////////////////////////////////////
     85
     86extern sqt_lock_t _tty0_sqt_lock;
     87
     88extern unsigned int _tty_rx_full[NB_TTY_CHANNELS];
     89
     90extern unsigned int _tty_rx_buf[NB_TTY_CHANNELS];
    7291
    7392////////////////////////////////////////////////////////////////////////////
     
    7594////////////////////////////////////////////////////////////////////////////
    7695
     96__attribute__((section(".kdata")))
    7797nic_chbuf_t  _nic_rx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64)));
    7898
     99__attribute__((section(".kdata")))
    79100nic_chbuf_t  _nic_tx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64)));
    80101
     
    84105////////////////////////////////////////////////////////////////////////////
    85106
     107__attribute__((section(".kdata")))
    86108fbf_chbuf_t _fbf_chbuf[NB_CMA_CHANNELS] __attribute__((aligned(64)));
    87109
     110__attribute__((section(".kdata")))
    88111unsigned long long _fbf_chbuf_paddr[NB_CMA_CHANNELS];
    89112
     
    92115// Note: This array must be synchronised with the define in file stdio.h
    93116////////////////////////////////////////////////////////////////////////////
     117
     118__attribute__((section(".kdata")))
    94119const void * _syscall_vector[64] =
    95120{
     
    241266
    242267///////////////////////////////////////////
    243 int _sys_tty_get_lock( unsigned int   channel,
     268int _sys_tty_get_lock( unsigned int   channel,       // unused
    244269                       unsigned int * save_sr_ptr )
    245270{
    246     // compute and check tty channel
    247     if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
    248     if( channel >= NB_TTY_CHANNELS ) return -1;
     271    // check tty channel
     272    if( channel != 0 )  return 1;
    249273
    250274    _it_disable( save_sr_ptr );
    251     _sbt_lock_acquire( &_tty_tx_lock[channel] );
     275    _sqt_lock_acquire( &_tty0_sqt_lock );
    252276    return 0;
    253277}
     
    257281                           unsigned int * save_sr_ptr )
    258282{
    259     // compute and check tty channel
    260     if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
    261     if( channel >= NB_TTY_CHANNELS ) return -1;
    262 
    263     _sbt_lock_release( &_tty_tx_lock[channel] );
     283    // check tty channel
     284    if( channel != 0 )  return 1;
     285
     286    _sqt_lock_release( &_tty0_sqt_lock );
    264287    _it_restore( save_sr_ptr );
    265288    return 0;
     
    332355#define NIC_CONTAINER_SIZE 4096
    333356
    334 ///////////////////////////////////////////
    335 int _sys_nic_alloc( unsigned int is_rx )
    336 {
     357////////////////////////////////////////
     358int _sys_nic_alloc( unsigned int is_rx,
     359                    unsigned int xmax,
     360                    unsigned int ymax )
     361{
     362    // check xmax / ymax parameters
     363    if ( xmax > X_SIZE )
     364    {
     365        _printf("\n[GIET_ERROR] in _sys_nic_alloc() xmax argument too large\n");
     366        return -1;
     367    }
     368    if ( ymax > Y_SIZE )
     369    {
     370        _printf("\n[GIET_ERROR] in _sys_nic_alloc() ymax argument too large\n");
     371        return -1;
     372    }
     373
     374    // get a NIC_RX or NIC_TX channel index
     375    unsigned int nic_channel;
     376    unsigned int cma_channel;
     377
     378    if ( is_rx ) nic_channel = _atomic_increment( &_nic_rx_channel_allocator, 1 );
     379    else         nic_channel = _atomic_increment( &_nic_tx_channel_allocator, 1 );
     380
     381    if ( (nic_channel >= NB_NIC_CHANNELS) )
     382    {
     383        _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough NIC channels\n");
     384        return -1;
     385    }
     386
     387    // get a CMA channel index
     388    cma_channel = _atomic_increment( &_cma_channel_allocator, 1 );
     389
     390    if ( cma_channel >= NB_CMA_CHANNELS )
     391    {
     392        _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough CMA channels\n");
     393        return -1;
     394    }
    337395
    338396#if GIET_DEBUG_NIC
    339397unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
    340 _printf("\n[GIET DEBUG NIC] Task %d enters sys_nic_alloc() at cycle %d\n",
    341         thread, _get_proctime() );
    342 #endif
    343 
    344     unsigned int nic_channel;
    345     unsigned int cma_channel;
    346 
    347     // get a NIC_RX or NIC_TX channel index
    348     if ( is_rx ) nic_channel = _atomic_increment( &_nic_rx_channel_allocator, 1 );
    349     else         nic_channel = _atomic_increment( &_nic_tx_channel_allocator, 1 );
    350 
    351     if ( (nic_channel >= NB_NIC_CHANNELS) )
    352     {
    353         _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough NIC channels\n");
    354         return -1;
    355     }
    356 
    357     // get a CMA channel index
    358     cma_channel = _atomic_increment( &_cma_channel_allocator, 1 );
    359 
    360     if ( cma_channel >= NB_CMA_CHANNELS )
    361     {
    362         _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough CMA channels\n");
    363         return -1;
    364     }
     398_printf("\n[GIET DEBUG NIC] Task %d enters sys_nic_alloc() at cycle %d\n"
     399        " nic_channel = %d / cma_channel = %d\n"
     400        thread , _get_proctime() , nic_channel , cma_channel );
     401#endif
    365402
    366403    // register nic_index and cma_index in task context
     
    376413    }
    377414
    378 #if GIET_DEBUG_NIC
    379 _printf("\n[GIET DEBUG NIC] Task %d exit _sys_nic_alloc() at cycle %d : "
    380         "NIC channel = %d / CMA channel = %d\n",
    381         thread, _get_proctime(), nic_channel, cma_channel );
    382 #endif
    383 
    384     return nic_channel;
    385 } // end _sys_nic_alloc()
    386 
    387 ////////////////////////////////////////
    388 int _sys_nic_start( unsigned int is_rx,
    389                     unsigned int channel )
    390 {
    391 
    392 #if GIET_DEBUG_NIC
    393 unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
    394 _printf("\n[GIET DEBUG NIC] Task %d enters _sys_nic_start() at cycle %d\n",
    395         thread , _get_proctime() );
    396 #endif
    397 
    398     unsigned int nic_channel;
    399     unsigned int cma_channel;
    400 
    401     // get NIC channel index and CMA channel index
    402     if ( is_rx )
    403     {
    404         nic_channel = _get_context_slot( CTX_NIC_RX_ID );
    405         cma_channel = _get_context_slot( CTX_CMA_RX_ID );
    406     }
    407     else
    408     {
    409         nic_channel = _get_context_slot( CTX_NIC_TX_ID );
    410         cma_channel = _get_context_slot( CTX_CMA_TX_ID );
    411     }
    412 
    413 #if GIET_DEBUG_NIC
    414 _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_start() at cycle %d"
    415         " get NIC channel = %d / CMA channel = %d\n",
    416         thread, _get_proctime(), nic_channel, cma_channel );
    417 #endif
    418 
    419     if ( nic_channel != channel )
    420     {
    421         _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal NIC channel\n");
    422         return -1;
    423     }
    424     if ( cma_channel >= NB_CMA_CHANNELS )
    425     {
    426         _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal CMA channel\n");
    427         return -1;
    428     }
    429 
     415    // physical addresses to be registered in the CMA registers
    430416    unsigned long long nic_chbuf_pbase;     // NIC chbuf physical address
    431417    unsigned long long ker_chbuf_pbase;     // kernel chbuf physical address
     
    437423    unsigned int       vaddr;
    438424
    439     // allocate two containers per cluster
    440     unsigned int        cx;           // container X coordinate
    441     unsigned int        cy;           // container Y coordinate
    442     unsigned int        index;        // container index in chbuf
    443     unsigned long long  cont_paddr;   // container physical address
    444    
    445     for ( cx = 0 ; cx < X_SIZE ; cx++ )
    446     {
    447         for ( cy = 0 ; cy < Y_SIZE ; cy++ )
     425    // allocate one kernel container per cluster in the (xmax / ymax) mesh
     426    unsigned int        cx;              // cluster X coordinate
     427    unsigned int        cy;              // cluster Y coordinate
     428    unsigned int        index;           // container index in chbuf
     429    unsigned long long  cont_paddr;      // container physical address
     430
     431    for ( cx = 0 ; cx < xmax ; cx++ )
     432    {
     433        for ( cy = 0 ; cy < ymax ; cy++ )
    448434        {
    449435            // compute index in chbuf
    450             index = (cx * Y_SIZE) + cy;
    451 
    452             // allocate the container
     436            index = (cx * ymax) + cy;
     437
     438            // allocate the kernel container
    453439            vaddr = (unsigned int)_remote_malloc( NIC_CONTAINER_SIZE, cx, cy );
     440
     441            if ( vaddr == 0 )  // not enough kernel heap memory in cluster[cx,cy]
     442            {
     443                _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough kenel heap"
     444                        " in cluster[%d,%d]\n", cx, cy );
     445                return -1;
     446            }
    454447
    455448            // compute container physical address
     
    460453            cont_paddr = (((unsigned long long)ppn) << 12) | (vaddr & 0x00000FFF);
    461454
    462             // initialize chbuf
     455            // initialize chbuf entry
    463456            if ( is_rx ) _nic_rx_chbuf[nic_channel].buffer[index].desc = cont_paddr;
    464457            else         _nic_tx_chbuf[nic_channel].buffer[index].desc = cont_paddr;
     
    470463#endif
    471464        }
     465    }
     466
     467    // complete kernel chbuf initialisation
     468    if ( is_rx )
     469    {
     470        _nic_rx_chbuf[nic_channel].xmax = xmax;
     471        _nic_rx_chbuf[nic_channel].ymax = ymax;
     472    }
     473    else
     474    {
     475        _nic_tx_chbuf[nic_channel].xmax = xmax;
     476        _nic_tx_chbuf[nic_channel].ymax = ymax;
    472477    }
    473478
     
    511516        _cma_set_register( cma_channel, CHBUF_DST_DESC , (unsigned int)(ker_chbuf_pbase) );
    512517        _cma_set_register( cma_channel, CHBUF_DST_EXT  , (unsigned int)(ker_chbuf_pbase>>32) );
    513         _cma_set_register( cma_channel, CHBUF_DST_NBUFS, X_SIZE*Y_SIZE );
     518        _cma_set_register( cma_channel, CHBUF_DST_NBUFS, xmax * ymax );
    514519    }
    515520    else                      // kernel to NIC
     
    517522        _cma_set_register( cma_channel, CHBUF_SRC_DESC , (unsigned int)(ker_chbuf_pbase) );
    518523        _cma_set_register( cma_channel, CHBUF_SRC_EXT  , (unsigned int)(ker_chbuf_pbase>>32) );
    519         _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, X_SIZE*Y_SIZE );
     524        _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, xmax * ymax );
    520525        _cma_set_register( cma_channel, CHBUF_DST_DESC , (unsigned int)(nic_chbuf_pbase) );
    521526        _cma_set_register( cma_channel, CHBUF_DST_EXT  , (unsigned int)(nic_chbuf_pbase>>32) );
    522527        _cma_set_register( cma_channel, CHBUF_DST_NBUFS, 2 );
     528    }
     529
     530#if GIET_DEBUG_NIC
     531_printf("\n[GIET DEBUG NIC] Task %d exit _sys_nic_alloc() at cycle %d\n",
     532        thread, _get_proctime() );
     533#endif
     534
     535    return nic_channel;
     536} // end _sys_nic_alloc()
     537
     538
     539////////////////////////////////////////
     540int _sys_nic_start( unsigned int is_rx,
     541                    unsigned int channel )
     542{
     543    unsigned int nic_channel;
     544    unsigned int cma_channel;
     545
     546    // get NIC channel index and CMA channel index from task context
     547    if ( is_rx )
     548    {
     549        nic_channel = _get_context_slot( CTX_NIC_RX_ID );
     550        cma_channel = _get_context_slot( CTX_CMA_RX_ID );
     551    }
     552    else
     553    {
     554        nic_channel = _get_context_slot( CTX_NIC_TX_ID );
     555        cma_channel = _get_context_slot( CTX_CMA_TX_ID );
     556    }
     557
     558#if GIET_DEBUG_NIC
     559unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
     560_printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_start() at cycle %d"
     561        " get NIC channel = %d / CMA channel = %d\n",
     562        thread, _get_proctime(), nic_channel, cma_channel );
     563#endif
     564
     565    // check NIC and CMA channels index
     566    if ( nic_channel != channel )
     567    {
     568        _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal NIC channel\n");
     569        return -1;
     570    }
     571    if ( cma_channel >= NB_CMA_CHANNELS )
     572    {
     573        _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal CMA channel\n");
     574        return -1;
    523575    }
    524576
     
    539591}  // end sys_nic_start()
    540592
     593
    541594//////////////////////////////////////
    542595int _sys_nic_move( unsigned int is_rx,
     
    551604#endif
    552605
     606    // check NIC channel index
     607    if ( channel >= NB_NIC_CHANNELS )
     608    {
     609        _printf("\n[GIET_ERROR] in _sys_nic_move() : illegal NIC channel index\n");
     610        return -1;
     611    }
     612
     613    // get kernel chbuf virtual address
     614    nic_chbuf_t* chbuf;
     615    if ( is_rx )  chbuf = &_nic_rx_chbuf[channel];
     616    else          chbuf = &_nic_tx_chbuf[channel];
     617
     618    // get xmax / ymax parameters
     619    unsigned int xmax = chbuf->xmax;
     620    unsigned int ymax = chbuf->ymax;
     621
    553622    // get cluster coordinates for the processor running the calling task
    554623    unsigned int  procid = _get_procid();
    555624    unsigned int  cx     = procid >> (Y_WIDTH + P_WIDTH);
    556625    unsigned int  cy     = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
     626   
     627    // check processor coordinates / (xmax,ymax)
     628    if ( cx >= xmax )
     629    {
     630        _printf("\n[GIET_ERROR] in _sys_nic_move() : processor X coordinate = %d"
     631                " / xmax = %d\n", cx , xmax );
     632        return -1;
     633    }
     634    if ( cy >= ymax )
     635    {
     636        _printf("\n[GIET_ERROR] in _sys_nic_move() : processor Y coordinate = %d"
     637                " / ymax = %d\n", cy , ymax );
     638        return -1;
     639    }
    557640   
    558641    unsigned long long user_buffer_paddr;    // user buffer physical address
     
    588671#endif
    589672
    590     // check NIC channel index
    591     if ( channel >= NB_NIC_CHANNELS )
    592     {
    593         _printf("\n[GIET_ERROR] in _sys_nic_move() : illegal NIC channel index\n");
    594         return -1;
    595     }
    596 
    597     // get kernel chbuf virtual address
    598     nic_chbuf_t* chbuf;
    599     if ( is_rx )  chbuf = &_nic_rx_chbuf[channel];
    600     else          chbuf = &_nic_tx_chbuf[channel];
    601 
    602673    // compute kernel chbuf physical address (required for sync)
    603674    vaddr = (unsigned int)chbuf;
     
    608679    kernel_chbuf_paddr = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF);
    609680
    610     // poll chbuf until success
     681    // poll local kernel container status until success
    611682    while ( 1 )
    612683    {
    613684        // compute buffer index and buffer descriptor paddr
    614         index = (Y_SIZE * cx) + cy;
     685        index = (ymax * cx) + cy;
    615686        buffer_desc_paddr = kernel_chbuf_paddr + (index<<6);
    616687
     
    633704    kernel_buffer_paddr = buffer_desc & 0x0000FFFFFFFFFFFFULL;
    634705   
    635     // move one container, using a physical_memcpy
    636     if ( is_rx )
     706    // move one container
     707    if ( is_rx )              // RX transfer
    637708    {
    638709        // inval kernel buffer in L2 before read in L2
     
    650721
    651722    }
    652     else
     723    else                      // TX transfer
    653724    {
    654725        // transfer data from user buffer to kernel buffer
     
    683754} // end _sys_nic_move()
    684755
     756
    685757////////////////////////////////////////
    686758int _sys_nic_stop( unsigned int is_rx,
     
    702774    }
    703775
     776    // check NIC and CMA channels index
    704777    if ( nic_channel != channel )
    705778    {
    706         _printf("\n[GIET_ERROR] in _sys_nic_stop(): illegal NIC channel\n"
    707                 "  allocated channel = %d / requested channel = %d\n",
    708                    nic_channel , channel );
     779        _printf("\n[GIET_ERROR] in _sys_nic_stop(): illegal NIC channel\n");
    709780        return -1;
    710781    }
     
    722793
    723794    return 0;
    724 }
     795}  // end _sys_nic_stop()
    725796
    726797////////////////////////////////////////
     
    763834    }
    764835    return 0;
    765 }
     836}  // en _sys_nic_clear()
    766837
    767838////////////////////////////////////////
     
    834905    }
    835906    return 0;
    836 }
     907}  // end _sys_nic_stats()
    837908
    838909/////////////////////////////////////////////////////////////////////////////////////////
     
    12311302}
    12321303
    1233 //////////////////////////////////////
    1234 int _sys_procs_number( unsigned int  x,
    1235                        unsigned int  y,
    1236                        unsigned int* number )
    1237 {
    1238     mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     1304////////////////////////////////////////////
     1305int _sys_procs_number( unsigned int* x_size,
     1306                       unsigned int* y_size,
     1307                       unsigned int* nprocs )
     1308{
     1309    mapping_header_t * header   = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
    12391310    mapping_cluster_t * cluster = _get_cluster_base(header);
    12401311
    1241     if ( (x < X_SIZE) && (y < Y_SIZE) )
    1242     {
    1243         *number = cluster[(x*Y_SIZE)+y].procs;
    1244         return 0;
    1245     }
    1246     else
    1247     {
    1248         _printf("\n[GIET ERROR] in _sys_procs_number() : illegal (x,y) coordinates\n" );
    1249         return -1;
    1250     }
     1312    unsigned int x;
     1313    unsigned int y;
     1314    unsigned int okmin = 1;
     1315    unsigned int okmax = 1;
     1316
     1317    // compute max values
     1318    unsigned int xmax  = header->x_size;
     1319    unsigned int ymax  = header->y_size;
     1320    unsigned int procs = cluster[0].procs;
     1321
     1322    // check the (ymax-1) lower rows
     1323    for ( y = 0 ; y < ymax-1 ; y++ )
     1324    {
     1325        for ( x = 0 ; x < xmax ; x++ )
     1326        {
     1327            if (cluster[x*ymax+y].procs != procs ) okmin = 0;
     1328        }
     1329    }
     1330
     1331    // check the upper row
     1332    for ( x = 0 ; x < xmax ; x++ )
     1333    {
     1334        if (cluster[x*ymax+ymax-1].procs != procs ) okmax = 0;
     1335    }
     1336
     1337    // return values
     1338    if ( okmin && okmax )
     1339    {
     1340        *x_size = xmax;
     1341        *y_size = ymax;
     1342        *nprocs = procs;
     1343    }
     1344    else if ( okmin )
     1345    {
     1346        *x_size = xmax;
     1347        *y_size = ymax-1;
     1348        *nprocs = procs;
     1349    }
     1350    else
     1351    {
     1352        *x_size = 0;
     1353        *y_size = 0;
     1354        *nprocs = 0;
     1355    }
     1356    return 0;
    12511357}
    12521358
Note: See TracChangeset for help on using the changeset viewer.