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

Introduce a fully parallel procedure for the kernel initialisation.

Location:
soft/giet_vm/giet_kernel
Files:
5 edited

Legend:

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

    r459 r494  
    2727#endif
    2828
    29 // ISR_TYPE names for display
     29////////////////////////////////////////////
     30//     ISR_TYPE names for display
     31///////////////////////////////////////////
     32__attribute__((section(".kdata")))
    3033char* _isr_type_name[] = { "DEFAULT",
    3134                           "TICK"   ,
  • soft/giet_vm/giet_kernel/kernel.ld

    r322 r494  
    2222    seg_kernel_data :
    2323    {
    24         *(.iommu)
    25         *(.fatdata)
    26         *(.descriptor)
    2724        *(.kdata)
    28         *(.rodata)
    29         *(.rodata.*)
    30         *(.data)
    31         *(.lit8)
    32         *(.lit4)
    33         *(.sdata)
    34         *(.bss)
    35         *(COMMON)
    36         *(.sbss)
    37         *(.scommon)
    3825    }
    3926
  • soft/giet_vm/giet_kernel/kernel_init.c

    r478 r494  
    1313#include <tty0.h>
    1414#include <kernel_malloc.h>
     15#include <kernel_locks.h>
     16#include <kernel_barriers.h>
    1517#include <fat32.h>
    1618#include <xcu_driver.h>
     
    7274
    7375
     76// Distributed kernel heap descriptors array
     77// __attribute__((section(".kdata")))
     78// kernel_heap_t  kernel_heap[X_SIZE][Y_SIZE];
     79
     80// FAT internal representation for kernel code
     81__attribute__((section(".kdata")))
     82fat32_fs_t     fat      __attribute__((aligned(512)));
     83
     84// array of page tables virtual addresses
     85__attribute__((section(".kdata")))
     86volatile unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX];
     87
     88// array of page tables PTPR values (physical addresses >> 13)
     89__attribute__((section(".kdata")))
     90volatile unsigned int _ptabs_ptprs[GIET_NB_VSPACE_MAX];
     91
     92// Array of pointers on the schedulers
     93__attribute__((section(".kdata")))
     94volatile static_scheduler_t*    _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
     95
     96// Synchonisation before entering parallel execution
     97__attribute__((section(".kdata")))
     98volatile unsigned int _kernel_init_done = 0;
     99
     100// Kernel uses sqt_lock to protect TTY0       
     101__attribute__((section(".kdata")))
     102unsigned int   _tty0_boot_mode = 0;
     103
     104// Distributed synchronisation barrier for parallel init by all processors     
     105__attribute__((section(".kdata")))
     106sqt_barrier_t  _all_procs_barrier  __attribute__((aligned(64)));
     107
     108
     109
     110// this variable is defined in tty0.c file
     111extern sqt_lock_t _tty0_sqt_lock;
     112
     113
     114
    74115///////////////////////////////////////////////////////////////////////////////////
    75 // Ditributed kernel heap descriptors array (for dynamic memory allocation)
    76 ///////////////////////////////////////////////////////////////////////////////////
    77 
    78 kernel_heap_t  kernel_heap[X_SIZE][Y_SIZE];
    79 
    80 ///////////////////////////////////////////////////////////////////////////////////
    81 // FAT internal representation for kernel code
    82 ///////////////////////////////////////////////////////////////////////////////////
    83 
    84 fat32_fs_t     fat      __attribute__((aligned(512)));
    85 
    86 ///////////////////////////////////////////////////////////////////////////////////
    87 // array of pointers on the page tables (virtual addresses)
    88 ///////////////////////////////////////////////////////////////////////////////////
    89 
    90 volatile unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX];    // virtual addresses
    91 volatile unsigned int _ptabs_ptprs[GIET_NB_VSPACE_MAX];    // physical addresses >> 13
    92 
    93 ///////////////////////////////////////////////////////////////////////////////////
    94 // Array of pointers on the schedulers (physical addresses)
    95 ///////////////////////////////////////////////////////////////////////////////////
    96 
    97 volatile static_scheduler_t*    _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
    98 
    99 ////////////////////////////////////////////////////////////////////////////////////
    100 // Synchonisation barrier before jumping to user code
    101 ////////////////////////////////////////////////////////////////////////////////////
    102 
    103 volatile unsigned int kernel_init_barrier = 0;
    104 
    105 ////////////////////////////////////////////////////////////////////////////////////
    106 // Global variables for TTY/kernel communications
    107 ////////////////////////////////////////////////////////////////////////////////////
    108 
    109 unsigned int   _tty_rx_buf[NB_TTY_CHANNELS];
    110 unsigned int   _tty_rx_full[NB_TTY_CHANNELS];
    111 
    112 ////////////////////////////////////////////////////////////////////////////////////
    113 // Distributed locks protecting TTY terminals       
    114 ////////////////////////////////////////////////////////////////////////////////////
    115 
    116 sbt_lock_t     _tty_tx_lock[NB_TTY_CHANNELS]  __attribute__((aligned(64)));
    117 
    118 ///////////////////////////////////////////////////////////////////////////////////
    119 // This kernel_init() function completes the kernel initialisation in 7 steps:
    120 // All processors execute this code, but this is done sequencially.
    121 // - step 0 : Initialise fat, heap descriptors, and tty locks
    122 // - step 1 : Initialise scheduler pointers array
    123 // - step 2 : Initialise PTAB pointers arrays
    124 // - step 3 : Initialise private XCU masks
    125 // - step 4 :
    126 // - step 5 :
    127 // - step 6 :
     116// This kernel_init() function completes the kernel initialisation in 7 steps.
     117// Step 0 is done by processor[0,0,0]. Steps 1 to 6 are executed in parallel
     118// by all procesors.
     119// - step 0 : P[0,0,0] Initialise fat, heap descriptors, barrier and TTY0 lock.
     120// - step 1 : Each processor initialises scheduler pointers array.
     121// - step 2 : Each processor initialises PTAB pointers arrays.
     122// - step 3 : Each processor initialises its private XCU masks.
     123// - step 4 : Each processor starts its private TICK timer.
     124// - step 5 : Each processor initialises its private idle task context.
     125// - step 6 : Each processor set sp, sr, ptpr, epc registers values.
    128126///////////////////////////////////////////////////////////////////////////////////
    129127__attribute__((section (".kinit"))) void kernel_init()
    130128{
    131     // gpid : hardware processor index (fixed format: X_WIDTH|Y_WIDTH|P_WIDTH)
    132     // p    : local processor id in a cluster ( p < NB_PROCS_MAX)
    133     // cpid : continuous processor index = (((x * Y_SIZE + y) * NB_PROCS_MAX) + p
     129    // gpid  : hardware processor index (fixed format: X_WIDTH|Y_WIDTH|P_WIDTH)
     130    // x,y,p : processor coordinates ( x<X_SIZE / y<Y_SIZE / p<NB_PROCS_MAX )
    134131
    135132    unsigned int gpid       = _get_procid();
     
    138135    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    139136    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
    140     unsigned int cpid       = ((( x * Y_SIZE) + y) * NB_PROCS_MAX) + p;
    141 
    142     // This initialisation is done sequencially by each processor
    143     while( cpid != kernel_init_barrier ) asm volatile ( "nop" );
    144 
    145     // Step 0 : P[0,0,0] initialises various complex structures
    146     //          - kernel FAT
    147     //          - distributed kernel heaps
    148     //          - distributed locks protecting TTY channels
    149     //          - distributed locks protecting MMC components
     137
     138    ////////////////////////////////////////////////////////////////////////////
     139    // Step 0 : P[0,0,0] initialises various structures
     140
    150141    if ( gpid == 0 )
    151142    {
     143        // distributed kernel heaps
    152144        _heap_init();
    153145       
     
    155147_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel HEAP init\n", x, y, p );
    156148#endif
    157         unsigned int channel;
    158         for ( channel = 0 ; channel < NB_TTY_CHANNELS ; channel++ )
    159         {
    160             _sbt_lock_init( &_tty_tx_lock[channel] );
    161 
    162 #if GIET_DEBUG_INIT
    163 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes TTY[%d] lock init\n",
    164                x , y , p , channel );
    165 #endif
    166         }
    167 
    168 /*
    169         unsigned int cx, cy;
    170         for ( cx = 0 ; cx < X_SIZE ; cx++ )
    171         {
    172             for ( cy = 0 ; cy < X_SIZE ; cy++ )
    173             {
    174                 _sbt_lock_init( &_mmc_lock[cx][cy] );
    175 
    176 #if GIET_DEBUG_INIT
    177 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes MMC[%d][%d] lock init\n",
    178                x , y , p , cx , cy );
    179 #endif
    180             }
    181         }
    182 */
     149        // kernel FAT
    183150        _fat_init( IOC_BOOT_MODE );
    184151
     
    186153_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel FAT init\n", x, y, p );
    187154#endif
    188 
    189     }
    190 
    191     // Step 1 : each processor get its scheduler virtual address from CP0_SCHED register
    192     //          and contributes to _schedulers[] array initialisation
     155        // distributed lock for TTY0
     156        _sqt_lock_init( &_tty0_sqt_lock );
     157
     158#if GIET_DEBUG_INIT
     159_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes TTY0 lock init\n",
     160               x , y , p );
     161#endif
     162        // distributed kernel barrier between all processors
     163        _sqt_barrier_init( &_all_procs_barrier );
     164
     165#if GIET_DEBUG_INIT
     166_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes barrier init\n",
     167               x , y , p );
     168#endif
     169
     170        // release other processors
     171        _kernel_init_done = 1;
     172    }
     173    else
     174    {
     175        while( _kernel_init_done == 0 )  asm volatile ( "nop" );
     176    }
     177
     178    ///////////////////////////////////////////////////////////////////
     179    // Step 1 : each processor get its scheduler vaddr from CP0_SCHED,
     180    //          contributes to _schedulers[] array initialisation,
     181    //          and wait completion of array initialisation.
    193182
    194183    static_scheduler_t* psched     = (static_scheduler_t*)_get_sched();
     
    198187
    199188#if GIET_DEBUG_INIT
    200 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises SCHED array\n"
    201                " - scheduler vbase = %x\n"
    202                " - tasks           = %d\n",
    203                x, y, p, (unsigned int)psched, tasks );
    204 #endif
    205 
     189_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises SCHED array\n"
     190        " - scheduler vbase = %x\n"
     191        " - tasks           = %d\n",
     192        x, y, p, (unsigned int)psched, tasks );
     193#endif
     194
     195    _sqt_barrier_wait( &_all_procs_barrier );   
     196
     197    ////////////////////////////////////////////////////////////////////////////
    206198    // step 2 : each processor that is allocated at least one task loops
    207199    //          on all allocated tasks:
     
    225217
    226218#if GIET_DEBUG_INIT
    227 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises PTABS arrays\n"
     219_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises PTABS arrays\n"
    228220        " - ptabs_vaddr[%d] = %x / ptpr_paddr[%d] = %l\n",
    229221        x, y, p, 
     
    244236
    245237#if GIET_DEBUG_INIT
    246 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] updates context for task %d\n"
    247                " - ctx_epc   = %x\n"
    248                " - ctx_ra    = %x\n",
    249                x, y, p, ltid,
    250                _get_task_slot( x, y, p, ltid, CTX_EPC_ID ),
    251                _get_task_slot( x, y, p, ltid, CTX_RA_ID ) );
     238_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] updates context for task %d\n"
     239        " - ctx_epc   = %x\n"
     240        " - ctx_ra    = %x\n",
     241        x, y, p, ltid,
     242        _get_task_slot( x, y, p, ltid, CTX_EPC_ID ),
     243        _get_task_slot( x, y, p, ltid, CTX_RA_ID ) );
    252244#endif
    253245
    254246    }  // end for tasks
    255247
    256     // step 3 : compute and set XCU masks
     248    _sqt_barrier_wait( &_all_procs_barrier );   
     249
     250    ////////////////////////////////////////////////////////////////////////////
     251    // step 3 : compute and set XCU masks for HWI / PTI / WTI interrupts
    257252
    258253    unsigned int isr_switch_index = 0xFFFFFFFF;
     
    279274
    280275#if GIET_DEBUG_INIT
    281 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] sets XCU masks\n"
    282                " - XCU HWI_MASK = %x\n"
    283                " - XCU WTI_MASK = %x\n"
    284                " - XCU PTI_MASK = %x\n",
    285                x, y, p, hwi_mask, wti_mask, pti_mask );
     276_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] sets XCU masks\n"
     277        " - ISR_TICK_INDEX = %d\n"
     278        " - XCU HWI_MASK   = %x\n"
     279        " - XCU WTI_MASK   = %x\n"
     280        " - XCU PTI_MASK   = %x\n",
     281        x, y, p,
     282        isr_switch_index,
     283        hwi_mask, wti_mask, pti_mask );
    286284#endif
    287285
     
    292290    _xcu_set_mask( cluster_xy, channel, pti_mask, IRQ_TYPE_PTI );
    293291
    294     // step 4 : start TICK timer if at least one task
     292    ////////////////////////////////////////////////////////////////////////////
     293    // step 4 : Each processor start TICK timer if at least one task
     294
    295295    if (tasks > 0)
    296296    {
     
    298298        if (isr_switch_index == 0xFFFFFFFF)
    299299        {
    300             _nolock_printf("\n[GIET ERROR] ISR_TICK not found for processor[%d,%d,%d]\n",
     300            _printf("\n[GIET ERROR] ISR_TICK not found for processor[%d,%d,%d]\n",
    301301                           x, y, p );
    302302            _exit();
     
    309309
    310310#if GIET_DEBUG_INIT
    311 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] starts TICK timer\n",
    312                x, y, p );
    313 #endif
    314 
     311_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] starts TICK timer\n",
     312        x, y, p );
     313#endif
     314
     315    ////////////////////////////////////////////////////////////////////////////
    315316    // step 5 : each processor updates the idle_task context:
    316317    //          (CTX_SP, CTX_RA, CTX_EPC).
     
    326327
    327328#if GIET_DEBUG_INIT
    328 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initializes IDLE task\n"
    329                " - stack_base = %x\n"
    330                " - stack_size = 0x1000\n",
    331                x, y, p, pstack - 0x1000 );
    332 #endif
    333 
    334     // step 6 : when all processors reach the synchronisation barrier,
    335     //          each processor set registers SP, SR, PTPR, EPC,
    336     //          with the values corresponding to the first allocated task,
    337     //          or to the idle_task if there is no task allocated,
    338     //          and jump to user code
    339 
    340     if (tasks == 0)
     329_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initializes IDLE task\n"
     330        " - stack_base = %x\n"
     331        " - stack_size = 0x1000\n",
     332        x, y, p, pstack - 0x1000 );
     333#endif
     334
     335    _sqt_barrier_wait( &_all_procs_barrier );   
     336
     337    ////////////////////////////////////////////////////////////////////////////
     338    // step 6 : Each processor compute values for registers SP, SR, PTPR, EPC,
     339    //          corresponding to the first allocated task (can be idle task)
     340    //          and jump to user code when barrier is reached
     341
     342    if (tasks == 0)
    341343    {
    342344        ltid = IDLE_TASK_INDEX;
    343 
    344         _nolock_printf("\n[GIET WARNING] No task allocated to processor[%d,%d,%d]\n",
    345                        x, y, p );
     345        _printf("\n[GIET WARNING] No task allocated to processor[%d,%d,%d]\n",
     346                x, y, p );
    346347    }
    347348    else
     
    355356    unsigned int epc_value  = _get_task_slot( x, y, p, ltid, CTX_EPC_ID);
    356357
    357 #if GIET_DEBUG_INIT
    358 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] reach barrier at cycle %d\n",
    359                x, y, p, _get_proctime() );
    360 #endif
    361 
    362     // increment barrier counter
    363     kernel_init_barrier++;
    364 
    365     // busy waiting until all processors synchronized
    366     while ( kernel_init_barrier != NB_TOTAL_PROCS );
    367 
    368 #if GIET_DEBUG_INIT
    369 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initializes registers at cycle %d\n"
    370         " - sp   = %x\n"
    371         " - sr   = %x\n"
    372         " - ptpr = %x\n"
    373         " - epc  = %x\n",
     358    _sqt_barrier_wait( &_all_procs_barrier );
     359
     360#if GIET_DEBUG_INIT
     361_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] jumps to user code at cycle %d\n"
     362        "  sp = %x / sr = %x / ptpr = %x / epc = %x\n",
    374363        x, y, p, _get_proctime(),
    375364        sp_value, sr_value, ptpr_value, epc_value );
  • 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
  • soft/giet_vm/giet_kernel/sys_handler.h

    r489 r494  
    1414
    1515#include "giet_config.h"
    16 #include "locks.h"
     16#include "kernel_locks.h"
    1717
    1818///////////////////////////////////////////////////////////////////////////////////
     
    4141// This structure is used by the CMA component to move a stream
    4242// of images from two user buffers to the frame buffer in kernel space.
    43 // it must be 64 bytes aligned.
    4443// It contains two chbuf arrays:
    4544// - The SRC chbuf contains two buffers (buf0 & buf1), in user space.
    4645// - The DST cbuf contains one single buffer (fbf), that is the frame buffer.
    4746// - The length field define the buffer size (bytes)
     47// This structure must be 64 bytes aligned.
    4848///////////////////////////////////////////////////////////////////////////////////
    4949
     
    6060// This structure is used by the CMA component to move a stream of containers
    6161// between the NIC chbuf containing 2 buffers, and a kernel chbuf
    62 // containing (X_SIZE * Y_SIZE) buffers (one buffer per cluster).
     62// containing up to (X_SIZE * Y_SIZE) buffers (one buffer per cluster).
    6363// The same structure is used for both TX or RX transfers.
    64 // It must be 64 bytes aligned.
     64// The number of distributed containers can be smaller than (X_SIZE * YSIZE).
     65// The actual number of buffers used in the chbuf is defined by (xmax * ymax).
     66// This structure must be 64 bytes aligned.
    6567//////////////////////////////////////////////////////////////////////////////////
    6668
     
    6870{
    6971    buffer_descriptor_t  buffer[X_SIZE*Y_SIZE];  // kernel chbuf
     72    unsigned int         xmax;                   // nb clusters in a row
     73    unsigned int         ymax;                   // nb clusters in a column
    7074} nic_chbuf_t;
    7175
     
    104108//////////////////////////////////////////////////////////////////////////////
    105109
    106 int _sys_nic_alloc( unsigned int is_rx );
     110int _sys_nic_alloc( unsigned int is_rx,
     111                    unsigned int xmax,
     112                    unsigned int ymax );
     113
    107114
    108115int _sys_nic_start( unsigned int is_rx,
     
    164171int _sys_thread_id();
    165172
    166 int _sys_procs_number( unsigned int  x,
    167                        unsigned int  y,
    168                        unsigned int* number );
     173int _sys_procs_number( unsigned int* x_size,
     174                       unsigned int* y_size,
     175                       unsigned int* nprocs );
    169176
    170177int _sys_vobj_get_vbase( char*         vspace_name,
Note: See TracChangeset for help on using the changeset viewer.