Ignore:
Timestamp:
Apr 13, 2015, 5:18:17 PM (10 years ago)
Author:
alain
Message:

Modify the _mwr_isr() to support descheduling/rescheduling of the
task using a coprocessor in DMA mode.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/giet_drivers/mwr_driver.c

    r529 r554  
    1010#include <mapping_info.h>
    1111#include <mwr_driver.h>
     12#include <ctx_handler.h>
    1213#include <utils.h>
    1314#include <kernel_locks.h>
     
    4142
    4243/////////////////////////////////////////////////////////////////////////////
    43 //      Global variables
    44 /////////////////////////////////////////////////////////////////////////////
    45 
     44//      Global variables (all arrays are indexed by the cluster index)
     45/////////////////////////////////////////////////////////////////////////////
     46
     47// Lock protecting exclusive access
    4648__attribute__((section(".kdata")))
    4749simple_lock_t  _coproc_lock[X_SIZE*Y_SIZE];
    4850
    49 __attribute__((section(".kdata")))
    50 unsigned int   _coproc_done[X_SIZE*Y_SIZE];
     51// Coprocessor type
     52__attribute__((section(".kdata")))
     53unsigned int  _coproc_type[X_SIZE*Y_SIZE];
     54
     55// coprocessor characteristics
     56__attribute__((section(".kdata")))
     57unsigned int   _coproc_info[X_SIZE*Y_SIZE];
     58
     59// Coprocessor running mode
     60__attribute__((section(".kdata")))
     61unsigned int  _coproc_mode[X_SIZE*Y_SIZE];
     62
     63// coprocessor status (for MODE_DMA_IRQ)
     64__attribute__((section(".kdata")))
     65unsigned int   _coproc_error[X_SIZE*Y_SIZE];
     66
     67// descheduled task gtid (for MODE_DMA_IRQ)
     68__attribute__((section(".kdata")))
     69unsigned int   _coproc_gtid[X_SIZE*Y_SIZE];
    5170
    5271/////////////////////////////////////////////////////////////////////////////
     
    93112        SEG_MWR_BASE +
    94113        (cluster_xy * PERI_CLUSTER_INCREMENT) +
    95         ((channel + 1) * (CHANNEL_SPAN << 2)) +
     114        ((channel + 1) * (MWR_CHANNEL_SPAN << 2)) +
    96115        (index << 2);
    97116
     
    103122// defined by the "index" and "channel") arguments, in the MWMR_DMA component
    104123// contained in cluster "cluster_xy".
    105 /////////////////////////////////////////////////////////////////////////////
     124////////////////////////////////////////////////////////////////////////////yy
    106125void _mwr_set_channel_register( unsigned int cluster_xy,  // cluster index
    107126                                unsigned int channel,     // channel index
     
    112131        SEG_MWR_BASE +
    113132        (cluster_xy * PERI_CLUSTER_INCREMENT) +
    114         ((channel + 1) * (CHANNEL_SPAN << 2)) +
     133        ((channel + 1) * (MWR_CHANNEL_SPAN << 2)) +
    115134        (index << 2);
    116135       
     
    118137}
    119138
    120 ///////////////////////////////////////////////////////
    121 void _mwr_isr( unsigned int irq_type,  // should be HWI
     139////////////////////////////////////////////////////////////////////////////yy
     140// This Interrupt service routine is called in two situations:
     141// - The MWR_DMA component is running in MODE_DMA_IRQ, and all the
     142//   communication channels have successfully completed.
     143// - The MWR_DMA component is running in any mode, and at least one
     144//   communication channel is reporting a VCI error.
     145////////////////////////////////////////////////////////////////////////////yy
     146void _mwr_isr( unsigned int irq_type,  // unused : should be HWI
    122147               unsigned int irq_id,    // index returned by XCU
    123                unsigned int channel )  // MWMR_DMA channel
    124 {
     148               unsigned int bloup )    // unused : should be 0         
     149{
     150    // get coprocessor coordinates and characteristics
     151    // the processor executing the ISR an the coprocessor
     152    // are in the same cluster
    125153    unsigned int gpid       = _get_procid();
    126154    unsigned int cluster_xy = gpid >> P_WIDTH;
    127155    unsigned int x          = cluster_xy >> Y_WIDTH;
    128156    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    129 
    130     // acknowledge IRQ
    131     _mwr_set_channel_register( cluster_xy, channel, CHANNEL_RUNNING, 0 );
    132 
    133     // compute coproc_id from cluster coordinates
    134     unsigned int coproc_id = x * Y_SIZE + y;
    135 
    136     // set synchronisation variable
    137     _coproc_done[coproc_id] = 1;
     157    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
     158    unsigned int cluster_id = x * Y_SIZE + y;
     159    unsigned int info       = _coproc_info[cluster_id];
     160    unsigned int nb_to      = info & 0xFF;
     161    unsigned int nb_from    = (info>>8) & 0xFF;
     162    unsigned int channel;
     163    unsigned int status;
     164    unsigned int error = 0;
     165
     166    // check status, report errors and reset all channels
     167    for ( channel = 0 ; channel < (nb_to + nb_from) ; channel++ )
     168    {
     169        status = _mwr_get_channel_register( cluster_xy , channel , MWR_CHANNEL_STATUS );
     170
     171        if ( status == MWR_CHANNEL_BUSY )          // strange => report error
     172        {
     173            _printf("\n[GIET_ERROR] in _mwr_isr() : channel %d is busy\n", channel );
     174            error = 1;
     175        }
     176        else if ( status == MWR_CHANNEL_ERROR_DATA )
     177        {
     178            _printf("\n[GIET_ERROR] in _mwr_isr() : DATA_ERROR / channel %d\n", channel );
     179            error = 1;
     180        }
     181        else if ( status == MWR_CHANNEL_ERROR_LOCK )
     182        {
     183            _printf("\n[GIET_ERROR] in _mwr_isr() : LOCK_ERROR / channel %d\n", channel );
     184            error = 1;
     185        }
     186        else if ( status == MWR_CHANNEL_ERROR_DESC )
     187        {
     188            _printf("\n[GIET_ERROR] in _mwr_isr() : DESC_ERROR / channel %d\n", channel );
     189            error = 1;
     190        }
     191
     192        // reset channel
     193        _mwr_set_channel_register( cluster_xy , channel , MWR_CHANNEL_RUNNING , 0 );
     194    }
     195
     196    // register error
     197    _coproc_error[cluster_id]  = error;
     198
     199    // identify task waiting on coprocessor completion
     200    // this task can run in a remote cluster
     201    unsigned int gtid           = _coproc_gtid[cluster_id];
     202    unsigned int remote_procid  = gtid>>16;
     203    unsigned int ltid           = gtid & 0xFFFF;
     204    unsigned int remote_cluster = remote_procid >> P_WIDTH;
     205    unsigned int remote_x       = remote_cluster >> Y_WIDTH;
     206    unsigned int remote_y       = remote_cluster & ((1<<Y_WIDTH)-1);
     207    unsigned int remote_p       = remote_procid & ((1<<P_WIDTH)-1);
     208
     209    // re-activates sleeping task
     210    _set_task_slot( remote_x,
     211                    remote_y,
     212                    remote_p,
     213                    ltid,       
     214                    CTX_RUN_ID,  // CTX_RUN slot
     215                    1 );         // running value
     216
     217    // send a WAKUP WTI to processor running the sleeping task
     218    _xcu_send_wti( remote_cluster,   
     219                   remote_p,
     220                   0 );          // don't force context switch
     221
     222#if GIET_DEBUG_COPROC 
     223_printf("\n[GIET DEBUG COPROC] P[%d,%d,%d] executes _mwr_isr() at cycle %d\n"
     224        "  for task %d running on P[%d,%d,%d] / error = %d\n",
     225        x , y , p , _get_proctime() , ltid , remote_x , remote_y , remote_p , error );
     226#endif
    138227}
    139228
Note: See TracChangeset for help on using the changeset viewer.