Changeset 528


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).

Location:
soft/giet_vm/giet_kernel
Files:
8 edited

Legend:

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

    r459 r528  
    88#include <ctx_handler.h>
    99#include <giet_config.h>
     10#include <hard_config.h>
    1011#include <utils.h>
    1112#include <tty0.h>
    1213#include <xcu_driver.h>
    1314
    14 ////////// defined in giet_kernel/switch.s file /////////
     15/////////////////////////////////////////////////////////////////////////////////
     16//     Extern variables and functions
     17/////////////////////////////////////////////////////////////////////////////////
     18
     19// defined in giet_kernel/switch.s file
    1520extern void _task_switch(unsigned int *, unsigned int *);
     21
     22// allocated in boot.c or kernel_init.c files
     23extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
     24
     25//////////////////////////////////
     26void _ctx_display( unsigned int x,
     27                   unsigned int y,
     28                   unsigned int p,
     29                   unsigned int ltid,
     30                   char*        string )
     31{
     32    static_scheduler_t* psched = _schedulers[x][y][p];
     33    _printf("\n########## task[%d,%d,%d,%d] context\n"
     34            " - CTX_EPC   = %x\n"
     35            " - CTX_PTAB  = %x\n"
     36            " - CTX_PTPR  = %x\n"
     37            " - CTX_VSID  = %x\n"
     38            " - CTX_SR    = %x\n"
     39            " - CTX_RA    = %x\n"
     40            " - CTX_SP    = %x\n"
     41            " - CTX_RUN   = %x\n"
     42            "########## %s\n",
     43            x , y , p , ltid ,
     44            psched->context[ltid][CTX_EPC_ID],
     45            psched->context[ltid][CTX_PTAB_ID],
     46            psched->context[ltid][CTX_PTPR_ID],
     47            psched->context[ltid][CTX_VSID_ID],
     48            psched->context[ltid][CTX_SR_ID],
     49            psched->context[ltid][CTX_RA_ID],
     50            psched->context[ltid][CTX_SP_ID],
     51            psched->context[ltid][CTX_RUN_ID],
     52            string );
     53}  // _ctx_display()
     54
    1655
    1756//////////////////
     
    4887
    4988    // launch "idle" task if no runable task
    50     if (found == 0)
    51     {
    52         next_task_id = IDLE_TASK_INDEX;
    53     }
     89    if (found == 0) next_task_id = IDLE_TASK_INDEX;
    5490
    5591#if GIET_DEBUG_SWITCH
    5692unsigned int x = cluster_xy >> Y_WIDTH;
    5793unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    58 
    59 _printf("\n[TASK SWITCH] (%d) -> (%d) on processor[%d,%d,%d] at cycle %d\n",
     94_printf("\n[DEBUG SWITCH] (%d) -> (%d) on processor[%d,%d,%d] at cycle %d\n",
    6095        curr_task_id, next_task_id, x, y , lpid, _get_proctime() );
    6196#endif
     
    66101        unsigned int* next_ctx_vaddr = &(psched->context[next_task_id][0]);
    67102
    68         // reset timer counter.
    69         // In all clusters, the first NB_PROCS_MAX
    70         // timers are system timers (TICK)
    71 
    72 #if USE_XCU
     103        // reset TICK timer counter.
    73104        _xcu_timer_reset_cpt( cluster_xy, lpid );
    74 #else
    75         _timer_reset_cpt( cluster_xy, lpid);
    76 #endif
    77105
    78106        // set current task index
     
    80108
    81109        // makes context switch
    82         _task_switch(curr_ctx_vaddr, next_ctx_vaddr);
     110        _task_switch( curr_ctx_vaddr , next_ctx_vaddr );
     111
    83112    }
    84113} //end _ctx_switch()
     114
    85115
    86116/////////////////
     
    110140
    111141        // warning message
    112         _puts("\n[GIET WARNING] Processor[");
    113         _putd( x );
    114         _puts(",");
    115         _putd( y );
    116         _puts(",");
    117         _putd( p );
    118         _puts("] still idle at cycle ");
    119         _putd( _get_proctime() );
    120         _puts("\n");
     142        _printf("\n[GIET WARNING] Processor[%d,%d,%d] still idle at cycle %d",
     143                x , y , p , _get_proctime() );
    121144    }
    122145} // end ctx_idle()
  • soft/giet_vm/giet_kernel/ctx_handler.h

    r449 r528  
    1 /////////////////////////////////////////////////////////////////////////////////////////
     1/////////////////////////////////////////////////////////////////////////////////
    22// File     : ctx_handler.h
    33// Date     : 01/04/2012
    44// Authors  : alain greiner & joel porquet
    55// Copyright (c) UPMC-LIP6
    6 /////////////////////////////////////////////////////////////////////////////////////////
     6/////////////////////////////////////////////////////////////////////////////////
    77// The ctx_handler.h and ctx_handler.c files are part of the GIET-VM nano-kernel.
    88// This code is used to support context switch when several tasks are executing
     
    1313// The task context [13] is reserved for the "idle" task that does nothing, and
    1414// is launched by the scheduler when there is no other runable task.
    15 /////////////////////////////////////////////////////////////////////////////////////////
     15/////////////////////////////////////////////////////////////////////////////////
    1616// A task context is an array of 64 words = 256 bytes.
    1717// It contains copies of processor registers (when the task is preempted)
    1818// and some general informations associated to a task, such as the peripherals
    19 // allocated to the task (private peripheral channel for multi-channels peripherals).
    20 /////////////////////////////////////////////////////////////////////////////////////////
     19// allocated to the task (private peripheral channel)
     20/////////////////////////////////////////////////////////////////////////////////
    2121// ctx[0] <- ***   |ctx[8] <- $8     |ctx[16]<- $16   |ctx[24]<- $24
    2222// ctx[1] <- $1    |ctx[9] <- $9     |ctx[17]<- $17   |ctx[25]<- $25
     
    3636// ctx[38]<- VSID  |ctx[46]<- TIM    |ctx[54]<- ***   |ctx[62]<- ***
    3737// ctx[39]<- PTPR  |ctx[47]<- HBA    |ctx[55]<- ***   |ctx[63]<- ***
    38 /////////////////////////////////////////////////////////////////////////////////////////
     38/////////////////////////////////////////////////////////////////////////////////
    3939
    4040#ifndef _CTX_HANDLER_H
     
    9494
    9595/////////////////////////////////////////////////////////////////////////////////
    96 //                 Schedulers array
    97 /////////////////////////////////////////////////////////////////////////////////
    98 extern static_scheduler_t _scheduler[];
    99 
    100 /////////////////////////////////////////////////////////////////////////////////
    101 //               External Functions
     96//               Extern Functions
    10297/////////////////////////////////////////////////////////////////////////////////
    10398
     
    126121extern void _idle_task();
    127122
     123/////////////////////////////////////////////////////////////////////////////////
     124// This function displays the context of a task identified by the processor
     125// coordinates (x,y,p), and by the local task index ltid.
     126// The string argument can be used for debug.
     127/////////////////////////////////////////////////////////////////////////////////
     128extern void _ctx_display( unsigned int x,
     129                          unsigned int y,
     130                          unsigned int p,
     131                          unsigned int ltid,
     132                          char*        string );
    128133
    129134#endif
  • soft/giet_vm/giet_kernel/exc_handler.c

    r459 r528  
    7676    unsigned int task       = _get_context_slot(CTX_LTID_ID);
    7777
     78
    7879    _printf("\n[GIET] Exception for task %d on processor[%d,%d,%d] at cycle %d\n"
    7980            " - type      : %s\n"
     
    8788    _set_context_slot(CTX_RUN_ID, 0);
    8889
    89     // deschedule
     90    // deschedule (suicide)
     91    unsigned int save_sr;  // unused
     92    _it_disable( &save_sr );
    9093    _ctx_switch();
    91 }
     94
     95}  // end display_cause()
    9296
    9397static void _cause_ukn()  { _display_cause(0); }
  • soft/giet_vm/giet_kernel/irq_handler.c

    r519 r528  
    1 ///////////////////////////////////////////////////////////////////////////////////
     1///////////////////////////////////////////////////////////////////////////
    22// File     : irq_handler.c
    33// Date     : 01/04/2012
    44// Author   : alain greiner
    55// Copyright (c) UPMC-LIP6
    6 ///////////////////////////////////////////////////////////////////////////////////
     6///////////////////////////////////////////////////////////////////////////
    77
    88#include <giet_config.h>
     
    1212#include <tim_driver.h>
    1313#include <xcu_driver.h>
     14#include <pic_driver.h>
    1415#include <tty_driver.h>
    1516#include <nic_driver.h>
     
    1920#include <dma_driver.h>
    2021#include <spi_driver.h>
     22#include <mwr_driver.h>
    2123#include <mapping_info.h>
    2224#include <utils.h>
    2325#include <tty0.h>
    2426
    25 #if NB_TIM_CHANNELS
    26 extern volatile unsigned char _user_timer_event[NB_TIM_CHANNELS] ;
    27 #endif
     27/////////////////////////////////////////////////////////////////////////
     28//       Global variables
     29/////////////////////////////////////////////////////////////////////////
     30
     31// array of external IRQ indexes for each (isr/channel) couple
     32__attribute__((section(".kdata")))
     33unsigned char _ext_irq_index[GIET_ISR_TYPE_MAX][GIET_ISR_CHANNEL_MAX];
     34
     35// WTI mailbox allocators for external IRQ routing (3 allocators per proc)
     36__attribute__((section(".kdata")))
     37unsigned char _wti_alloc_one[X_SIZE][Y_SIZE][NB_PROCS_MAX];
     38__attribute__((section(".kdata")))
     39unsigned char _wti_alloc_two[X_SIZE][Y_SIZE][NB_PROCS_MAX];
     40__attribute__((section(".kdata")))
     41unsigned char _wti_alloc_ter[X_SIZE][Y_SIZE][NB_PROCS_MAX];
     42
     43/////////////////////////////////////////////////////////////////////////
     44// this array is allocated in the boot.c or kernel_init.c
     45/////////////////////////////////////////////////////////////////////////
     46
     47extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
    2848
    2949/////////////////////////////////////////////////////////////////////////
     
    4565                           "DMA"    ,
    4666                           "SPI"    ,
    47                            "MWR"    };
     67                           "MWR"    ,
     68                           "HBA"    };
     69
     70////////////////////
     71void _ext_irq_init()
     72{
     73    mapping_header_t*    header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     74    mapping_cluster_t*   cluster = _get_cluster_base(header);
     75    mapping_periph_t*    periph  = _get_periph_base(header);
     76    mapping_irq_t*       irq     = _get_irq_base(header);
     77    unsigned int         periph_id;   // peripheral index in mapping_info
     78    unsigned int         irq_id;      // irq index in mapping_info
     79
     80    // get cluster_io index in mapping
     81    unsigned int         x_io       = header->x_io; 
     82    unsigned int         y_io       = header->y_io; 
     83    unsigned int         cluster_io = (x_io * Y_SIZE) + y_io;
     84    mapping_periph_t*    pic        = NULL;
     85
     86    // scan external peripherals to find XCU
     87    unsigned int min = cluster[cluster_io].periph_offset ;
     88    unsigned int max = min + cluster[cluster_io].periphs ;
     89   
     90    for ( periph_id = min ; periph_id < max ; periph_id++ )
     91    {
     92        if ( periph[periph_id].type == PERIPH_TYPE_PIC )
     93        {
     94            pic = &periph[periph_id];
     95            break;
     96        }
     97    } 
     98
     99    if ( pic == NULL )
     100    {
     101        _printf("\n[GIET ERROR] in _ext_irq_init() : No PIC component found\n");
     102        _exit();
     103    }
     104
     105    // scan PIC IRQS defined in mapping
     106    for ( irq_id = pic->irq_offset ;
     107          irq_id < pic->irq_offset + pic->irqs ;
     108          irq_id++ )
     109    {
     110        unsigned int type    = irq[irq_id].srctype;
     111        unsigned int srcid   = irq[irq_id].srcid;
     112        unsigned int isr     = irq[irq_id].isr;
     113        unsigned int channel = irq[irq_id].channel;
     114
     115        if ( (type != IRQ_TYPE_HWI)            ||
     116             (srcid > 31)                      ||
     117             (isr >= GIET_ISR_TYPE_MAX)        ||
     118             (channel >= GIET_ISR_CHANNEL_MAX) )
     119        {
     120            _printf("\n[GIET ERROR] in _ext_irq_init() : Bad PIC IRQ\n"
     121                    "  type = %d / srcid = %d / isr = %d / channel = %d\n",
     122                    type , srcid , isr , channel );
     123            _exit();
     124        }
     125        _ext_irq_index[isr][channel] = srcid;
     126    }
     127}  // end _ext_irq_init()
     128
     129////////////////////////////////////////////
     130void _ext_irq_alloc( unsigned int   isr_type,
     131                     unsigned int   isr_channel,
     132                     unsigned int*  wti_index )
     133{
     134    unsigned int wti_id;        // allocated WTI mailbox index in XCU
     135    unsigned int irq_id;        // external IRQ index in PIC (input)
     136    unsigned int wti_addr;      // WTI mailbox physical address (32 lsb bits)
     137
     138    // check arguments
     139    if ( isr_type >= GIET_ISR_TYPE_MAX )
     140    {
     141        _printf("\n[GIET ERROR] in _ext_irq_alloc() : illegal ISR type\n");
     142        _exit();
     143    }
     144    if ( isr_channel >= GIET_ISR_CHANNEL_MAX )
     145    {
     146        _printf("\n[GIET ERROR] in _ext_irq_alloc() : illegal ISR channel\n");
     147        _exit();
     148    }
     149
     150    // get processor coordinates [x,y,p]
     151    unsigned int gpid           = _get_procid();
     152    unsigned int cluster_xy     = gpid >> P_WIDTH;
     153    unsigned int x              = cluster_xy >> Y_WIDTH;
     154    unsigned int y              = cluster_xy & ((1<<Y_WIDTH)-1);
     155    unsigned int p              = gpid & ((1<<P_WIDTH)-1);
     156
     157    // allocate a WTI mailbox to proc[x,y,p] (blocking until success)
     158    while ( 1 )
     159    {
     160        if ( _wti_alloc_one[x][y][p] == 0 )
     161        {
     162            _wti_alloc_one[x][y][p] = 1;
     163            wti_id = p + NB_PROCS_MAX;
     164            break;
     165        }
     166        if ( _wti_alloc_two[x][y][p] == 0 )
     167        {
     168            _wti_alloc_two[x][y][p] = 1;
     169            wti_id = p + 2*NB_PROCS_MAX;
     170            break;
     171        }
     172        if ( _wti_alloc_ter[x][y][p] == 0 )
     173        {
     174            _wti_alloc_ter[x][y][p] = 1;
     175            wti_id = p + 3*NB_PROCS_MAX;
     176            break;
     177        }
     178    }   
     179    *wti_index = wti_id;
     180
     181    // register the mailbox physical address in IOPIC
     182    irq_id   = _ext_irq_index[isr_type][isr_channel];
     183    _xcu_get_wti_address( wti_id , &wti_addr );
     184    _pic_init( irq_id , wti_addr, cluster_xy );
     185   
     186    // initializes the WTI interrupt vector entry for XCU
     187    _schedulers[x][y][p]->wti_vector[wti_id] = isr_channel<<16 | isr_type;
     188
     189}  // end ext_irq_alloc()
     190
     191////////////////////////////////////////////
     192void _ext_irq_release( unsigned int isr_type,
     193                       unsigned int isr_channel,
     194                       unsigned int wti_index )
     195{
     196    unsigned int irq_id;        // external IRQ index in PIC (input)
     197
     198    // get processor coordinates [x,y,p]
     199    unsigned int gpid           = _get_procid();
     200    unsigned int cluster_xy     = gpid >> P_WIDTH;
     201    unsigned int x              = cluster_xy >> Y_WIDTH;
     202    unsigned int y              = cluster_xy & ((1<<Y_WIDTH)-1);
     203    unsigned int p              = gpid & ((1<<P_WIDTH)-1);
     204
     205    // check arguments
     206    if ( isr_type >= GIET_ISR_TYPE_MAX )
     207    {
     208        _printf("\n[GIET ERROR] in _ext_irq_release() illegal ISR type\n");
     209        _exit();
     210    }
     211    if ( isr_channel >= GIET_ISR_CHANNEL_MAX )
     212    {
     213        _printf("\n[GIET ERROR] in _ext_irq_release() : illegal ISR channel\n");
     214        _exit();
     215    }
     216
     217    // desactivates dynamically allocated PIC entry
     218    irq_id = _ext_irq_index[isr_type][isr_channel];
     219    _pic_set_register( irq_id , IOPIC_MASK , 0 );
     220
     221    // releases dynamically allocated WTI mailbox
     222    if      ( wti_index == p +   NB_PROCS_MAX ) _wti_alloc_one[x][y][p] = 0;
     223    else if ( wti_index == p + 2*NB_PROCS_MAX ) _wti_alloc_two[x][y][p] = 0;
     224    else if ( wti_index == p + 3*NB_PROCS_MAX ) _wti_alloc_ter[x][y][p] = 0;
     225    else
     226    {
     227        _printf("\n[GIET ERROR] in _ext_irq_release() : illegal WTI index\n");
     228        _exit();
     229    }
     230}  // end ext_irq_release()
     231
    48232/////////////////
    49233void _irq_demux()
     
    156340    unsigned int x          = cluster_xy >> Y_WIDTH;
    157341    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    158     unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
    159 
    160     unsigned int task       = _get_current_task_id();
    161     unsigned int value;
     342    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
     343
     344    unsigned int value;     // WTI mailbox value
     345    unsigned int save_sr;   // save SR value in pre-empted task stack
     346
     347    unsigned int ltid       = _get_current_task_id();
    162348
    163349    if ( irq_type != IRQ_TYPE_WTI )
    164350    {
    165         _puts("[GIET ERROR] _isr_wakup() not called by a WTI on processor[");
    166         _putd( x );
    167         _puts(",");
    168         _putd( y );
    169         _puts(",");
    170         _putd( lpid );
    171         _puts("] at cycle ");
    172         _putd( _get_proctime() );
    173         _puts("\n");
     351        _printf("[GIET ERROR] P[%d,%d,%d] enters _isr_wakup() at cycle %d\n"
     352                " but not called by a WTI interrupt\n",
     353                x , y , p , _get_proctime() );
    174354        _exit();
    175355    }
     
    178358    _xcu_get_wti_value( cluster_xy, irq_id, &value );
    179359
    180 #if GIET_DEBUG_IRQS // we don't take the TTY lock to avoid deadlocks
    181 _puts("\n[IRQS DEBUG] Processor[");
    182 _putd( x );
    183 _puts(",");
    184 _putd( y );
    185 _puts(",");
    186 _putd( lpid );
    187 _puts("] enters _isr_wakup() at cycle ");
    188 _putd( _get_proctime() );
    189 _puts("\n  WTI / mailbox data = ");
    190 _putx( value );
    191 _puts(" / current task index = ");
    192 _putd( task );
    193 _puts("\n  ");
     360#if GIET_DEBUG_SWITCH
     361_printf("\n[DEBUG SWITCH] P[%d,%d,%d] enters _isr_wakup() at cycle %d\n"
     362        "  WTI index = %d / current ltid = %d / mailbox value = %x\n",
     363        x , y , p , _get_proctime() , irq_id , ltid , value );
    194364#endif
    195365
    196     // context swich if required
    197     if ( (task == IDLE_TASK_INDEX) || (value != 0) ) _ctx_switch();
     366    // enter critical section and swich context (if required)
     367    if ( (ltid == IDLE_TASK_INDEX) || (value != 0) )
     368    {
     369        _it_disable( &save_sr );
     370        _ctx_switch();
     371        _it_restore( &save_sr );
     372    }
     373
    198374} // end _isr_wakup
    199375
     
    207383    unsigned int x          = cluster_xy >> Y_WIDTH;
    208384    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    209     unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
     385    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
     386
     387    unsigned int save_sr;   // save SR value in pre-empted task stack
    210388
    211389    if ( irq_type != IRQ_TYPE_PTI )
    212390    {
    213         _puts("[GIET ERROR] _isr_tick() not called by a PTI on processor[");
    214         _putd( x );
    215         _puts(",");
    216         _putd( y );
    217         _puts(",");
    218         _putd( lpid );
    219         _puts("] at cycle ");
    220         _putd( _get_proctime() );
    221         _puts("\n");
     391        _printf("[GIET ERROR] P[%d,%d,%d] enters _isr_tick() at cycle %d\n"
     392                " but not called by a PTI interrupt\n",
     393                x , y , p , _get_proctime() );
    222394        _exit();
    223395    }
     
    226398    _xcu_timer_reset_irq( cluster_xy, irq_id );
    227399
    228 #if GIET_DEBUG_IRQS  // we don't take the TTY lock to avoid deadlock
    229 _puts("\n[IRQS DEBUG] Processor[");
    230 _putd( x );
    231 _puts(",");
    232 _putd( y );
    233 _puts(",");
    234 _putd( lpid );
    235 _puts("] enters _isr_tick() at cycle ");
    236 _putd( _get_proctime() );
    237 _puts("\n  ");
     400#if GIET_DEBUG_SWITCH
     401unsigned int ltid  = _get_current_task_id();
     402_printf("\n[DEBUG SWITCH] P[%d,%d,%d] enters _isr_tick() at cycle %d\n"
     403        "  WTI index = %d / current ltid = %d\n",
     404        x , y , p , _get_proctime() , irq_id , ltid );
    238405#endif
    239406
    240     // context switch
     407    // enter critical section and switch context
     408    _it_disable( &save_sr );
    241409    _ctx_switch();
     410    _it_restore( &save_sr );
     411
    242412}  // end _isr_tick
    243413
  • soft/giet_vm/giet_kernel/irq_handler.h

    r519 r528  
    1 ///////////////////////////////////////////////////////////////////////////////////
     1///////////////////////////////////////////////////////////////////////////
    22// File     : irq_handler.h
    33// Date     : 01/04/2012
    44// Author   : alain greiner
    55// Copyright (c) UPMC-LIP6
    6 ///////////////////////////////////////////////////////////////////////////////////
    7 // The irq_handler.c and irq_handler.h files are part of the GIET-VM nano-kernel.
    8 // They contain the code of the _irq_demux() function that access the XICU or
    9 // ICU component (Interupt Controler Unit), and the various ISRs (Interrupt
    10 // Service Routine) associated to the various ISR types.
    11 ///////////////////////////////////////////////////////////////////////////////////
     6///////////////////////////////////////////////////////////////////////////
     7// The irq_handler.c and irq_handler.h files are part of the GIET-VM.
     8// They contain the code of used to handlle HWI, WTI, PTI interrupts.
     9///////////////////////////////////////////////////////////////////////////
    1210
    1311#ifndef _IRQ_HANDLER_H
    1412#define _IRQ_HANDLER_H
    1513
    16 ////////////////////////////////////////////////////////////////////////////////
     14///////////////////////////////////////////////////////////////////////////
    1715// This enum must consistent with the values defined in
    18 // xml_driver.c / irq_handler.c / mapping.py
    19 ///////////////////////////////////////////////////////////////////////////////
     16// xml_driver.c / xml_parser.c / irq_handler.c / mapping.py
     17///////////////////////////////////////////////////////////////////////////
    2018
    2119enum isr_type_t
     
    3533    ISR_SPI     = 12,
    3634    ISR_MWR     = 13,
     35    ISR_HBA     = 14,
    3736};
    3837
    39 ///////////////////////////////////////////////////////////////////////////////////
     38///////////////////////////////////////////////////////////////////////////
     39//    Global variables allocated in irq_handler.c     
     40///////////////////////////////////////////////////////////////////////////
     41
     42// array of external IRQ indexes for each (isr/channel) couple
     43extern unsigned char _ext_irq_index[GIET_ISR_TYPE_MAX][GIET_ISR_CHANNEL_MAX];
     44
     45// WTI mailbox allocators for external IRQ routing (3 allocators per proc)
     46extern unsigned char _wti_alloc_one[X_SIZE][Y_SIZE][NB_PROCS_MAX];
     47extern unsigned char _wti_alloc_two[X_SIZE][Y_SIZE][NB_PROCS_MAX];
     48extern unsigned char _wti_alloc_ter[X_SIZE][Y_SIZE][NB_PROCS_MAX];
     49
     50///////////////////////////////////////////////////////////////////////////
    4051//    irq_handler functions
    41 ///////////////////////////////////////////////////////////////////////////////////
     52///////////////////////////////////////////////////////////////////////////
    4253
    43 ///////////////////////////////////////////////////////////////////////////////////
    44 // This function access the ICU or XICU component (Interrupt Controler Unit)
    45 // to get the interrupt vector entry. There is one ICU or XICU component per
     54///////////////////////////////////////////////////////////////////////////
     55// This function is only used when the architecture contains an external
     56// IOPIC component. It initializes the _ext_irq_index[isr][channel] array,
     57// defining the IRQ index associated to (isr_type/isr_channel) couple.
     58// This array is used by the kernel for dynamic routing of an external IRQ
     59// signaling completion to  the processor that launched the I/O operation.
     60///////////////////////////////////////////////////////////////////////////
     61
     62extern void _ext_irq_init();
     63
     64///////////////////////////////////////////////////////////////////////////
     65// This function is only used when the architecture contains an external
     66// IOPIC component. It dynamically routes an external IRQ signaling
     67// completion of an I/O operation to the processor P[x,y,p] running
     68// the calling task.
     69// 1) it allocates a WTI mailbox in the XCU of cluster[x,y] : Each processor
     70//    has 3  mailboxes, with index in [4*p+1, 4*p+2, 4*p+3].
     71// 2) it initialises the IOPIC_ADDRESS and IOPIC_MASK registers associated
     72//    to the (isr_type/isr_channel) couple.
     73// 3) it initializes the proper entry in the WTI interrupt vector associated
     74//    to processor P[x,y,p].
     75///////////////////////////////////////////////////////////////////////////
     76
     77extern void _ext_irq_alloc( unsigned int   isr_type,
     78                            unsigned int   isr_channel,
     79                            unsigned int*  wti_index );
     80                             
     81///////////////////////////////////////////////////////////////////////////
     82// This function is only used when the architecture contains an external
     83// IOPIC component. It desallocates all ressources allocated by the
     84// previous _ext_irq_alloc() function to the calling processor.
     85// 1)  it desactivates the PIC entry associated to (isr_type/isr_channel).
     86// 2) it releases the WTI mailbox in the XCU of cluster[x,y].
     87///////////////////////////////////////////////////////////////////////////
     88
     89extern void _ext_irq_release( unsigned int isr_type,
     90                              unsigned int isr_channel,
     91                              unsigned int wti_index );
     92
     93///////////////////////////////////////////////////////////////////////////
     94// This function access the XICU component (Interrupt Controler Unit)
     95// to get the interrupt vector entry. There is one XICU component per
    4696// cluster, and this component can support up to NB_PROCS_MAX output IRQs.
    4797// It returns the highest priority active interrupt index (smaller
    4898// indexes have the highest priority).
    49 // Any value larger than 31 means "no active interrupt", and no ISR is executed.
     99// Any value larger than 31 means "no active interrupt".
    50100//
    51101// There is three interrupt vectors per processor (stored in the processor's
    52102// scheduler) for the three HWI, PTI, and WTI interrupts types.
    53 // Each interrupt vector entry contains three bits fields:
    54 // - isr_id     bits[15:0]  : defines the type of ISR to be executed.
    55 // - channel_id bits[30:16] : defines the channel for multi-channels peripherals.
    56 // - valid      bit 31      : valid interrupt vector entry
     103// Each interrupt vector entry contains two fields:
     104// - isr_type     bits[15:0]  : defines the type of ISR to be executed.
     105// - isr_channel  bits[31:16] : defines the channel index
    57106// If the peripheral is replicated in clusters, the channel_id is
    58107// a global index : channel_id = cluster_id * NB_CHANNELS_MAX + loc_id   
    59 ///////////////////////////////////////////////////////////////////////////////////
     108///////////////////////////////////////////////////////////////////////////
     109
    60110extern void _irq_demux();
    61111
    62 ///////////////////////////////////////////////////////////////////////////////////
     112///////////////////////////////////////////////////////////////////////////
    63113// This default ISR is called  when the interrupt handler is called,
    64 // and there is no active IRQ. It simply displays a warning message on TTY[0].
    65 ///////////////////////////////////////////////////////////////////////////////////
     114// and there is no active IRQ. It displays a warning message on TTY[0].
     115///////////////////////////////////////////////////////////////////////////
     116
    66117extern void _isr_default();
    67118
    68 ///////////////////////////////////////////////////////////////////////////////////
    69 // This ISR can only be executed after a WTI (IPI) to force a context switch
    70 // on a remote processor. The context switch is only executed if the current task
    71 // is the IDLE_TASK, or if the value written in the mailbox is non zero.
    72 ///////////////////////////////////////////////////////////////////////////////////
     119///////////////////////////////////////////////////////////////////////////
     120// This ISR can only be executed after a WTI to force a context switch
     121// on a remote processor. The context switch is only executed if the
     122// current task is the IDLE_TASK, or if the value written in the mailbox
     123// is non zero.
     124///////////////////////////////////////////////////////////////////////////
     125
    73126extern void _isr_wakup( unsigned int irq_type,
    74127                        unsigned int irq_id,
  • 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
  • soft/giet_vm/giet_kernel/sys_handler.c

    r519 r528  
    6161#endif
    6262
    63 
    6463////////////////////////////////////////////////////////////////////////////
    65 //     Coprocessors loks and synchronisation variables
     64//        Extern variables
    6665////////////////////////////////////////////////////////////////////////////
    6766
    68 __attribute__((section(".kdata")))
    69 simple_lock_t  _coproc_lock[X_SIZE*Y_SIZE];
    70 
    71 __attribute__((section(".kdata")))
    72 unsigned int   _coproc_done[X_SIZE*Y_SIZE];
     67// allocated in tty0.c file.
     68extern sqt_lock_t _tty0_sqt_lock;
     69
     70// allocated in mwr_driver.c file.
     71extern simple_lock_t  _coproc_lock[X_SIZE*Y_SIZE];
     72extern unsigned int   _coproc_done[X_SIZE*Y_SIZE];
     73
     74// allocated in tty_driver.c file.
     75extern unsigned int _tty_rx_full[NB_TTY_CHANNELS];
     76extern unsigned int _tty_rx_buf[NB_TTY_CHANNELS];
    7377
    7478////////////////////////////////////////////////////////////////////////////
     
    9195__attribute__((section(".kdata")))
    9296unsigned int _nic_tx_channel_allocator = 0;
    93 
    94 ////////////////////////////////////////////////////////////////////////////
    95 // These global variables are allocated in tty0.c and tty_driver.c files.
    96 ////////////////////////////////////////////////////////////////////////////
    97 
    98 extern sqt_lock_t _tty0_sqt_lock;
    99 
    100 extern unsigned int _tty_rx_full[NB_TTY_CHANNELS];
    101 
    102 extern unsigned int _tty_rx_buf[NB_TTY_CHANNELS];
    10397
    10498////////////////////////////////////////////////////////////////////////////
     
    157151    &_sys_ukn,                  /* 0x17 */
    158152    &_sys_ukn,                  /* 0x18 */   
    159     &_context_switch,           /* 0x19 */
     153    &_sys_context_switch,       /* 0x19 */
    160154    &_sys_vseg_get_vbase,       /* 0x1A */
    161155    &_sys_vseg_get_length,      /* 0x1B */
     
    355349    unsigned int size = desc->buffer_size;
    356350 
    357     // these variables are used for the v2p translations
    358     unsigned int       ptab  = _get_context_slot(CTX_PTAB_ID);
    359     unsigned int       ppn;
    360     unsigned int       flags;
     351    // physical addresses
    361352    unsigned long long buffer_paddr;
    362353    unsigned int       buffer_lsb;
     
    369360    unsigned int       lock_msb;
    370361
     362    unsigned int       flags;     // unused
     363
    371364    // compute memory buffer physical address
    372     _v2p_translate( (page_table_t*)ptab,
    373                     desc->buffer_vaddr>>12,
    374                     &ppn,
    375                     &flags );
    376     buffer_paddr = (((unsigned long long)ppn) << 12) |
    377                    (desc->buffer_vaddr & 0x00000FFF);
    378     buffer_lsb = (unsigned int)buffer_paddr;
    379     buffer_msb = (unsigned int)(buffer_paddr>>32);
     365    buffer_paddr = _v2p_translate( desc->buffer_vaddr , &flags );
     366    buffer_lsb   = (unsigned int)buffer_paddr;
     367    buffer_msb   = (unsigned int)(buffer_paddr>>32);
    380368
    381369    // call MWMR_DMA driver
     
    385373    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_BUFFER_MSB, buffer_msb );
    386374                       
    387     // compute MWMR descriptor and lock physical addresses (if required)
    388375    if ( mode == MODE_MWMR )
    389376    {
    390         _v2p_translate( (page_table_t*)ptab,
    391                         desc->mwmr_vaddr>>12,
    392                         &ppn,
    393                         &flags );
    394         mwmr_paddr = (((unsigned long long)ppn) << 12) |
    395                      (desc->mwmr_vaddr & 0x00000FFF);
     377        // compute MWMR descriptor physical address
     378        mwmr_paddr = _v2p_translate( desc->mwmr_vaddr , &flags );
    396379        mwmr_lsb = (unsigned int)mwmr_paddr;
    397380        mwmr_msb = (unsigned int)(mwmr_paddr>>32);
    398 
    399         _v2p_translate( (page_table_t*)ptab,
    400                         desc->lock_vaddr>>12,
    401                         &ppn,
    402                         &flags );
    403         lock_paddr = (((unsigned long long)ppn) << 12) |
    404                      (desc->lock_vaddr & 0x00000FFF);
    405         lock_lsb = (unsigned int)lock_paddr;
    406         lock_msb = (unsigned int)(lock_paddr>>32);
    407381
    408382        // call MWMR_DMA driver
    409383        _mwr_set_channel_register( cluster_xy, channel, CHANNEL_MWMR_LSB, mwmr_lsb );
    410384        _mwr_set_channel_register( cluster_xy, channel, CHANNEL_MWMR_MSB, mwmr_msb );
     385
     386        // compute lock physical address
     387        lock_paddr = _v2p_translate( desc->lock_vaddr , &flags );
     388        lock_lsb = (unsigned int)lock_paddr;
     389        lock_msb = (unsigned int)(lock_paddr>>32);
     390
     391        // call MWMR_DMA driver
    411392        _mwr_set_channel_register( cluster_xy, channel, CHANNEL_LOCK_LSB, lock_lsb );
    412393        _mwr_set_channel_register( cluster_xy, channel, CHANNEL_LOCK_MSB, lock_msb );
     
    740721    unsigned long long ker_chbuf_pbase;     // kernel chbuf physical address
    741722
    742     // These variables are used for the various V2P translation
    743     unsigned int       ptab  = _get_context_slot(CTX_PTAB_ID);
    744     unsigned int       ppn;
    745     unsigned int       flags;
    746     unsigned int       vaddr;
    747 
    748723    // allocate one kernel container per cluster in the (xmax / ymax) mesh
    749     unsigned int        cx;              // cluster X coordinate
    750     unsigned int        cy;              // cluster Y coordinate
    751     unsigned int        index;           // container index in chbuf
    752     unsigned long long  cont_paddr;      // container physical address
     724    unsigned int        cx;                 // cluster X coordinate
     725    unsigned int        cy;                 // cluster Y coordinate
     726    unsigned int        index;              // container index in chbuf
     727    unsigned int        vaddr;              // virtual address
     728    unsigned long long  cont_paddr;         // container physical address
     729
     730    unsigned int        flags;              // for _v2p_translate()
    753731
    754732    for ( cx = 0 ; cx < xmax ; cx++ )
     
    770748
    771749            // compute container physical address
    772             _v2p_translate( (page_table_t*)ptab,
    773                             vaddr>>12,
    774                             &ppn,
    775                             &flags );
    776             cont_paddr = (((unsigned long long)ppn) << 12) | (vaddr & 0x00000FFF);
     750            cont_paddr = _v2p_translate( vaddr , &flags );
    777751
    778752            // initialize chbuf entry
     
    816790    if ( is_rx ) vaddr = (unsigned int)( &_nic_rx_chbuf[nic_channel] );
    817791    else         vaddr = (unsigned int)( &_nic_tx_chbuf[nic_channel] );
    818     _v2p_translate( (page_table_t*)ptab,
    819                      vaddr>>12,
    820                      &ppn,
    821                      &flags );
    822     ker_chbuf_pbase = (((unsigned long long)ppn) << 12) | (vaddr & 0x00000FFF);
     792
     793    ker_chbuf_pbase = _v2p_translate( vaddr , &flags );
    823794
    824795#if GIET_DEBUG_NIC
     
    965936    unsigned long long kernel_buffer_paddr;  // kernel buffer physical address
    966937    unsigned long long kernel_chbuf_paddr;   // kernel chbuf physical address
    967     unsigned long long buffer_desc;          // kernel buffer descriptor
    968     unsigned long long buffer_desc_paddr;    // kernel buffer descriptor physical address
     938    unsigned long long buffer_descriptor;    // kernel buffer descriptor
     939    unsigned long long buffer_desc_paddr;    // kernel buffer descriptor paddr
    969940    unsigned int       index;                // kernel buffer index in chbuf
    970 
    971     // The following variables are used for V2P translation
    972     unsigned int ptab = _get_context_slot( CTX_PTAB_ID );
    973     unsigned int ppn;
    974     unsigned int flags;
    975     unsigned int vaddr;
     941    unsigned int       flags;                // for _v2P_translate
    976942
    977943    // Compute user buffer physical address and check access rights
    978     vaddr = (unsigned int)buffer;
    979     _v2p_translate( (page_table_t*)ptab,
    980                      vaddr>>12,
    981                      &ppn,
    982                      &flags );
     944    user_buffer_paddr = _v2p_translate( (unsigned int)buffer , &flags );
    983945
    984946    if ( (flags & PTE_U) == 0 )
     
    987949        return -1;
    988950    }
    989     user_buffer_paddr = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF);
    990951
    991952#if GIET_DEBUG_NIC
     
    995956
    996957    // compute kernel chbuf physical address (required for sync)
    997     vaddr = (unsigned int)chbuf;
    998     _v2p_translate( (page_table_t*)ptab,
    999                      vaddr>>12,
    1000                      &ppn,
    1001                      &flags );
    1002     kernel_chbuf_paddr = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF);
     958    kernel_chbuf_paddr = _v2p_translate( (unsigned int)chbuf , &flags );
    1003959
    1004960    // poll local kernel container status until success
     
    1011967        // inval buffer descriptor in L2 before read in L2
    1012968        _mmc_inval( buffer_desc_paddr , 8 );
    1013         buffer_desc = chbuf->buffer[index].desc;
     969        buffer_descriptor = chbuf->buffer[index].desc;
    1014970
    1015971#if GIET_DEBUG_NIC
    1016972_printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_move() read buffer descriptor %d\n"
    1017973        " at cycle = %d / paddr = %l / buffer descriptor = %l\n",
    1018         thread, index, _get_proctime(), buffer_desc_paddr, buffer_desc );
     974        thread, index, _get_proctime(), buffer_desc_paddr, buffer_descriptor );
    1019975#endif
    1020976
    1021977        // test buffer status and break if found
    1022         if ( ( is_rx != 0 ) && (buffer_desc >> 63) == 1 )  break;
    1023         if ( ( is_rx == 0 ) && (buffer_desc >> 63) == 0 )  break;
     978        if ( ( is_rx != 0 ) && (buffer_descriptor >> 63) == 1 )  break;
     979        if ( ( is_rx == 0 ) && (buffer_descriptor >> 63) == 0 )  break;
    1024980    }
    1025981
    1026982    // compute kernel buffer physical address
    1027     kernel_buffer_paddr = buffer_desc & 0x0000FFFFFFFFFFFFULL;
     983    kernel_buffer_paddr = buffer_descriptor & 0x0000FFFFFFFFFFFFULL;
    1028984   
    1029985    // move one container
     
    12811237#if NB_CMA_CHANNELS > 0
    12821238
    1283     unsigned int       ptab;            // page table virtual address
    12841239    unsigned int       vaddr;           // virtual address
    1285     unsigned int       flags;           // protection flags
    1286     unsigned int       ppn;             // physical page number
     1240    unsigned int       flags;           // for _v2p_translate()
    12871241
    12881242    // get channel index
     
    13081262
    13091263    // checking user buffers virtual addresses and length alignment
    1310     if ( ((unsigned int)vbase0 & 0x3) || ((unsigned int)vbase1 & 0x3) || (length & 0x3) )
    1311     {
    1312         _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer not word aligned\n");
    1313         return -1;
    1314     }
    1315 
    1316     // get page table virtual address
    1317     ptab = _get_context_slot(CTX_PTAB_ID);
     1264    if ( ((unsigned int)vbase0 & 0x3) ||
     1265         ((unsigned int)vbase1 & 0x3) ||
     1266         (length & 0x3) )
     1267    {
     1268        _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer not aligned\n");
     1269        return -1;
     1270    }
    13181271
    13191272    // compute frame buffer physical address and initialize _fbf_chbuf[channel]
    1320     vaddr = ((unsigned int)SEG_FBF_BASE);
    1321     _v2p_translate( (page_table_t*) ptab,
    1322                     (vaddr >> 12),
    1323                     &ppn,
    1324                     &flags );
    1325 
    1326     _fbf_chbuf[channel].fbf.desc = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF);
     1273    vaddr = (unsigned int)SEG_FBF_BASE;
     1274    _fbf_chbuf[channel].fbf.desc = _v2p_translate( vaddr , &flags );
    13271275
    13281276    // Compute user buffer 0 physical addresses and intialize _fbf_chbuf[channel]
    1329     vaddr = (unsigned int)vbase0;
    1330     _v2p_translate( (page_table_t*) ptab,
    1331                     (vaddr >> 12),
    1332                     &ppn,
    1333                     &flags );
     1277    vaddr = (unsigned int)vbase0;
     1278    _fbf_chbuf[channel].buf0.desc = _v2p_translate( vaddr , &flags );
     1279
    13341280    if ((flags & PTE_U) == 0)
    13351281    {
    1336         _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 0 not in user space\n");
    1337         return -1;
    1338     }
    1339 
    1340     _fbf_chbuf[channel].buf0.desc = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF);
     1282        _printf("\n[GIET ERROR] in _fbf_cma_start() : buf0 not in user space\n");
     1283        return -1;
     1284    }
    13411285
    13421286    // Compute user buffer 1 physical addresses and intialize _fbf_chbuf[channel]
    1343     vaddr = (unsigned int)vbase1;
    1344     _v2p_translate( (page_table_t*) ptab,
    1345                     (vaddr >> 12),
    1346                     &ppn,
    1347                     &flags );
     1287    vaddr = (unsigned int)vbase1;
     1288    _fbf_chbuf[channel].buf1.desc = _v2p_translate( vaddr , &flags );
     1289
    13481290    if ((flags & PTE_U) == 0)
    13491291    {
    1350         _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 1 not in user space\n");
    1351         return -1;
    1352     }
    1353 
    1354     _fbf_chbuf[channel].buf1.desc = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF);
     1292        _printf("\n[GIET ERROR] in _fbf_cma_start() : buf1 not in user space\n");
     1293        return -1;
     1294    }
    13551295
    13561296    // initializes buffer length
     
    13581298
    13591299    // Compute and register physical adress of the fbf_chbuf descriptor
    1360     vaddr = (unsigned int)(&_fbf_chbuf[channel]);
    1361     _v2p_translate( (page_table_t*) ptab,
    1362                     (vaddr >> 12),
    1363                     &ppn,
    1364                     &flags );
     1300    vaddr = (unsigned int)&_fbf_chbuf[channel];
     1301    _fbf_chbuf_paddr[channel] = _v2p_translate( vaddr , &flags );
    13651302 
    1366     _fbf_chbuf_paddr[channel] = (((paddr_t)ppn) << 12) | (vaddr & 0x00000FFF);
    1367 
    13681303    if ( USE_IOB )
    13691304    {
     
    15941529
    15951530    // deschedule
    1596     _context_switch();
     1531    _sys_context_switch();
    15971532
    15981533    return 0;
    15991534}
    16001535
    1601 //////////////////////
    1602 int _context_switch()
     1536/////////////////////////
     1537int _sys_context_switch()
    16031538{
    16041539    unsigned int save_sr;
     
    17551690                      unsigned int* y )
    17561691{
    1757     unsigned int ppn;
    17581692    unsigned int flags;
    1759     unsigned int vpn  = (((unsigned int)ptr)>>12);
     1693    unsigned long long paddr = _v2p_translate( (unsigned int)ptr , &flags );
    17601694   
    1761     // get the page table pointer
    1762     page_table_t* pt = (page_table_t*)_get_context_slot( CTX_PTAB_ID );
    1763 
    1764     // compute the physical address
    1765     _v2p_translate( pt, vpn, &ppn, &flags );
    1766 
    1767     *x = (ppn>>24) & 0xF;
    1768     *y = (ppn>>20) & 0xF;
     1695    *x = (paddr>>36) & 0xF;
     1696    *y = (paddr>>32) & 0xF;
     1697
    17691698    return 0;
    17701699}
  • soft/giet_vm/giet_kernel/sys_handler.h

    r519 r528  
    197197int _sys_task_exit( char* string );
    198198
    199 int _context_switch();
     199int _sys_context_switch();
    200200
    201201int _sys_local_task_id();
Note: See TracChangeset for help on using the changeset viewer.