Ignore:
Timestamp:
Mar 10, 2015, 3:01:43 PM (10 years ago)
Author:
alain
Message:

Introducing support for hardware coprocessors
using the vci_mwmr_dma components.

File:
1 edited

Legend:

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

    r516 r519  
    1212#include <nic_driver.h>
    1313#include <mmc_driver.h>
     14#include <mwr_driver.h>
    1415#include <cma_driver.h>
    1516#include <ctx_handler.h>
     
    2223#include <giet_config.h>
    2324#include <mapping_info.h>
     25#include <io.h>
    2426
    2527#if !defined(SEG_BOOT_MAPPING_BASE)
     
    5961#endif
    6062
     63
     64////////////////////////////////////////////////////////////////////////////
     65//     Coprocessors loks and synchronisation variables
     66////////////////////////////////////////////////////////////////////////////
     67
     68__attribute__((section(".kdata")))
     69simple_lock_t  _coproc_lock[X_SIZE*Y_SIZE];
     70
     71__attribute__((section(".kdata")))
     72unsigned int   _coproc_done[X_SIZE*Y_SIZE];
    6173
    6274////////////////////////////////////////////////////////////////////////////
     
    8193
    8294////////////////////////////////////////////////////////////////////////////
    83 // These global variables is defined in tty0.c and tty_driver.c files.
     95// These global variables are allocated in tty0.c and tty_driver.c files.
    8496////////////////////////////////////////////////////////////////////////////
    8597
     
    119131const void * _syscall_vector[64] =
    120132{
    121     &_sys_proc_xyp,         /* 0x00 */
    122     &_get_proctime,         /* 0x01 */
    123     &_sys_tty_write,        /* 0x02 */
    124     &_sys_tty_read,         /* 0x03 */
    125     &_sys_tty_alloc,        /* 0x04 */
    126     &_sys_tty_get_lock,     /* 0x05 */
    127     &_sys_tty_release_lock, /* 0x06 */
    128     &_sys_heap_info,        /* 0x07 */
    129     &_sys_local_task_id,    /* 0x08 */
    130     &_sys_global_task_id,   /* 0x09 */
    131     &_sys_fbf_cma_alloc,    /* 0x0A */
    132     &_sys_fbf_cma_start,    /* 0x0B */
    133     &_sys_fbf_cma_display,  /* 0x0C */
    134     &_sys_fbf_cma_stop,     /* 0x0D */
    135     &_sys_task_exit,        /* 0x0E */
    136     &_sys_procs_number,     /* 0x0F */
    137 
    138     &_sys_fbf_sync_write,   /* 0x10 */
    139     &_sys_fbf_sync_read,    /* 0x11 */
    140     &_sys_thread_id,        /* 0x12 */
    141     &_sys_ukn,              /* 0x13 */
    142     &_sys_tim_alloc,        /* 0x14 */
    143     &_sys_tim_start,        /* 0x15 */
    144     &_sys_tim_stop,         /* 0x16 */
    145     &_sys_ukn,              /* 0x17 */
    146     &_sys_ukn,              /* 0x18 */   
    147     &_context_switch,       /* 0x19 */
    148     &_sys_vseg_get_vbase,   /* 0x1A */
    149     &_sys_vseg_get_length,  /* 0x1B */
    150     &_sys_xy_from_ptr,      /* 0x1C */
    151     &_sys_ukn,              /* 0x1D */
    152     &_sys_ukn,              /* 0x1E */
    153     &_sys_ukn,              /* 0x1F */
    154 
    155     &_fat_user_open,        /* 0x20 */
    156     &_fat_user_read,        /* 0x21 */
    157     &_fat_user_write,       /* 0x22 */
    158     &_fat_user_lseek,       /* 0x23 */
    159     &_fat_fstat,            /* 0x24 */
    160     &_fat_close,            /* 0x25 */
    161     &_sys_ukn,              /* 0x26 */
    162     &_sys_ukn,              /* 0x27 */
    163     &_sys_ukn,              /* 0x28 */
    164     &_sys_ukn,              /* 0x29 */
    165     &_sys_ukn,              /* 0x2A */
    166     &_sys_ukn,              /* 0x2B */
    167     &_sys_ukn,              /* 0x2C */
    168     &_sys_ukn,              /* 0x2D */
    169     &_sys_ukn,              /* 0x2E */
    170     &_sys_ukn,              /* 0x2F */
    171 
    172     &_sys_nic_alloc,        /* 0x30 */
    173     &_sys_nic_start,        /* 0x31 */
    174     &_sys_nic_move,         /* 0x32 */
    175     &_sys_nic_stop,         /* 0x33 */
    176     &_sys_nic_stats,        /* 0x34 */
    177     &_sys_nic_clear,        /* 0x35 */
    178     &_sys_ukn,              /* 0x36 */
    179     &_sys_ukn,              /* 0x37 */
    180     &_sys_ukn,              /* 0x38 */   
    181     &_sys_ukn,              /* 0x39 */
    182     &_sys_ukn,              /* 0x3A */
    183     &_sys_ukn,              /* 0x3B */
    184     &_sys_ukn,              /* 0x3C */
    185     &_sys_ukn,              /* 0x3D */
    186     &_sys_ukn,              /* 0x3E */
    187     &_sys_ukn,              /* 0x3F */
     133    &_sys_proc_xyp,             /* 0x00 */
     134    &_get_proctime,             /* 0x01 */
     135    &_sys_tty_write,            /* 0x02 */
     136    &_sys_tty_read,             /* 0x03 */
     137    &_sys_tty_alloc,            /* 0x04 */
     138    &_sys_tty_get_lock,         /* 0x05 */
     139    &_sys_tty_release_lock,     /* 0x06 */
     140    &_sys_heap_info,            /* 0x07 */
     141    &_sys_local_task_id,        /* 0x08 */
     142    &_sys_global_task_id,       /* 0x09 */
     143    &_sys_fbf_cma_alloc,        /* 0x0A */
     144    &_sys_fbf_cma_start,        /* 0x0B */
     145    &_sys_fbf_cma_display,      /* 0x0C */
     146    &_sys_fbf_cma_stop,         /* 0x0D */
     147    &_sys_task_exit,            /* 0x0E */
     148    &_sys_procs_number,         /* 0x0F */
     149
     150    &_sys_fbf_sync_write,       /* 0x10 */
     151    &_sys_fbf_sync_read,        /* 0x11 */
     152    &_sys_thread_id,            /* 0x12 */
     153    &_sys_ukn,                  /* 0x13 */
     154    &_sys_tim_alloc,            /* 0x14 */
     155    &_sys_tim_start,            /* 0x15 */
     156    &_sys_tim_stop,             /* 0x16 */
     157    &_sys_ukn,                  /* 0x17 */
     158    &_sys_ukn,                  /* 0x18 */   
     159    &_context_switch,           /* 0x19 */
     160    &_sys_vseg_get_vbase,       /* 0x1A */
     161    &_sys_vseg_get_length,      /* 0x1B */
     162    &_sys_xy_from_ptr,          /* 0x1C */
     163    &_sys_ukn,                  /* 0x1D */
     164    &_sys_ukn,                  /* 0x1E */
     165    &_sys_ukn,                  /* 0x1F */
     166
     167    &_fat_user_open,            /* 0x20 */
     168    &_fat_user_read,            /* 0x21 */
     169    &_fat_user_write,           /* 0x22 */
     170    &_fat_user_lseek,           /* 0x23 */
     171    &_fat_fstat,                /* 0x24 */
     172    &_fat_close,                /* 0x25 */
     173    &_sys_ukn,                  /* 0x26 */
     174    &_sys_ukn,                  /* 0x27 */
     175    &_sys_ukn,                  /* 0x28 */
     176    &_sys_ukn,                  /* 0x29 */
     177    &_sys_ukn,                  /* 0x2A */
     178    &_sys_ukn,                  /* 0x2B */
     179    &_sys_ukn,                  /* 0x2C */
     180    &_sys_ukn,                  /* 0x2D */
     181    &_sys_ukn,                  /* 0x2E */
     182    &_sys_ukn,                  /* 0x2F */
     183
     184    &_sys_nic_alloc,            /* 0x30 */
     185    &_sys_nic_start,            /* 0x31 */
     186    &_sys_nic_move,             /* 0x32 */
     187    &_sys_nic_stop,             /* 0x33 */
     188    &_sys_nic_stats,            /* 0x34 */
     189    &_sys_nic_clear,            /* 0x35 */
     190    &_sys_ukn,                  /* 0x36 */
     191    &_sys_ukn,                  /* 0x37 */
     192    &_sys_coproc_register_get,  /* 0x38 */   
     193    &_sys_coproc_register_set,  /* 0x39 */
     194    &_sys_coproc_release,       /* 0x3A */
     195    &_sys_coproc_completed,     /* 0x3B */
     196    &_sys_coproc_alloc,         /* 0x3C */
     197    &_sys_coproc_channel_init,  /* 0x3D */
     198    &_sys_coproc_channel_start, /* 0x3E */
     199    &_sys_coproc_channel_stop,  /* 0x3F */
    188200};
     201
     202
     203//////////////////////////////////////////////////////////////////////////////
     204//           Coprocessors related syscall handlers
     205//////////////////////////////////////////////////////////////////////////////
     206
     207///////////////////////////////////////////////////////
     208int _sys_coproc_register_set( unsigned int  cluster_xy,
     209                              unsigned int  reg_index,
     210                              unsigned int  value )
     211{
     212    // TODO checking coprocessor ownership...
     213
     214    _mwr_set_coproc_register( cluster_xy , reg_index , value );
     215    return 0;
     216
     217
     218///////////////////////////////////////////////////////
     219int _sys_coproc_register_get( unsigned int   cluster_xy,
     220                              unsigned int   reg_index,
     221                              unsigned int*  buffer )
     222{
     223    // TODO checking coprocessor ownership...
     224
     225    *buffer = _mwr_get_coproc_register( cluster_xy , reg_index );
     226    return 0;
     227
     228
     229//////////////////////////////////////////////////
     230int _sys_coproc_alloc( unsigned int   coproc_type,
     231                       unsigned int*  coproc_info,
     232                       unsigned int*  cluster_xy )
     233{
     234    // In this implementation, the allocation policy is constrained:
     235    // the coprocessor must be in the same cluster as the calling task,
     236    // and ther is at most one coprocessor per cluster
     237
     238    mapping_header_t  * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     239    mapping_cluster_t * cluster = _get_cluster_base(header);
     240    mapping_periph_t  * periph  = _get_periph_base(header);
     241
     242    // get cluster coordinates and cluster global index
     243    unsigned int procid     = _get_procid();
     244    unsigned int x          = procid >> (Y_WIDTH + P_WIDTH);
     245    unsigned int y          = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
     246    unsigned int cluster_id = x*Y_SIZE + y;
     247 
     248    // search coprocessor in cluster
     249    mapping_periph_t*  found = NULL;
     250    unsigned int min   = cluster[cluster_id].periph_offset;
     251    unsigned int max   = min + cluster[cluster_id].periphs;
     252    unsigned int periph_id;
     253    for ( periph_id = min ; periph_id < max ; periph_id++ )
     254    {
     255        if ( (periph[periph_id].type == PERIPH_TYPE_MWR) &&
     256             (periph[periph_id].subtype == coproc_type) )
     257        {
     258            found = &periph[periph_id];
     259            break;
     260        }
     261    }
     262
     263    if ( found != NULL )
     264    {
     265        // get the lock (at most one coproc per cluster)
     266        _simple_lock_acquire( &_coproc_lock[cluster_id] );
     267 
     268        // returns coprocessor info
     269        *coproc_info = (found->arg0 & 0xFF)     |
     270                       (found->arg1 & 0xFF)<<8  |
     271                       (found->arg2 & 0xFF)<<16 |
     272                       (found->arg3 & 0xFF)<<24 ;
     273        *cluster_xy = (x<<Y_WIDTH) + y;
     274
     275#if GIET_DEBUG_COPROC
     276_printf("\n[GIET DEBUG COPROC] _sys_coproc_alloc() in cluster[%d,%d]\n"
     277        "  coproc_info = %x / cluster_xy = %x\n",
     278        x , y , *coproc_info , *cluster_xy );
     279#endif
     280        return 0;
     281    }
     282    else
     283    {
     284         _printf("\n[GIET_ERROR] in _sys_coproc_alloc(): no coprocessor "
     285                 " with type %d available in cluster[%d,%d]\n",
     286                 coproc_type , x , y );
     287        return -1;
     288    }
     289}  // end _sys_coproc_alloc()
     290
     291//////////////////////////////////////////////////
     292int _sys_coproc_release( unsigned int cluster_xy )
     293{
     294    // TODO checking coprocessor ownership...
     295
     296    // check cluster coordinates
     297    unsigned int cx     = cluster_xy >> Y_WIDTH;
     298    unsigned int cy     = cluster_xy & ((1<<Y_WIDTH)-1);
     299    unsigned int procid = _get_procid();
     300    unsigned int x      = procid >> (Y_WIDTH + P_WIDTH);
     301    unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
     302    if ( (x != cx) || (y != cy) )
     303    {
     304         _printf("\n[GIET_ERROR] in _sys_coproc_channel_init(): "
     305                 "wrong cluster coordinates\n");
     306         return -1;
     307    }
     308
     309    // compute coprocessor global index
     310    unsigned int coproc_id = x * Y_SIZE + y;
     311
     312    // release coprocessor
     313    _simple_lock_release( &_coproc_lock[coproc_id] );
     314
     315#if GIET_DEBUG_COPROC
     316_printf("\n[GIET DEBUG COPROC] _sys_coproc_release() in cluster[%d,%d]\n",
     317        x, y );
     318#endif
     319
     320    return 0;
     321}  // end _sys_coproc_release()
     322
     323/////////////////////////////////////////////////////////////////
     324int _sys_coproc_channel_init( unsigned int            cluster_xy,
     325                              unsigned int            channel,
     326                              giet_coproc_channel_t*  desc )
     327{
     328    // TODO checking coprocessor ownership...
     329
     330    // check cluster coordinates
     331    unsigned int cx     = cluster_xy >> Y_WIDTH;
     332    unsigned int cy     = cluster_xy & ((1<<Y_WIDTH)-1);
     333    unsigned int procid = _get_procid();
     334    unsigned int x      = procid >> (Y_WIDTH + P_WIDTH);
     335    unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
     336    if ( (x != cx) || (y != cy) )
     337    {
     338         _printf("\n[GIET_ERROR] in _sys_coproc_channel_init(): "
     339                 "wrong cluster coordinates\n");
     340         return -1;
     341    }
     342
     343    // check channel mode
     344    unsigned mode = desc->channel_mode;
     345    if ( (mode != MODE_MWMR) &&
     346         (mode != MODE_DMA_IRQ) &&
     347         (mode != MODE_DMA_NO_IRQ) )
     348    {
     349         _printf("\n[GIET_ERROR] in _sys_coproc_channel_init():"
     350                 " illegal mode\n");
     351         return -1;
     352    }
     353
     354    // get memory buffer size
     355    unsigned int size = desc->buffer_size;
     356 
     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;
     361    unsigned long long buffer_paddr;
     362    unsigned int       buffer_lsb;
     363    unsigned int       buffer_msb;
     364    unsigned long long mwmr_paddr;
     365    unsigned int       mwmr_lsb;
     366    unsigned int       mwmr_msb;
     367    unsigned long long lock_paddr;
     368    unsigned int       lock_lsb;
     369    unsigned int       lock_msb;
     370
     371    // 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);
     380
     381    // call MWMR_DMA driver
     382    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_MODE, mode );
     383    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_SIZE, size );
     384    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_BUFFER_LSB, buffer_lsb );
     385    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_BUFFER_MSB, buffer_msb );
     386                       
     387    // compute MWMR descriptor and lock physical addresses (if required)
     388    if ( mode == MODE_MWMR )
     389    {
     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);
     396        mwmr_lsb = (unsigned int)mwmr_paddr;
     397        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);
     407
     408        // call MWMR_DMA driver
     409        _mwr_set_channel_register( cluster_xy, channel, CHANNEL_MWMR_LSB, mwmr_lsb );
     410        _mwr_set_channel_register( cluster_xy, channel, CHANNEL_MWMR_MSB, mwmr_msb );
     411        _mwr_set_channel_register( cluster_xy, channel, CHANNEL_LOCK_LSB, lock_lsb );
     412        _mwr_set_channel_register( cluster_xy, channel, CHANNEL_LOCK_MSB, lock_msb );
     413    }
     414
     415#if GIET_DEBUG_COPROC
     416_printf("\n[GIET DEBUG COPROC] _sys_coproc_channel_init() in cluster[%d,%d]\n"
     417        " channel =  %d / mode = %d / buffer_size = %d\n"
     418        " buffer_paddr = %l / mwmr_paddr = %l / lock_paddr = %l\n",
     419        x , y , channel , mode , size ,
     420        buffer_paddr, mwmr_paddr, lock_paddr );
     421#endif
     422       
     423    return 0;
     424} // end _sys_coproc_channel_init()
     425
     426////////////////////////////////////////////////////////
     427int _sys_coproc_channel_start( unsigned int  cluster_xy,
     428                               unsigned int  channel )
     429{
     430    // TODO checking coprocessor ownership...
     431
     432    // check cluster coordinates
     433    unsigned int cx     = cluster_xy >> Y_WIDTH;
     434    unsigned int cy     = cluster_xy & ((1<<Y_WIDTH)-1);
     435    unsigned int procid = _get_procid();
     436    unsigned int x      = procid >> (Y_WIDTH + P_WIDTH);
     437    unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
     438    if ( (x != cx) || (y != cy) )
     439    {
     440         _printf("\n[GIET_ERROR] in _sys_coproc_channel_start():"
     441                 " wrong coordinates\n");
     442         return -1;
     443    }
     444 
     445    // reset synchronisation variable
     446    unsigned int coproc_id = (x * Y_SIZE) + y;
     447    _coproc_done[coproc_id] = 0;
     448
     449    // call MWMR_DMA driver
     450    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_RUNNING, 1 );
     451
     452#if GIET_DEBUG_COPROC
     453_printf("\n[GIET DEBUG COPROC] _sys_coproc_channel_start() in cluster[%d,%d]"
     454        " / channel = %d\n", x , y , channel );
     455#endif
     456
     457    return 0;
     458} // end _sys_coproc_channel_start()
     459
     460///////////////////////////////////////////////////////
     461int _sys_coproc_channel_stop( unsigned int  cluster_xy,
     462                              unsigned int  channel )
     463{
     464    // TODO checking coprocessor ownership...
     465
     466    // check cluster coordinates
     467    unsigned int cx     = cluster_xy >> Y_WIDTH;
     468    unsigned int cy     = cluster_xy & ((1<<Y_WIDTH)-1);
     469    unsigned int procid = _get_procid();
     470    unsigned int x      = procid >> (Y_WIDTH + P_WIDTH);
     471    unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
     472    if ( (x != cx) || (y != cy) )
     473    {
     474         _printf("\n[GIET_ERROR] in _sys_coproc_channel_stop(): wrong coordinates\n");
     475         return -1;
     476    }
     477 
     478    // call MWMR_DMA driver
     479    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_RUNNING, 0 );
     480
     481#if GIET_DEBUG_COPROC
     482_printf("\n[GIET DEBUG COPROC] _sys_coproc_channel_stop() in cluster[%d,%d]"
     483        " / channel = %d\n", x , y , channel );
     484#endif
     485
     486    return 0;
     487} // end _sys_coproc_channel_stop()
     488
     489/////////////////////////////////////////////////////
     490int _sys_coproc_completed( unsigned int  cluster_xy )
     491{
     492    // TODO checking coprocessor ownership...
     493
     494    // check cluster coordinates
     495    unsigned int cx     = cluster_xy >> Y_WIDTH;
     496    unsigned int cy     = cluster_xy & ((1<<Y_WIDTH)-1);
     497    unsigned int procid = _get_procid();
     498    unsigned int x      = procid >> (Y_WIDTH + P_WIDTH);
     499    unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
     500    if ( (x != cx) || (y != cy) )
     501    {
     502         _printf("\n[GIET_ERROR] in _sys_coproc_completed(): "
     503                 "wrong cluster coordinates\n");
     504         return -1;
     505    }
     506 
     507    // polling the synchronisation variable
     508    unsigned int coproc_id = (x * Y_SIZE) + y;
     509    while ( ioread32( &_coproc_done[coproc_id]) == 0 ) asm volatile("nop");
     510
     511    _coproc_done[coproc_id] = 0;
     512
     513#if GIET_DEBUG_COPROC
     514_printf("\n[GIET DEBUG COPROC] _sys_coproc_completed() in cluster[%d,%d]\n",
     515        x, y );
     516#endif
     517
     518    return 0;
     519} // end _sys_coproc_completed()
    189520
    190521
Note: See TracChangeset for help on using the changeset viewer.