Ignore:
Timestamp:
Mar 27, 2015, 11:43:48 AM (9 years ago)
Author:
alain
Message:

1) Introducing support for external IRQs dynamic routing.
2) Simplifying the _v2p_translate() function.
3) Removing the generic IOC driver (integrated in the FAT library).

File:
1 edited

Legend:

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

    r494 r528  
    1111#include <hard_config.h>
    1212#include <utils.h>
     13#include <vmem.h>
    1314#include <tty0.h>
    1415#include <kernel_malloc.h>
     
    5253#endif
    5354
     55#if !defined(USE_PIC)
     56# error: You must define USE_PIC in the hard_config.h file
     57#endif
     58
    5459#if !defined(IDLE_TASK_INDEX)
    5560# error: You must define IDLE_TASK_INDEX in the ctx_handler.h file
     
    7277#endif
    7378
    74 
    75 
    76 // Distributed kernel heap descriptors array
    77 // __attribute__((section(".kdata")))
    78 // kernel_heap_t  kernel_heap[X_SIZE][Y_SIZE];
     79#if !defined(GIET_ISR_TYPE_MAX)
     80# error: You must define GIET_ISR_TYPE_MAX in the giet_config.h file
     81#endif
     82
     83#if !defined(GIET_ISR_CHANNEL_MAX)
     84# error: You must define GIET_ISR_CHANNEL_MAX in the giet_config.h file
     85#endif
     86
     87
     88////////////////////////////////////////////////////////////////////////////////
     89//       Global variables
     90////////////////////////////////////////////////////////////////////////////////
    7991
    8092// FAT internal representation for kernel code
    8193__attribute__((section(".kdata")))
    82 fat32_fs_t     fat      __attribute__((aligned(512)));
     94fat32_fs_t     _fat      __attribute__((aligned(512)));
    8395
    8496// array of page tables virtual addresses
    8597__attribute__((section(".kdata")))
    86 volatile unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX];
     98volatile unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX][X_SIZE][Y_SIZE];
    8799
    88100// array of page tables PTPR values (physical addresses >> 13)
    89101__attribute__((section(".kdata")))
    90 volatile unsigned int _ptabs_ptprs[GIET_NB_VSPACE_MAX];
     102volatile unsigned int _ptabs_ptprs[GIET_NB_VSPACE_MAX][X_SIZE][Y_SIZE];
    91103
    92104// Array of pointers on the schedulers
    93105__attribute__((section(".kdata")))
    94 volatile static_scheduler_t*    _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
     106volatile static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
    95107
    96108// Synchonisation before entering parallel execution
     
    102114unsigned int   _tty0_boot_mode = 0;
    103115
    104 // Distributed synchronisation barrier for parallel init by all processors     
     116// synchronisation barrier for parallel init by all processors     
    105117__attribute__((section(".kdata")))
    106118sqt_barrier_t  _all_procs_barrier  __attribute__((aligned(64)));
    107119
    108 
     120////////////////////////////////////////////////////////////////////////////////
     121//      Extern variables
     122////////////////////////////////////////////////////////////////////////////////
    109123
    110124// this variable is defined in tty0.c file
    111125extern sqt_lock_t _tty0_sqt_lock;
    112126
    113 
    114 
    115 ///////////////////////////////////////////////////////////////////////////////////
    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.
     127////////////////////////////////////////////////////////////////////////////////
     128// This kernel_init() function completes the kernel initialisation in 6 steps:
     129// Step 0 is done by processor[0,0,0]. Steps 1 to 4 are executed in parallel
     130// by all processors.
     131// - step 0 : P[0,0,0] Initialise various global variables.
    120132// - step 1 : Each processor initialises scheduler pointers array.
    121133// - 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.
    126 ///////////////////////////////////////////////////////////////////////////////////
     134// - step 3 : Each processor initialise idle task and starts TICK timer.
     135// - step 4 : Each processor set sp, sr, ptpr, epc registers values.
     136////////////////////////////////////////////////////////////////////////////////
    127137__attribute__((section (".kinit"))) void kernel_init()
    128138{
    129139    // 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 )
     140    // x,y,p : proc coordinates ( x < X_SIZE / y < Y_SIZE / p < NB_PROCS_MAX )
    131141
    132142    unsigned int gpid       = _get_procid();
     
    137147
    138148    ////////////////////////////////////////////////////////////////////////////
    139     // Step 0 : P[0,0,0] initialises various structures
     149    // Step 0 : P[0,0,0] initialises various global vaiables
     150    ////////////////////////////////////////////////////////////////////////////
    140151
    141152    if ( gpid == 0 )
    142153    {
    143         // distributed kernel heaps
     154        // distributed kernel heap initialisation
    144155        _heap_init();
    145156       
    146157#if GIET_DEBUG_INIT
    147 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel HEAP init\n", x, y, p );
    148 #endif
    149         // kernel FAT
    150         _fat_init( IOC_BOOT_MODE );
    151 
    152 #if GIET_DEBUG_INIT
    153 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel FAT init\n", x, y, p );
     158_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel HEAP init\n",
     159               x, y, p );
    154160#endif
    155161        // distributed lock for TTY0
     
    167173               x , y , p );
    168174#endif
     175
     176#if USE_PIC
     177
     178        // _ext_irq_index[isr][channel] initialisation
     179        _ext_irq_init();
     180
     181        // routing HBA IRQ to proc[0,0,0] EXT_IRQ_ONE
     182        unsigned int unused = 0;
     183        if ( USE_IOC_HBA ) _ext_irq_alloc( ISR_HBA , 0 , &unused );
     184
     185#if GIET_DEBUG_INIT
     186_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes ext_irq init\n",
     187               x , y , p );
     188#endif
     189
     190#endif // USE_PIC
    169191
    170192        // release other processors
     
    176198    }
    177199
    178     ///////////////////////////////////////////////////////////////////
     200    ///////////////////////////////////////////////////////////////////////////
    179201    // Step 1 : each processor get its scheduler vaddr from CP0_SCHED,
    180202    //          contributes to _schedulers[] array initialisation,
    181203    //          and wait completion of array initialisation.
     204    ///////////////////////////////////////////////////////////////////////////
    182205
    183206    static_scheduler_t* psched     = (static_scheduler_t*)_get_sched();
     
    193216#endif
    194217
     218    /////////////////////////////////////////
    195219    _sqt_barrier_wait( &_all_procs_barrier );   
     220    /////////////////////////////////////////
    196221
    197222    ////////////////////////////////////////////////////////////////////////////
    198223    // step 2 : each processor that is allocated at least one task loops
    199     //          on all allocated tasks:
    200     //          - contributes to _ptabs_vaddr[] & _ptabs_ptprs[] initialisation.
     224    //          on its allocated tasks:
     225    //          - contributes to _ptabs_vaddr[][][] & _ptabs_ptprs[][][]
     226    //            initialisation, from values stored in the tasks contexts.
    201227    //          - set CTX_RA slot  with the kernel _ctx_eret() virtual address.
    202228    //          - set CTX_EPC slot that must contain the task entry point,
    203     //            and contain only at this point the virtual address of the memory
    204     //            location containing this entry point.
     229    //            and contain only at this point the virtual address of the
     230    //            memory slot containing this entry point.
     231    ////////////////////////////////////////////////////////////////////////////
    205232
    206233    unsigned int ltid;
     
    213240
    214241        // initialize PTABS arrays
    215         _ptabs_vaddr[vsid] = ptab;
    216         _ptabs_ptprs[vsid] = ptpr;
    217 
    218 #if GIET_DEBUG_INIT
    219 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises PTABS arrays\n"
    220         " - ptabs_vaddr[%d] = %x / ptpr_paddr[%d] = %l\n",
    221         x, y, p, 
    222         vsid, ptab, vsid, ((unsigned long long)ptpr)<<13 );
    223 #endif
    224 
    225         // set the ptpr to use the task page table
    226         asm volatile( "mtc2    %0,   $0   \n"
     242        _ptabs_vaddr[vsid][x][y] = ptab;
     243        _ptabs_ptprs[vsid][x][y] = ptpr;
     244
     245        // set the ptpr to use the local page table
     246        asm volatile( "mtc2    %0,   $0"
    227247                      : : "r" (ptpr) );
    228248
     
    232252
    233253        // compute ctx_epc
    234         unsigned int* ptr = (unsigned int*)_get_task_slot( x, y, p, ltid, CTX_EPC_ID );
    235         _set_task_slot( x, y, p, ltid, CTX_EPC_ID, *ptr );
    236 
    237 #if GIET_DEBUG_INIT
    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,
     254        unsigned int* ptr = (unsigned int*)_get_task_slot(x,y,p,ltid,CTX_EPC_ID);
     255        _set_task_slot(x,y,p,ltid,CTX_EPC_ID,*ptr);
     256
     257#if GIET_DEBUG_INIT
     258_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises PTABS arrays"
     259        " and context for task %d \n"
     260        " - ptabs_vaddr[%d][%d][%d] = %x\n"
     261        " - ptabs_paddr[%d][%d][%d] = %l\n"
     262        " - ctx_epc              = %x\n"
     263        " - ctx_ra               = %x\n",
     264        x , y , p , ltid , 
     265        vsid , x , y , ptab ,
     266        vsid , x , y , ((unsigned long long)ptpr)<<13 ,
    242267        _get_task_slot( x, y, p, ltid, CTX_EPC_ID ),
    243268        _get_task_slot( x, y, p, ltid, CTX_RA_ID ) );
     
    246271    }  // end for tasks
    247272
     273    /////////////////////////////////////////
    248274    _sqt_barrier_wait( &_all_procs_barrier );   
    249 
    250     ////////////////////////////////////////////////////////////////////////////
    251     // step 3 : compute and set XCU masks for HWI / PTI / WTI interrupts
    252 
    253     unsigned int isr_switch_index = 0xFFFFFFFF;
    254     unsigned int hwi_mask = 0;
    255     unsigned int pti_mask = 0;
    256     unsigned int wti_mask = 0;
    257     unsigned int irq_id;            // IN_IRQ index
    258     unsigned int entry;             // interrupt vector entry
    259 
    260     for (irq_id = 0; irq_id < 32; irq_id++)
     275    /////////////////////////////////////////
     276
     277    ////////////////////////////////////////////////////////////////////////////
     278    // step 3 : - Each processor complete idle task context initialisation,
     279    //            (only the CTX_SP, CTX_RA, CTX_EPC slot, because the CTX_PTPR
     280    //            and CTX_PTAB slots have been initialised in boot code)
     281    //            The 4 Kbytes idle stack is implemented in the scheduler itself.
     282    //          - Each processor starts TICK timer, as soon as at least one task
     283    //            is allocated.
     284    //          - P[0,0,0] initialises FAT (not done before, because it must
     285    //            be done after the _ptabs_vaddr[v][x][y] array initialisation,
     286    //            for V2P translation in _fat_ioc_access() function).
     287    ////////////////////////////////////////////////////////////////////////////
     288
     289    unsigned int sp  = ((unsigned int)psched) + 0x2000;
     290    unsigned int ra  = (unsigned int)(&_ctx_eret);
     291    unsigned int epc = (unsigned int)(&_idle_task);
     292
     293    _set_task_slot( x , y , p , IDLE_TASK_INDEX , CTX_SP_ID  , sp  );
     294    _set_task_slot( x , y , p , IDLE_TASK_INDEX , CTX_RA_ID  , ra  );
     295    _set_task_slot( x , y , p , IDLE_TASK_INDEX , CTX_EPC_ID , epc );
     296
     297    if (tasks > 0) _xcu_timer_start( cluster_xy, p, GIET_TICK_VALUE );
     298
     299#if GIET_DEBUG_INIT
     300_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initializes idle_task and starts TICK\n", 
     301        x, y, p );
     302#endif
     303
     304    if ( gpid == 0 )
    261305    {
    262         entry = psched->hwi_vector[irq_id];
    263         if ( entry & 0x80000000 ) hwi_mask = hwi_mask | (1<<irq_id);
    264         if ( (entry & 0x0000FFFF) == ISR_TICK ) isr_switch_index = irq_id;
    265 
    266         entry = psched->pti_vector[irq_id];
    267         if ( entry & 0x80000000 ) pti_mask = pti_mask | (1<<irq_id);
    268         if ( (entry & 0x0000FFFF) == ISR_TICK ) isr_switch_index = irq_id;
    269 
    270         entry = psched->wti_vector[irq_id];
    271         if ( entry & 0x80000000 ) wti_mask = wti_mask | (1<<irq_id);
    272         if ( (entry & 0x0000FFFF) == ISR_TICK ) isr_switch_index = irq_id;
     306         _fat_init( 0 );   // no IRQ
     307
     308#if GIET_DEBUG_INIT
     309_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel FAT init\n",
     310        x, y, p );
     311#endif
     312
    273313    }
    274314
    275 #if GIET_DEBUG_INIT
    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 );
    284 #endif
    285 
    286     unsigned int channel = p * IRQ_PER_PROCESSOR;
    287 
    288     _xcu_set_mask( cluster_xy, channel, hwi_mask, IRQ_TYPE_HWI );
    289     _xcu_set_mask( cluster_xy, channel, wti_mask, IRQ_TYPE_WTI );
    290     _xcu_set_mask( cluster_xy, channel, pti_mask, IRQ_TYPE_PTI );
    291 
    292     ////////////////////////////////////////////////////////////////////////////
    293     // step 4 : Each processor start TICK timer if at least one task
    294 
    295     if (tasks > 0)
    296     {
    297         // one ISR_TICK must be defined for each proc
    298         if (isr_switch_index == 0xFFFFFFFF)
    299         {
    300             _printf("\n[GIET ERROR] ISR_TICK not found for processor[%d,%d,%d]\n",
    301                            x, y, p );
    302             _exit();
    303         }
    304 
    305         // start system timer
    306         _xcu_timer_start( cluster_xy, isr_switch_index, GIET_TICK_VALUE );
    307 
    308     }
    309 
    310 #if GIET_DEBUG_INIT
    311 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] starts TICK timer\n",
    312         x, y, p );
    313 #endif
    314 
    315     ////////////////////////////////////////////////////////////////////////////
    316     // step 5 : each processor updates the idle_task context:
    317     //          (CTX_SP, CTX_RA, CTX_EPC).
    318     //          The 4 Kbytes idle stack is implemented in the scheduler.
    319     //          The PTPR register, the CTX_PTPR and CTX_PTAB slots
    320     //          have been initialised in boot code.
    321 
    322     unsigned int pstack = ((unsigned int)psched) + 0x2000;
    323 
    324     _set_task_slot( x, y, p, IDLE_TASK_INDEX, CTX_SP_ID,  pstack);
    325     _set_task_slot( x, y, p, IDLE_TASK_INDEX, CTX_RA_ID,  (unsigned int) &_ctx_eret);
    326     _set_task_slot( x, y, p, IDLE_TASK_INDEX, CTX_EPC_ID, (unsigned int) &_idle_task);
    327 
    328 #if GIET_DEBUG_INIT
    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 
     315    /////////////////////////////////////////
    335316    _sqt_barrier_wait( &_all_procs_barrier );   
    336 
    337     ////////////////////////////////////////////////////////////////////////////
    338     // step 6 : Each processor compute values for registers SP, SR, PTPR, EPC,
     317    /////////////////////////////////////////
     318
     319    ////////////////////////////////////////////////////////////////////////////
     320    // step 4 : Each processor compute values for registers SP, SR, PTPR, EPC,
    339321    //          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)
    343     {
    344         ltid = IDLE_TASK_INDEX;
    345         _printf("\n[GIET WARNING] No task allocated to processor[%d,%d,%d]\n",
    346                 x, y, p );
    347     }
    348     else
    349     {
    350         ltid = 0;
    351     }
     322    //          and jumps to user code.
     323    ////////////////////////////////////////////////////////////////////////////
     324
     325    if (tasks == 0) _printf("\n[GIET WARNING] No task allocated to P[%d,%d,%d]\n",
     326                            x, y, p );
     327
     328    if (tasks == 0) ltid = IDLE_TASK_INDEX;
     329    else            ltid = 0;
    352330
    353331    unsigned int sp_value   = _get_task_slot( x, y, p, ltid, CTX_SP_ID);
     
    356334    unsigned int epc_value  = _get_task_slot( x, y, p, ltid, CTX_EPC_ID);
    357335
    358     _sqt_barrier_wait( &_all_procs_barrier );
    359 
    360336#if GIET_DEBUG_INIT
    361337_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",
    363         x, y, p, _get_proctime(),
    364         sp_value, sr_value, ptpr_value, epc_value );
     338        " ltid = %d / sp = %x / sr = %x / ptpr = %x / epc = %x\n",
     339        x , y , p , _get_proctime() ,
     340        ltid , sp_value , sr_value , ptpr_value , epc_value );
    365341#endif
    366342
Note: See TracChangeset for help on using the changeset viewer.