Changeset 529


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

1) Removing the IOC driver (integrated in the FAT library).
2) Simplifying the BDV, HBA, SDC, RDK drivers: they support
only two modes (synchronous => polling / descheduling => IRQ),
and only one access function (for both read/write).

Location:
soft/giet_vm/giet_drivers
Files:
2 deleted
14 edited

Legend:

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

    r496 r529  
    22// File      : bdv_driver.c
    33// Date      : 23/05/2013
    4 // Author    : alain greiner
    5 // Maintainer: cesar fuguet
     4// Author    : alain greiner cesar fuguet
    65// Copyright (c) UPMC-LIP6
    76///////////////////////////////////////////////////////////////////////////////////
    87// Implementation notes:
    9 // 1. In order to share code, the two _bdv_read() and _bdv_write() functions
    10 //    call the same _bdv_access() function.
    11 // 2. All accesses to BDV registers are done by the two
    12 //    _bdv_set_register() and _bdv_get_register() low-level functions,
    13 //    that are handling virtual / physical extended addressing.
     8// All accesses to BDV registers are done by the two
     9// _bdv_set_register() and _bdv_get_register() low-level functions,
     10// that are handling virtual / physical extended addressing.
    1411///////////////////////////////////////////////////////////////////////////////////
    1512
     
    1815#include <bdv_driver.h>
    1916#include <xcu_driver.h>
    20 #include <ioc_driver.h>
     17#include <kernel_locks.h>
    2118#include <utils.h>
    2219#include <tty0.h>
    2320#include <ctx_handler.h>
    24 
    25 ///////////////////////////////////////////////////////////////////////////////
    26 // BDV global variables
    27 ///////////////////////////////////////////////////////////////////////////////
    28 
     21#include <irq_handler.h>
     22
     23///////////////////////////////////////////////////////////////////////////////
     24//      Global variables
     25///////////////////////////////////////////////////////////////////////////////
     26
     27// lock protecting single channel BDV peripheral
    2928__attribute__((section(".kdata")))
    3029spin_lock_t  _bdv_lock __attribute__((aligned(64)));
    3130
     31// global index of the waiting task (only used in descheduling mode)
     32__attribute__((section(".kdata")))
     33unsigned int _bdv_gtid;
     34
     35// BDV peripheral status (only used in descheduling mode)
    3236__attribute__((section(".kdata")))
    3337unsigned int _bdv_status;
    34 
    35 __attribute__((section(".kdata")))
    36 unsigned int _bdv_gtid;
    3738
    3839///////////////////////////////////////////////////////////////////////////////
     
    5657
    5758///////////////////////////////////////////////////////////////////////////////
    58 // This function transfer data between a memory buffer and the block device.
    59 // The buffer lentgth is (count*block_size) bytes.
    60 // Arguments are:
    61 // - to_mem     : from external storage to memory when non 0.
    62 // - mode       : BOOT / KERNEL / USER
    63 // - lba        : first block index on the external storage.
    64 // - buf_paddr  : physical base address of the memory buffer.
    65 // - count      : number of blocks to be transfered.
    66 // Returns 0 if success, > 0 if error.
    67 ///////////////////////////////////////////////////////////////////////////////
    68 static unsigned int _bdv_access( unsigned int       to_mem,
    69                                  unsigned int       mode,
    70                                  unsigned int       lba,
    71                                  unsigned long long buf_paddr,
    72                                  unsigned int       count)
     59//      Extern functions
     60///////////////////////////////////////////////////////////////////////////////
     61
     62/////////////////////////////////////////////////////
     63unsigned int _bdv_access( unsigned int       use_irq,
     64                          unsigned int       to_mem,
     65                          unsigned int       lba,
     66                          unsigned long long buf_paddr,
     67                          unsigned int       count)
    7368{
    7469    unsigned int procid  = _get_procid();
     
    7873
    7974#if GIET_DEBUG_IOC_DRIVER
    80 _puts("\n[BDV DEBUG] _bdv_access() : P[");
    81 _putd( x );
    82 _puts(",");
    83 _putd( y );
    84 _puts(",");
    85 _putd( p );
    86 _puts("] enters at cycle ");
    87 _putd( _get_proctime() );
    88 _puts("\n - to_mem  = ");
    89 _putd( to_mem );
    90 _puts("\n - mode    = ");
    91 _putd( mode );
    92 _puts("\n - paddr   = ");
    93 _putl( buf_paddr );
    94 _puts("\n - sectors = ");
    95 _putd( count );
    96 _puts("\n - lba     = ");
    97 _putx( lba );
    98 _puts("\n");
    99 #endif
    100 
    101     unsigned int       error = 0;
     75_printf("\n[BDV DEBUG] P[%d,%d,%d] enters _bdv_access at cycle %d\n"
     76        "  use_irq = %d / to_mem = %d / lba = %x / paddr = %l / count = %d\n",
     77        x , y , p , _get_proctime() , use_irq , to_mem , lba , buf_paddr, count );
     78#endif
     79
     80    // check buffer alignment
     81    if( buf_paddr & 0x1FF )
     82    {
     83        _printf("\n[BDV ERROR] in _bdv_access() : buffer not block aligned\n");
     84        return -1;
     85    }
     86
     87    unsigned int error;
     88    unsigned int status;
    10289
    10390    // get the lock protecting BDV
    10491    _spin_lock_acquire( &_bdv_lock );
    105 
    106 #if GIET_DEBUG_IOC_DRIVER
    107 _puts("\n[BDV DEBUG] _bdv_access() : P[");
    108 _putd( x );
    109 _puts(",");
    110 _putd( y );
    111 _puts(",");
    112 _putd( p );
    113 _puts("] get _bdv_lock at cycle ");
    114 _putd( _get_proctime() );
    115 _puts("\n");
    116 #endif
    11792
    11893    // set device registers
     
    12297    _bdv_set_register( BLOCK_DEVICE_LBA       , lba );
    12398
    124     // In BOOT mode, we launch transfer, and poll the BDV_STATUS
    125     // register because IRQs are masked.
    126     if ( mode == IOC_BOOT_MODE )
     99    /////////////////////////////////////////////////////////////////////
     100    // In synchronous mode, we launch transfer,
     101    // and poll the BDV_STATUS register until completion.
     102    /////////////////////////////////////////////////////////////////////
     103    if ( use_irq == 0 )
    127104    {
    128105        // Launch transfert
     
    131108
    132109#if GIET_DEBUG_IOC_DRIVER
    133 _puts("\n[BDV DEBUG] _bdv_access() : P[");
    134 _putd( x );
    135 _puts(",");
    136 _putd( y );
    137 _puts(",");
    138 _putd( p );
    139 _puts("] launch transfer in polling mode at cycle ");
    140 _putd( _get_proctime() );
    141 _puts("\n");
    142 #endif
    143         unsigned int status;
     110_printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] launch transfer"
     111        " in polling mode at cycle %d\n",
     112        x , y , p , _get_proctime() );
     113#endif
     114
    144115        do
    145116        {
     
    147118
    148119#if GIET_DEBUG_IOC_DRIVER
    149 _puts("\n[BDV DEBUG] _bdv_access() : P[");
    150 _putd( x );
    151 _puts(",");
    152 _putd( y );
    153 _puts(",");
    154 _putd( p );
    155 _puts("] wait on BDV_STATUS register ...\n");
     120_printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] wait on BDV_STATUS ...\n",
     121        x , y , p );
    156122#endif
    157123        }
     
    164130        error = ( (status == BLOCK_DEVICE_READ_ERROR) ||
    165131                  (status == BLOCK_DEVICE_WRITE_ERROR) );
    166 
    167         // release lock
    168         _spin_lock_release( &_bdv_lock );     
    169     }
    170     // in USER or KERNEL mode, we deschedule the task.
    171     // When the task is rescheduled, we check the _bdv_status variable,
    172     // and release the lock.
     132    }
     133
     134    /////////////////////////////////////////////////////////////////
     135    // in descheduling mode, we deschedule the task
     136    // and use an interrupt to reschedule the task.
    173137    // We need a critical section, because we must reset the RUN bit
    174         // before to launch the transfer, and we don't want to be descheduled
    175         // between these two operations.
     138        // before to launch the transfer, and we don't want to be
     139    // descheduled between these two operations.
     140    /////////////////////////////////////////////////////////////////
    176141    else
    177142    {
    178143        unsigned int save_sr;
     144        unsigned int wti_index;
    179145        unsigned int ltid = _get_current_task_id();
    180146
    181         // activates BDV interrupts
     147        // activates BDV interrupt
    182148        _bdv_set_register( BLOCK_DEVICE_IRQ_ENABLE, 1 );
    183149
    184         // set the _bdv_status variable
    185         _bdv_status = BLOCK_DEVICE_BUSY;
     150        // allocate a WTI mailbox to the calling proc if external IRQ
     151        if ( USE_PIC ) _ext_irq_alloc( ISR_BDV , 0 , &wti_index );
    186152
    187153        // enters critical section
     
    197163
    198164#if GIET_DEBUG_IOC_DRIVER
    199 _puts("\n[BDV DEBUG] _bdv_access() : P[");
    200 _putd( x );
    201 _puts(",");
    202 _putd( y );
    203 _puts(",");
    204 _putd( p );
    205 _puts("] launch transfer in interrupt mode at cycle ");
    206 _putd( _get_proctime() );
    207 _puts("\n");
     165_printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] launch transfer"
     166        " in descheduling mode at cycle %d\n",
     167        x , y , p , _get_proctime() );
    208168#endif
    209169
     
    212172
    213173#if GIET_DEBUG_IOC_DRIVER
    214 _puts("\n[BDV DEBUG] _bdv_access() : P[");
    215 _putd( x );
    216 _puts(",");
    217 _putd( y );
    218 _puts(",");
    219 _putd( p );
    220 _puts("] resume execution after descheduling\n");
    221 #endif
     174_printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] resume execution at cycle %d\n",
     175        x , y , p , _get_proctime() );
     176#endif
     177
     178        // release WTI mailbox if external IRQ
     179        if ( USE_PIC ) _ext_irq_release( ISR_BDV , 0 , wti_index );
     180
    222181        // restore SR
    223182        _it_restore( &save_sr );
     
    226185        error = ( (_bdv_status == BLOCK_DEVICE_READ_ERROR) ||
    227186                  (_bdv_status == BLOCK_DEVICE_WRITE_ERROR) );
    228 
    229         // reset _bdv_status and release lock
    230         _bdv_status = BLOCK_DEVICE_IDLE;
    231         _spin_lock_release( &_bdv_lock );     
    232     }
    233 
    234 #if GIET_DEBUG_IOC_DRIVER
    235 _puts("\n[BDV DEBUG] _bdv_access() : P[");
    236 _putd( x );
    237 _puts(",");
    238 _putd( y );
    239 _puts(",");
    240 _putd( p );
    241 _puts("] exit at cycle ");
    242 _putd( _get_proctime() );
    243 _puts(" / error = ");
    244 _putd( error );
    245 _puts("\n");
     187    }
     188
     189    // release lock
     190    _spin_lock_release( &_bdv_lock );     
     191
     192#if GIET_DEBUG_IOC_DRIVER
     193_printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] exit at cycle %d\n",
     194        x , y , p , _get_proctime() );
    246195#endif
    247196
     
    249198} // end _bdv_access()
    250199
    251 ///////////////////////////////////////////////////////////////////////////////
    252 //      External functions
    253 ///////////////////////////////////////////////////////////////////////////////
    254 
    255200////////////////////////
    256201unsigned int _bdv_init()
     
    264209    _bdv_set_register( BLOCK_DEVICE_IRQ_ENABLE, 0 );
    265210    return 0;
    266 }
    267 
    268 ////////////////////////////////////////////////
    269 unsigned int _bdv_read( unsigned int       mode, 
    270                         unsigned int       lba,
    271                         unsigned long long buffer,
    272                         unsigned int       count)
    273 {
    274     return _bdv_access( 1,        // read access
    275                         mode, 
    276                         lba,
    277                         buffer,
    278                         count );
    279 }
    280 
    281 /////////////////////////////////////////////////
    282 unsigned int _bdv_write( unsigned int       mode, 
    283                          unsigned int       lba,
    284                          unsigned long long buffer,
    285                          unsigned int       count )
    286 {
    287     return _bdv_access( 0,        // write access
    288                         mode, 
    289                         lba,
    290                         buffer,
    291                         count );
    292 }
    293 
    294 //////////////////////////////
    295 unsigned int _bdv_get_status()
    296 {
    297     return _bdv_get_register( BLOCK_DEVICE_STATUS );
    298 }
    299 
    300 //////////////////////////////////
    301 unsigned int _bdv_get_block_size()
    302 {
    303     return _bdv_get_register( BLOCK_DEVICE_BLOCK_SIZE );
    304211}
    305212
     
    309216               unsigned int channel )   // unused
    310217{
    311     // get BDV status (and reset IRQ)
     218    // get BDV status and reset BDV_IRQ
    312219    unsigned int status =  _bdv_get_register( BLOCK_DEVICE_STATUS );
    313220
     
    316223         (status == BLOCK_DEVICE_BUSY) )   return;
    317224 
    318     // save status in kernel buffer _bdv_status
    319     _bdv_status = status; 
     225    // register status in global variable
     226    _bdv_status = status;
    320227
    321228    // identify task waiting on BDV
     
    333240                    ltid,       
    334241                    CTX_RUN_ID,  // CTX_RUN slot
    335                     1 );         // running
    336 
    337     // requires a context switch for remote processor running the waiting task
     242                    1 );         // running value
     243
     244    // send a WAKUP WTI to processor running the sleeping task
    338245    _xcu_send_wti( remote_cluster,   
    339246                   remote_p,
    340                    0 );          // don't force context switch if not idle
    341 
    342 #if GIET_DEBUG_IRQS  // we don't take the TTY lock to avoid deadlock
     247                   0 );          // don't force context switch
     248
     249#if GIET_DEBUG_IOC_DRIVER 
    343250unsigned int procid  = _get_procid();
    344251unsigned int x       = procid >> (Y_WIDTH + P_WIDTH);
    345252unsigned int y       = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
    346253unsigned int p       = procid & ((1<<P_WIDTH)-1);
    347 
    348 _puts("\n[IRQS DEBUG] Processor[");
    349 _putd(x );
    350 _puts(",");
    351 _putd(y );
    352 _puts(",");
    353 _putd(p );
    354 _puts("] enters _bdv_isr() at cycle ");
    355 _putd(_get_proctime() );
    356 _puts("\n  for task ");
    357 _putd(ltid );
    358 _puts(" running on processor[");
    359 _putd(remote_x );
    360 _puts(",");
    361 _putd(remote_y );
    362 _puts(",");
    363 _putd(remote_p );
    364 _puts(" / bdv status = ");
    365 _putx(_bdv_status );
    366 _puts("\n");
    367 #endif
    368 
    369 }
     254_printf("\n[IOC DEBUG] Processor[%d,%d,%d] enters _bdv_isr() at cycle %d\n"
     255        "  for task %d running on P[%d,%d,%d] / bdv_status = %x\n",
     256        x , y , p , _get_proctime() ,
     257        ltid , remote_x , remote_y , remote_p , status );
     258#endif
     259
     260} // end bdv_isr()
    370261
    371262
  • soft/giet_vm/giet_drivers/bdv_driver.h

    r496 r529  
    1010// a single channel, block oriented, external storage contrÃŽler.
    1111//
    12 // The _bdv_read() and _bdv_write() functions are always blocking.
    13 // They can be called in 3 modes:
     12// The _bdv_access() function supports both read and write access to block device,
     13// and implement two operating modes:
    1414//
    15 // - In BOOT mode, these functions use a polling policy on the BDV STATUS
     15// - in "synchronous" mode, it uses a polling policy on the BDV STATUS
    1616//   register to detect transfer completion, as interrupts are not activated.
    1717//   This mode is used by the boot code to load the map.bin file into memory
    1818//   (before MMU activation), or to load the .elf files (after MMU activation).
    19 //
    20 // - In KERNEL mode, these functions use a descheduling strategy:
    21 //   The ISR executed when transfer completes should restart the calling task.
    22 //   There is no checking of user access right to the memory buffer.
    23 //   This mode must be used, for an "open" system call.
    24 //
    25 // - In USER mode, these functions use a descheduling strategy:
    26 //   The ISR executed when transfer completes should restart the calling task,
    27 //   The user access right to the memory buffer must be checked.
    28 //   This mode must be used for a "read/write" system call.
    29 //
     19// - In "descheduling" mode, ir uses a descheduling + IRQ policy.
     20//   The ISR executed when transfer completes should restart the calling task,
     21//   as the calling task global index has been saved in the _bdv_gtid variable.
     22//   
    3023// As the BDV component can be used by several programs running in parallel,
    31 // the _bdv_lock variable guaranties exclusive access to the device.  The
    32 // _bdv_read() and _bdv_write() functions use atomic LL/SC to get the lock.
    33 //
    34 // Finally, the memory buffer must fulfill the following conditions:
    35 // - The buffer must be word aligned,
    36 // - The buffer must be mapped in user space for an user access,
    37 // - The buffer must be writable in case of (to_mem) access,
    38 // - The total number of physical pages occupied by the user buffer cannot
    39 //   be larger than 512 pages if the IOMMU is activated,
    40 // - All physical pages occupied by the user buffer must be contiguous
    41 //   if the IOMMU is not activated.
    42 // An error code is returned if these conditions are not verified.
     24// the _bdv_lock variable guaranties exclusive access to the device.
    4325//
    4426// The SEG_IOC_BASE address must be defined in the hard_config.h file.
     
    8668
    8769///////////////////////////////////////////////////////////////////////////////
    88 // BDV global variables
     70//           Global variables
    8971///////////////////////////////////////////////////////////////////////////////
    9072
    9173extern spin_lock_t  _bdv_lock;
     74
     75extern unsigned int _bdv_gtid;
     76
    9277extern unsigned int _bdv_status;
    93 extern unsigned int _bdv_gtid;
    9478
    9579///////////////////////////////////////////////////////////////////////////////////
     
    10488
    10589///////////////////////////////////////////////////////////////////////////////////
    106 // Transfer data from the block device to a memory buffer.
    107 // - mode     : BOOT / KERNEL / USER
     90// Transfer data to/from the block device from/to a memory buffer.
     91// - use_irq  : descheduling + IRQ if non zero / polling if zero
     92// - to_mem   : from external storage to memory when non 0.
    10893// - lba      : first block index on the block device
    109 // - buffer   : base address of the memory buffer (must be word aligned)
    110 // - count    : number of blocks to be transfered.
    111 // Returns 0 if success, > 0 if error.
    112 ////////////////////////////////////////////////////////////////////////////////////
    113 extern unsigned int _bdv_read(  unsigned int       mode,
    114                                 unsigned int       lba,
    115                                 unsigned long long buffer,
    116                                 unsigned int       count );
    117 
    118 ///////////////////////////////////////////////////////////////////////////////////
    119 // Transfer data from a memory buffer to the block device.
    120 // - mode     : BOOT / KERNEL / USER
    121 // - lba      : first block index on the block device
    122 // - buffer   : base address of the memory buffer (must be word aligned)
     94// - buffer   : pbase address of the memory buffer (must be word aligned)
    12395// - count    : number of blocks to be transfered.
    12496// Returns 0 if success, > 0 if error.
    12597///////////////////////////////////////////////////////////////////////////////////
    126 extern unsigned int _bdv_write( unsigned int       mode,
    127                                 unsigned int       lba,
    128                                 unsigned long long buffer,
    129                                 unsigned int       count );
    130 
    131 ///////////////////////////////////////////////////////////////////////////////////
    132 // Returns device status.
    133 ///////////////////////////////////////////////////////////////////////////////////
    134 extern unsigned int _bdv_get_status();
    135 
    136 ///////////////////////////////////////////////////////////////////////////////////
    137 // Returns block size.
    138 ///////////////////////////////////////////////////////////////////////////////////
    139 extern unsigned int _bdv_get_block_size();
     98extern unsigned int _bdv_access( unsigned int       use_irq,
     99                                 unsigned int       to_mem,
     100                                 unsigned int       lba,
     101                                 unsigned long long buffer,
     102                                 unsigned int       count );
    140103
    141104///////////////////////////////////////////////////////////////////////////////////
  • soft/giet_vm/giet_drivers/dma_driver.c

    r496 r529  
    8888
    8989////////////////////////////////////////////////
    90 unsigned int _dma_init( unsigned int cluster_xy,
    91                         unsigned int channel_id )
    92 {
    93 #if NB_DMA_CHANNELS > 0
    94 
    95     // parameters checking
     90void _dma_disable_irq( unsigned int cluster_xy,
     91                       unsigned int channel_id )
     92{
     93#if NB_DMA_CHANNELS > 0
     94
     95    // check DMA channel parameters
    9696    unsigned int x = cluster_xy >> Y_WIDTH;
    9797    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    98     if (x >= X_SIZE)                    return 1;
    99     if (y >= Y_SIZE)                    return 1;
    100     if (channel_id >= NB_DMA_CHANNELS)  return 1;
     98    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (channel_id >= NB_DMA_CHANNELS) )
     99    {
     100        _puts("\n[DMA ERROR] in _dma_disable_irq() : illegal DMA channel ");
     101        _exit();
     102    }
    101103
    102104    // disable interrupt for selected channel
    103105    _dma_set_register(cluster_xy, channel_id, DMA_IRQ_DISABLE, 1);
    104     return 0;
    105 #else
    106     return 1;
    107 #endif
    108 }
    109 
    110 //////////////////////////////////////////////////
    111 unsigned int _dma_reset( unsigned int cluster_xy,
     106
     107#endif
     108}
     109
     110/////////////////////////////////////////////////
     111void _dma_reset_channel( unsigned int cluster_xy,
    112112                         unsigned int channel_id )
    113113{
    114114#if NB_DMA_CHANNELS > 0
    115115
    116     // parameters checking
     116    // check DMA channel parameters
    117117    unsigned int x = cluster_xy >> Y_WIDTH;
    118118    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    119     if (x >= X_SIZE)                    return 1;
    120     if (y >= Y_SIZE)                    return 1;
    121     if (channel_id >= NB_DMA_CHANNELS)  return 1;
     119    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (channel_id >= NB_DMA_CHANNELS) )
     120    {
     121        _puts("\n[DMA ERROR] in _dma_reset_channel() : illegal DMA channel ");
     122        _exit();
     123    }
    122124
    123125    // reset selected channel
    124126    _dma_set_register(cluster_xy, channel_id, DMA_RESET, 0);
    125     return 0;
    126 #else
    127     return 1;
    128 #endif
    129 }
    130 
    131 //////////////////////////////////////////////////////
    132 unsigned int _dma_get_status( unsigned int cluster_xy,
    133                               unsigned int channel_id )
    134 {
    135 #if NB_DMA_CHANNELS > 0
    136 
    137     // parameters checking
     127
     128#endif
     129}
     130
     131///////////////////////////////////////////////////////
     132void _dma_get_status( unsigned int  cluster_xy,
     133                      unsigned int  channel_id,
     134                      unsigned int* status )
     135{
     136#if NB_DMA_CHANNELS > 0
     137
     138    // check DMA channel parameters
    138139    unsigned int x = cluster_xy >> Y_WIDTH;
    139140    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    140     if (x >= X_SIZE)                    return 1;
    141     if (y >= Y_SIZE)                    return 1;
    142     if (channel_id >= NB_DMA_CHANNELS)  return 1;
    143 
    144     // get selected channel status
    145     return _dma_get_register(cluster_xy, channel_id, DMA_LEN);
    146 #else
    147     return DMA_IDLE;
     141    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (channel_id >= NB_DMA_CHANNELS) )
     142    {
     143        _puts("\n[DMA ERROR] in _dma_get_status() : illegal DMA channel ");
     144        _exit();
     145    }
     146
     147    // returns selected channel status
     148    *status = _dma_get_register(cluster_xy, channel_id, DMA_LEN);
     149
    148150#endif
    149151}
     
    157159{
    158160#if NB_DMA_CHANNELS > 0
     161
     162    // check DMA channel parameters
     163    unsigned int x = cluster_xy >> Y_WIDTH;
     164    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     165    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (channel_id >= NB_DMA_CHANNELS) )
     166    {
     167        _puts("\n[DMA ERROR] in _dma_start_transfer() : illegal DMA channel ");
     168        _exit();
     169    }
    159170
    160171    // selected channel configuration and lauching
     
    169180    _dma_set_register(cluster_xy, channel_id, DMA_LEN,
    170181            (unsigned int)size);
    171 
    172182#endif
    173183}
     
    176186void _dma_physical_copy( unsigned int       cluster_xy,  // DMA cluster
    177187                         unsigned int       channel_id,  // DMA channel
    178                          unsigned long long dst_paddr,   // destination physical address
    179                          unsigned long long src_paddr,   // source physical address
     188                         unsigned long long dst_paddr,   // dest physical address
     189                         unsigned long long src_paddr,   // src physical address
    180190                         unsigned int       size )       // bytes
    181191{
    182192#if NB_DMA_CHANNELS > 0
    183 
    184     // check DMA channel parameters
    185     unsigned int x = cluster_xy >> Y_WIDTH;
    186     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    187     if ( (x >= X_SIZE) || (y >= Y_SIZE) || (channel_id >= NB_DMA_CHANNELS) )
    188     {
    189         _puts("\n[DMA ERROR] in _dma_physical_copy() : illegal DMA channel ");
    190         _exit();
    191     }
    192193
    193194    // check buffers alignment constraints
     
    199200
    200201#if GIET_DEBUG_DMA_DRIVER
     202unsigned int x = cluster_xy >> Y_WIDTH;
     203unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    201204_puts("\n[DMA DEBUG] enter _dma_physical_copy() for channel[");
    202205_putd( x );
     
    212215_putl( dst_paddr );
    213216_puts("\n - bytes       = ");
    214 _putd( size );
    215 _puts("\n");
    216 #endif
    217 
    218     // dma channel configuration & lauching
     217_putx( size );
     218_puts("\n");
     219#endif
     220
     221    // dma channel configuration
     222    _dma_disable_irq( cluster_xy, channel_id );
     223
     224    // dma transfer lauching
    219225    _dma_start_transfer( cluster_xy, channel_id, dst_paddr, src_paddr, size );
    220226
    221227    // scan dma channel status
    222     unsigned int status = _dma_get_status( cluster_xy, channel_id );
     228    unsigned int status;
     229    do
     230    {
     231        _dma_get_status( cluster_xy, channel_id , &status );
     232
     233#if GIET_DEBUG_DMA_DRIVER
     234_puts("\n[DMA DEBUG] _dma_physical_copy() : ... waiting on DMA_STATUS\n");
     235#endif
     236
     237    }
    223238    while( (status != DMA_SUCCESS) &&
    224239           (status != DMA_READ_ERROR) &&
    225            (status != DMA_WRITE_ERROR) )
    226     {
    227         status = _dma_get_status( cluster_xy, channel_id );
    228 
    229 #if GIET_DEBUG_DMA_DRIVER
    230 _puts("\n[DMA DEBUG] _dma_physical_copy() : ... waiting on DMA_STATUS register\n");
    231 #endif
    232 
    233     }
     240           (status != DMA_WRITE_ERROR) );
    234241   
    235242    // analyse status
    236243    if( status != DMA_SUCCESS )
    237244    {
    238         _puts("\n[DMA ERROR] in _dma_physical_copy() : bad DMA_STATUS");
     245        _puts("\n[DMA ERROR] in _dma_physical_copy() : ERROR_STATUS");
    239246        _exit();
    240247    }
    241248
    242249    // reset dma channel
    243     _dma_reset( cluster_xy, channel_id );
     250    _dma_reset_channel( cluster_xy , channel_id );
    244251
    245252#if GIET_DEBUG_DMA_DRIVER
     
    261268void  _dma_copy( unsigned int cluster_xy,    // DMA cluster
    262269                 unsigned int channel_id,    // DMA channel
    263                  unsigned int vspace_id,     // vspace index for v2p translation
    264270                 unsigned int dst_vaddr,     // dst_vaddr buffer vbase
    265271                 unsigned int src_vaddr,     // src_vaddr buffer vbase
     
    268274#if NB_DMA_CHANNELS > 0
    269275
    270     // check DMA channel parameters
    271     unsigned int x = cluster_xy >> Y_WIDTH;
    272     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    273     if ( (x >= X_SIZE) || (y >= Y_SIZE) || (channel_id >= NB_DMA_CHANNELS) )
    274     {
    275         _puts("\n[DMA ERROR] in _dma_copy() : illegal DMA channel ");
    276         _exit();
    277     }
    278 
    279276    // check buffers alignment constraints
    280277    if ( (dst_vaddr & 0x3)   || (src_vaddr & 0x3) || (size & 0x3) )
     
    284281    }
    285282
    286     unsigned int ppn;
     283    unsigned long long src_paddr;
     284    unsigned long long dst_paddr;
    287285    unsigned int flags;
    288286
    289287#if GIET_DEBUG_DMA_DRIVER
     288unsigned int x = cluster_xy >> Y_WIDTH;
     289unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    290290_puts("\n[DMA DEBUG] enter _dma_copy() for channel[");
    291291_putd( x );
     
    305305#endif
    306306
    307     // checking alignment constraints
    308     if ( (((unsigned int)dst_vaddr) & 0x3) ||
    309          (((unsigned int)src_vaddr) & 0x3) ||
    310          (size & 0x3) )
    311     {
    312         _puts("\n[DMA ERROR] in _dma_copy() : buffer unaligned\n");
    313         _exit();
    314     }
    315 
    316     // get vspace page table pointer
    317     unsigned int pt = _ptabs_vaddr[vspace_id];
    318 
    319307    // get src_paddr buffer physical addresse
    320     _v2p_translate( (page_table_t*)pt,              // page table pointer
    321                      src_vaddr>>12,                  // vpn
    322                      &ppn,                           // ppn
    323                      &flags );                       // flags
    324     unsigned long long src_paddr = (((unsigned long long)ppn) << 12) |
    325                                    (unsigned long long)(src_vaddr & 0x00000FFF);
     308    src_paddr = _v2p_translate( src_vaddr , &flags );
    326309
    327310    // get dst_paddr buffer physical addresse
    328     _v2p_translate( (page_table_t*)pt,              // page table pointer
    329                      dst_vaddr>>12,                  // vpn
    330                      &ppn,                           // ppn
    331                      &flags );                       // flags
    332     unsigned long long dst_paddr = (((unsigned long long)ppn) << 12) |
    333                                    (unsigned long long)(dst_vaddr & 0x00000FFF);
     311    dst_paddr = _v2p_translate( dst_vaddr , &flags );
    334312
    335313#if GIET_DEBUG_DMA_DRIVER
     
    345323
    346324    // scan dma channel status
    347     unsigned int status = _dma_get_status( cluster_xy, channel_id );
     325    unsigned int status;
     326    do
     327    {
     328        _dma_get_status( cluster_xy, channel_id , &status );
     329
     330#if GIET_DEBUG_DMA_DRIVER
     331_puts("\n[DMA DEBUG] _dma_physical_copy() : ... waiting on DMA_STATUS\n");
     332#endif
     333
     334    }
    348335    while( (status != DMA_SUCCESS) &&
    349336           (status != DMA_READ_ERROR) &&
    350            (status != DMA_WRITE_ERROR) )
    351     {
    352         status = _dma_get_status( cluster_xy, channel_id );
    353 
    354 #if GIET_DEBUG_DMA_DRIVER
    355 _puts("\n[DMA DEBUG] _dma_copy() : ... waiting on DMA_STATUS register\n");
    356 #endif
    357 
    358     }
     337           (status != DMA_WRITE_ERROR) );
    359338   
    360339    // analyse status
     
    365344    }
    366345    // reset dma channel
    367     _dma_reset( cluster_xy, channel_id );
     346    _dma_reset_channel( cluster_xy, channel_id );
    368347
    369348#if GIET_DEBUG_DMA_DRIVER
     
    380359#endif
    381360} // end _dma_copy
     361
    382362
    383363/////////////////////////////////////
  • soft/giet_vm/giet_drivers/dma_driver.h

    r518 r529  
    1515//
    1616// A DMA channel is a private ressource allocated to a given processor.
    17 // It is exclusively used by the kernet to speedup data transfers, and
     17// It is exclusively used by the kernel to speedup data transfers, and
    1818// there is no lock protecting exclusive access to the channel.
    1919// As the kernel uses a polling policy on the DMA_STATUS register to detect
     
    2323//    SEG_DMA_BASE + cluster_xy * PERI_CLUSTER_INCREMENT + DMA_SPAN * channel_id
    2424//
    25 // The SEG_DMA_BASE virtual address mus be defined in the hard_config.h file.
     25// The SEG_DMA_BASE virtual address must be defined in the hard_config.h file.
    2626//////////////////////////////////////////////////////////////////////////////////
    2727
     
    6363//////////////////////////////////////////////////////////////////////////////////
    6464// This function disables interrupts for one DMA channel in one cluster.
    65 // AS the GIET-VM uses a polling policy to detect DMA transfer completion,
    66 // the DMA component initialisation must disable interrupts.
    67 // Returns 0 if success, returns > 0 if error.
     65// In case of error (illegal DMA channel), an error
     66// message is displayed on TTY0, and system crash.
    6867//////////////////////////////////////////////////////////////////////////////////
    69 extern unsigned int _dma_init( unsigned int cluster_xy,
    70                                unsigned int channel_id );
     68extern void _dma_disable_irq( unsigned int cluster_xy,
     69                              unsigned int channel_id );
    7170
    7271//////////////////////////////////////////////////////////////////////////////////
    7372// This function re-initialises one DMA channel in one cluster after transfer
    7473// completion. It actually forces the channel to return in IDLE state.
     74// In case of error (illegal DMA channel), an error
     75// message is displayed on TTY0, and system crash.
    7576//////////////////////////////////////////////////////////////////////////////////
    76 extern unsigned int _dma_reset( unsigned int  cluster_xy,
     77extern void _dma_reset_channel( unsigned int  cluster_xy,
    7778                                unsigned int  channel_id );
    7879
    7980//////////////////////////////////////////////////////////////////////////////////
    80 // This function returns the status of a DMA channel in a given cluster
     81// This function returns the status of a DMA channel in a given cluster.
     82// In case of error (illegal DMA channel), an error
     83// message is displayed on TTY0, and system crash.
    8184//////////////////////////////////////////////////////////////////////////////////
    82 extern unsigned int _dma_get_status( unsigned int  cluster_xy,
    83                                      unsigned int  channel_id );
     85extern void _dma_get_status( unsigned int  cluster_xy,
     86                             unsigned int  channel_id,
     87                             unsigned int* status );
    8488
    8589//////////////////////////////////////////////////////////////////////////////////
     
    8791// for the source and destination buffers in a DMA channel in a given cluster
    8892// and sets the transfer size to lauch the transfer.
     93// In case of error (illegal DMA channel), an error
     94// message is displayed on TTY0, and system crash.
    8995//////////////////////////////////////////////////////////////////////////////////
    9096extern void _dma_start_transfer( unsigned int       cluster_xy,
     
    118124// This function copies a source memory buffer to a destination memory buffer,
    119125// making virtual to physical address translation: the MMU should be activated.
    120 // This blocking function is supposed to be used by the kernel only,
    121 // and uses a polling policy on DMA_STATUS register to detect completion.
    122 // Therefore, the DMA_IRQ is NOT used.
    123126// The source and destination buffers base addresses must be word aligned,
    124127// and the buffer's size must be multiple of 4.
     
    128131extern void _dma_copy(  unsigned int cluster_xy,
    129132                        unsigned int channel_id,
    130                         unsigned int vspace_id,
    131133                        unsigned int dst_vaddr,
    132134                        unsigned int src_vaddr,
     
    134136
    135137//////////////////////////////////////////////////////////////////////////////////
    136 // This ISR should not be used by the GIET_VM, because the DMA is only
    137 // used by the kernel in the boot phase, with a polling strategy.
     138// Interrupt Service Routine.
    138139//////////////////////////////////////////////////////////////////////////////////
    139140extern void _dma_isr( unsigned int irq_type,
  • soft/giet_vm/giet_drivers/hba_driver.c

    r481 r529  
    1 ///////////////////////////////////////////////////////////////////////////////////
     1//////////////////////////////////////////////////////////////////////////////////
    22// File     : hba_driver.c
    33// Date     : 23/11/2013
     
    66///////////////////////////////////////////////////////////////////////////////////
    77// Implementation notes:
    8 // 1. In order to share code, the two _hba_read() and _hba_write() functions
    9 //    call the same _hba_set_cmd() function.
    10 // 2. All accesses to HBA registers are done by the two
    11 //    _hba_set_register() and _hba_get_register() low-level functions,
    12 //    that are handling virtual / physical extended addressing.
     8// All accesses to HBA registers are done by the two
     9// _hba_set_register() and _hba_get_register() low-level functions,
     10// that are handling virtual / physical extended addressing.
    1311///////////////////////////////////////////////////////////////////////////////////
    1412
    1513#include <giet_config.h>
    16 #include <ioc_driver.h>
     14#include <hard_config.h>
     15#include <hba_driver.h>
     16#include <xcu_driver.h>
     17#include <kernel_locks.h>
    1718#include <utils.h>
    1819#include <tty0.h>
    19 #include <iob_driver.h>
    2020#include <ctx_handler.h>
    21 #include <mmc_driver.h>
    22 #include <hba_driver.h>
     21#include <irq_handler.h>
    2322#include <vmem.h>
    2423
    25 #if !defined( NB_IOC_CHANNELS )
    26 # error: You must define NB_IOC_CHANNELS in the hard_config.h file
    27 #endif
    28 
    29 #if ( NB_IOC_CHANNELS > 8 )
    30 # error: NB_IOC_CHANNELS cannot be larger than 8
    31 #endif
    32 
    33 #define in_unckdata __attribute__((section (".unckdata")))
    34 
    35 //////////////////////////////////////////////////////////////////
     24///////////////////////////////////////////////////////////////////////////////////
    3625//               Global variables
    37 //////////////////////////////////////////////////////////////////
    38 
    39 // command list array (one per channel)
    40 hba_cmd_list_t   hba_cmd_list[NB_IOC_CHANNELS] __attribute__((aligned(0x1000)));   
    41 
    42 // command tables array (32 command tables per channel)
    43 hba_cmd_table_t  hba_cmd_table[NB_IOC_CHANNELS][32] __attribute__((aligned(0x1000)));
    44 
    45 // command list physical addresses array (one per channel)
    46 paddr_t          hba_cmd_list_paddr[NB_IOC_CHANNELS];
    47 
    48 // command tables physical addresses array (32 command tables per channel)
    49 paddr_t          hba_cmd_table_paddr[NB_IOC_CHANNELS][32];
    50 
    51 // command list pointer array (one per channel)
    52 unsigned int     hba_cmd_slot[NB_IOC_CHANNELS];
     26///////////////////////////////////////////////////////////////////////////////////
     27
     28// global index ot the task, for each entry in the command list
     29__attribute__((section(".kdata")))
     30unsigned int _hba_gtid[32];
     31
     32// status of the command, for each entry in the command list
     33__attribute__((section(".kdata")))
     34unsigned int _hba_status[32];
     35
     36// command list : up to 32 commands
     37__attribute__((section(".kdata")))
     38hba_cmd_desc_t  _hba_cmd_list[32] __attribute__((aligned(0x1000)));   
     39
     40// command tables array : one command table per entry in command list
     41__attribute__((section(".kdata")))
     42hba_cmd_table_t _hba_cmd_table[32] __attribute__((aligned(0x1000)));
     43
     44// command list write index : next slot to register a command
     45__attribute__((section(".kdata")))
     46unsigned int     _hba_cmd_ptw;
     47
     48// command list read index : next slot to poll a completed command
     49__attribute__((section(".kdata")))
     50unsigned int     _hba_cmd_ptr;
    5351
    5452//////////////////////////////////////////////////////////////////////////////
    55 // This low level function returns the value of register (channel / index)
     53// This low level function returns the value of register (index)
    5654//////////////////////////////////////////////////////////////////////////////
    57 unsigned int _hba_get_register( unsigned int channel,
    58                                 unsigned int index )
    59 {
    60     unsigned int* vaddr = (unsigned int*)SEG_IOC_BASE + channel*HBA_SPAN + index;
     55unsigned int _hba_get_register( unsigned int index )
     56{
     57    unsigned int* vaddr = (unsigned int*)SEG_IOC_BASE + index;
    6158    return _io_extended_read( vaddr );
    6259}
    6360
    6461//////////////////////////////////////////////////////////////////////////////
    65 // This low level function set a new value in register (channel / index) 
     62// This low level function set a new value in register (index) 
    6663//////////////////////////////////////////////////////////////////////////////
    67 void _hba_set_register( unsigned int channel,
    68                         unsigned int index,
     64void _hba_set_register( unsigned int index,
    6965                        unsigned int value )
    7066{
    71     unsigned int* vaddr = (unsigned int*)SEG_IOC_BASE + channel*HBA_SPAN + index;
     67    unsigned int* vaddr = (unsigned int*)SEG_IOC_BASE + index;
    7268    _io_extended_write( vaddr, value );
    7369}
    7470
     71///////////////////////////////////////////////////////////////////////////////
     72//      Extern functions
     73///////////////////////////////////////////////////////////////////////////////
    7574
    7675///////////////////////////////////////////////////////////////////////////////
    7776// This function register a command in both the command list
    7877// and the command table, and updates the HBA_PXCI register.
    79 // It uses the AHCI Scatter/Gather mechanisme to split the user
    80 // buffer in several physical buffers, with the constraint that each physical
    81 // buffer must be an integer number of blocks entirely contained in a single
    82 // page frame.
    8378// return 0 if success, -1 if error
    8479///////////////////////////////////////////////////////////////////////////////
    85 unsigned int _hba_cmd_set( unsigned int  channel,     // channel index
    86                            unsigned int  is_read,     // to memory
    87                            unsigned int  lba,         // logic block address
    88                            paddr_t       buffer,      // buffer physical address
    89                            unsigned int  count )      // number of blocks
    90 {
    91     unsigned int       block_size;     // defined by the block device (bytes)
    92     unsigned int       pxci;           // command list status
    93     unsigned int       cmd_id;         // command index in command list
    94 
     80unsigned int _hba_access( unsigned int       use_irq,
     81                          unsigned int       to_mem,
     82                          unsigned int       lba, 
     83                          unsigned long long buf_paddr,
     84                          unsigned int       count )   
     85{
     86    unsigned int procid  = _get_procid();
     87    unsigned int x       = procid >> (Y_WIDTH + P_WIDTH);
     88    unsigned int y       = (procid >> P_WIDTH) & ((1<<Y_WIDTH) - 1);
     89    unsigned int p       = procid & ((1<<P_WIDTH)-1);
     90
     91#if GIET_DEBUG_IOC_DRIVER
     92_printf("\n[HBA DEBUG] P[%d,%d,%d] enters _hba_access at cycle %d\n"
     93        "  use_irq = %d / to_mem = %d / lba = %x / paddr = %l / count = %d\n",
     94        x , y , p , _get_proctime() , use_irq , to_mem , lba , buf_paddr, count );
     95#endif
     96
     97    unsigned int       pxci;           // HBA_PXCI register value
     98    unsigned int       ptw;            // command list write pointer
     99    unsigned int       pxis;           // HBA_PXIS register value
    95100    hba_cmd_desc_t*    cmd_desc;       // command descriptor pointer   
    96101    hba_cmd_table_t*   cmd_table;      // command table pointer
    97102
    98     block_size = _hba_get_block_size();
    99 
    100103    // check buffer alignment
    101     if( buffer & (block_size-1) )
    102     {
    103         _puts("\n[GIET ERROR] in _hba_set_cmd() : user buffer not block aligned\n");
     104    if( buf_paddr & 0x1FF )
     105    {
     106        _printf("\n[HBA ERROR] in _hba_access() : buffer not block aligned\n");
    104107        return -1;
    105108    }
    106109
    107     // get command list status from PXCI register
    108     pxci = _hba_get_register( channel, HBA_PXCI );
    109 
    110     // get command index and return error if command list full
    111     cmd_id = hba_cmd_slot[channel];
    112     if( pxci & (1<<cmd_id ) )
    113     {
    114         _puts("\n[GIET ERROR] in _hba_set_cmd() : command list full for channel ");
    115         _putd( channel );
    116         _puts("\n");
    117         return -1;
    118     }
    119 
     110    // get pointer on the next possible entry in command list
     111    ptw = _atomic_increment( &_hba_cmd_ptw , 1 );
     112
     113    // poll PXCI register until pointed entry empty
     114    do
     115    {
     116        // get PXCI register
     117        pxci = _hba_get_register( HBA_PXCI );
     118    }
     119    while ( pxci & (1<<ptw) );
     120   
    120121    // compute pointers on command descriptor and command table   
    121     cmd_desc  = (hba_cmd_desc_t*)(&(hba_cmd_list[channel].desc[cmd_id]));
    122     cmd_table = (hba_cmd_table_t*)(&(hba_cmd_table[channel][cmd_id]));
     122    cmd_desc  = &_hba_cmd_list[ptw];
     123    cmd_table = &_hba_cmd_table[ptw];
    123124
    124125    // set  buffer descriptor in command table
    125     cmd_table->entry[0].dba  = (unsigned int)(buffer);
    126     cmd_table->entry[0].dbau = (unsigned int)(buffer >> 32);
    127     cmd_table->entry[0].dbc  = count * block_size;
     126    cmd_table->entry[0].dba  = (unsigned int)(buf_paddr);
     127    cmd_table->entry[0].dbau = (unsigned int)(buf_paddr >> 32);
     128    cmd_table->entry[0].dbc  = count * 512;
    128129
    129130    // initialize command table header
     
    138139    cmd_desc->prdtl[0] = 1;
    139140    cmd_desc->prdtl[1] = 0;
    140     cmd_desc->ctba     = (unsigned int)(hba_cmd_table_paddr[channel][cmd_id]);
    141     cmd_desc->ctbau    = (unsigned int)(hba_cmd_table_paddr[channel][cmd_id]>>32);
    142     if( is_read ) cmd_desc->flag[0] = 0x00;
    143     else          cmd_desc->flag[0] = 0x40;     
     141    if( to_mem ) cmd_desc->flag[0] = 0x00;
     142    else         cmd_desc->flag[0] = 0x40;     
    144143   
    145     // update PXCI register
    146     _hba_set_register( channel, HBA_PXCI, (1<<cmd_id) );
    147 
    148     // update command pointer
    149     hba_cmd_slot[channel] = (cmd_id + 1)%32;
    150 
    151     return  0;
    152 }
    153 
    154 /* This can be used for a future use with buffer in virtual space
    155 
    156     // get user space page table virtual address
    157     user_pt_vbase     = _get_context_slot(CTX_PTAB_ID);
    158     vpn_min           = buf_vaddr >> 12;
    159     vpn_max           = (buf_vaddr + (block_size*count) - 1) >> 12;
    160     offset            = buf_vaddr & 0xFFF;
    161     offset_last       = (buf_vaddr + (block_size*count) - 1) & 0xFFF;
    162 
    163     // initialize all buffer descriptors in command table
    164     // (loop on all virtual pages covering the user buffer)
    165     for( vpn = vpn_min, buf_id = 0 ; vpn <= vpn_max ; vpn++ )
    166     {
    167         paddr_t      paddr;
    168         unsigned int count;
    169         unsigned int ppn;
    170         unsigned int flags;
    171         unsigned int ko;
    172         unsigned int buf_id = 0;
    173 
    174         // get ppn and flags
    175         _v2p_translate( (page_table_t*)user_pt_vbase,
    176                         vpn,
    177                         &ppn,
    178                         &flags );
    179 
    180         // check access rights
    181         if ((flags & PTE_U) == 0)
     144    // set command in PXCI[ptw]
     145    _hba_set_register( HBA_PXCI, pxci + (1<<ptw) );
     146
     147
     148    /////////////////////////////////////////////////////////////////////
     149    // In synchronous mode, we poll the PXCI register until completion
     150    /////////////////////////////////////////////////////////////////////
     151    if ( use_irq == 0 )
     152    {
     153
     154#if GIET_DEBUG_IOC_DRIVER
     155_printf("\n[HBA DEBUG] _hba_access() : P[%d,%d,%d] launch transfer"
     156        " in polling mode at cycle %d\n",
     157        x , y , p , _get_proctime() );
     158#endif
     159        // disable IRQs in PXIE register
     160        _hba_set_register( HBA_PXIE , 0 );
     161
     162        // poll PXCI[ptw] until command completed by HBA
     163        do
    182164        {
    183             _puts("[GIET ERROR] in _hba_set_cmd() : user buffer not in user space\n");
    184             return -1;
     165            pxci = _hba_get_register( HBA_PXCI ) & (1<<ptw);
     166
     167#if GIET_DEBUG_IOC_DRIVER
     168_printf("\n[HBA DEBUG] _hba_access() : P[%d,%d,%d] wait on HBA_STATUS ...\n",
     169        x , y , p );
     170#endif
    185171        }
    186         if (((flags & PTE_W) == 0 ) && (is_read == 0) )
     172        while( pxci & (1<<ptw) );
     173             
     174        // get PXIS register
     175        pxis = _hba_get_register( HBA_PXIS );
     176
     177        // reset PXIS register
     178        _hba_set_register( HBA_PXIS , 0 );
     179    }
     180
     181    /////////////////////////////////////////////////////////////////
     182    // in descheduling mode, we deschedule the task
     183    // and use an interrupt to reschedule the task.
     184    // We need a critical section, because we must reset the RUN bit
     185        // before to launch the transfer, and we don't want to be
     186    // descheduled between these two operations.
     187    /////////////////////////////////////////////////////////////////
     188    else
     189    {
     190
     191#if GIET_DEBUG_IOC_DRIVER
     192_printf("\n[HBA DEBUG] _hba_access() : P[%d,%d,%d] launch transfer"
     193        " in descheduling mode at cycle %d\n",
     194        x , y , p , _get_proctime() );
     195#endif
     196        unsigned int save_sr;
     197        unsigned int ltid = _get_current_task_id();
     198
     199        // activates HBA interrupts
     200        _hba_set_register( HBA_PXIE , 0x00000001 );
     201
     202        // set _hba_gtid[ptw]
     203        _hba_gtid[ptw] = (procid<<16) + ltid;
     204
     205        // enters critical section
     206        _it_disable( &save_sr );
     207
     208        // reset runnable
     209        _set_task_slot( x, y, p, ltid, CTX_RUN_ID, 0 ); 
     210
     211        // deschedule task
     212        _ctx_switch();                     
     213
     214#if GIET_DEBUG_IOC_DRIVER
     215_printf("\n[HBA DEBUG] _hba_access() : P[%d,%d,%d] resume execution at cycle %d\n",
     216        x , y , p , _get_proctime() );
     217#endif
     218
     219        // restore SR
     220        _it_restore( &save_sr );
     221
     222        // get command status
     223        pxis = _hba_status[ptw];
     224    }   
     225
     226#if GIET_DEBUG_IOC_DRIVER
     227_printf("\n[HBA DEBUG] _hba_access() : P[%d,%d,%d] exit at cycle %d\n",
     228        x , y , p , _get_proctime() );
     229#endif
     230
     231    if ( pxis & 0x40000000 ) return pxis;
     232    else                     return 0;
     233
     234} // end _hba_access()
     235
     236
     237////////////////////////
     238unsigned int _hba_init()
     239{
     240    unsigned int       flags;
     241    unsigned int       vaddr;
     242    unsigned long long paddr;
     243    unsigned int       c;     
     244    unsigned int       pxclb;
     245    unsigned int       pxclbu;
     246
     247    // command list pointers
     248    _hba_cmd_ptw = 0;
     249    _hba_cmd_ptr = 0;
     250
     251    // Command list physical addresse
     252    vaddr  = (unsigned int)(_hba_cmd_list);
     253    paddr  = _v2p_translate( vaddr , &flags );
     254    pxclb  = (unsigned int)paddr;
     255    pxclbu = (unsigned int)(paddr>>32);
     256
     257    // Command tables physical addresses
     258    for( c=0 ; c<32 ; c++ )
     259    {
     260        // compute command table physical address
     261        // for one entry in the command list
     262        vaddr = (unsigned int)(&_hba_cmd_table[c]);
     263        paddr = _v2p_translate( vaddr , &flags );
     264
     265        // initialise the corresponding command descriptor
     266        _hba_cmd_list[c].ctba  = (unsigned int)paddr;
     267        _hba_cmd_list[c].ctbau = (unsigned int)(paddr>>32);
     268    }
     269
     270    // set HBA registers
     271    _hba_set_register( HBA_PXCLB , pxclb  );
     272    _hba_set_register( HBA_PXCLBU, pxclbu );
     273    _hba_set_register( HBA_PXIE  , 0      );
     274    _hba_set_register( HBA_PXIS  , 0      );
     275    _hba_set_register( HBA_PXCI  , 0      );
     276    _hba_set_register( HBA_PXCMD , 1      );
     277
     278    return 0;
     279}
     280
     281
     282/////////////////////////////////////
     283void _hba_isr( unsigned int irq_type,   // HWI / WTI
     284               unsigned int irq_id,     // index returned by ICU
     285               unsigned int channel )   // unused
     286{
     287    // get HBA_PXCI containing commands status
     288    unsigned int pxci = _hba_get_register( HBA_PXCI );
     289
     290    // scan active commands from (_hba_cmd_ptr) to (_hba_cmd_ptw-1)
     291    unsigned int c;
     292    for ( c = _hba_cmd_ptr ;
     293          c != _hba_cmd_ptw ;
     294          c = (c + 1) % 32 )
     295    {
     296        if ( (pxci & (1<<c)) == 0 )    // command completed
    187297        {
    188             _puts("[GIET ERROR] in _hba_set_cmd() : user buffer not writable\n");
    189             return -1;
     298            // increment read pointer;
     299            _hba_cmd_ptr++;
     300
     301            // save PXIS register
     302            _hba_status[c] = _hba_get_register( HBA_PXIS );
     303
     304            // reset PXIS register
     305            _hba_set_register( HBA_PXIS , 0 );
     306 
     307            // identify waiting task
     308            unsigned int remote_procid  = _hba_gtid[c]>>16;
     309            unsigned int ltid           = _hba_gtid[c] & 0xFFFF;
     310            unsigned int remote_cluster = remote_procid >> P_WIDTH;
     311            unsigned int remote_x       = remote_cluster >> Y_WIDTH;
     312            unsigned int remote_y       = remote_cluster & ((1<<Y_WIDTH)-1);
     313            unsigned int remote_p       = remote_procid & ((1<<P_WIDTH)-1);
     314 
     315            // re-activates waiting task
     316            _set_task_slot( remote_x,
     317                            remote_y,
     318                            remote_p,
     319                            ltid,
     320                            CTX_RUN_ID,
     321                            1 );
     322
     323            // send a WAKUP WTI to processor running the waiting task
     324            _xcu_send_wti( remote_cluster ,
     325                           remote_p ,
     326                           0 );          // don't force context switch
     327
     328#if GIET_DEBUG_IOC_DRIVER 
     329unsigned int procid  = _get_procid();
     330unsigned int x       = procid >> (Y_WIDTH + P_WIDTH);
     331unsigned int y       = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
     332unsigned int p       = procid & ((1<<P_WIDTH)-1);
     333_printf("\n[HBA DEBUG] Processor[%d,%d,%d] executes _hba_isr() :\n"
     334        "  resume task %d running on P[%d,%d,%d] / status = %x at cyle %d\n",
     335        x , y , p ,
     336        ltid , remote_x , remote_y , remote_p , _hba_status[c] , _get_proctime() );
     337#endif
    190338        }
    191 
    192         // check buffer index overflow
    193         if( buf_id > 245 )
     339        else                         // command non completed
    194340        {
    195             _puts("[GIET ERROR] in _hba_set_cmd() : max number of buffers is 248\n");
    196             return -1;   
    197         }
    198 
    199         // buffer allocation
    200         if( vpn == vpn_min )       // first page: one single buffer
    201         {
    202             paddr = (((paddr_t)ppn) << 12) + offset;
    203             count = 0x1000 - offset;
    204             cmd_table->entry[buf_id].dba  = (unsigned int)(paddr);
    205             cmd_table->entry[buf_id].dbau = (unsigned int)(paddr >> 32);
    206             cmd_table->entry[buf_id].dbc  = count;
    207 
    208             buf_id++;
    209         }
    210         else if( vpn == vpn_max )  // last page: one single buffer
    211         {
    212             paddr = (((paddr_t)ppn) << 12);
    213             count = offset_last;
    214             cmd_table->entry[buf_id].dba  = (unsigned int)(paddr);
    215             cmd_table->entry[buf_id].dbau = (unsigned int)(paddr >> 32);
    216             cmd_table->entry[buf_id].dbc  = count;
    217 
    218             buf_id++;
    219         }
    220         else if( offset )          // midle page and offset != 0: two buffers 
    221         {
    222             paddr = (((paddr_t)ppn) << 12);
    223            
    224             count = offset;
    225             cmd_table->entry[buf_id].dba  = (unsigned int)(paddr);
    226             cmd_table->entry[buf_id].dbau = (unsigned int)(paddr >> 32);
    227             cmd_table->entry[buf_id].dbc  = count;
    228 
    229             buf_id++;
    230 
    231             paddr = (((paddr_t)ppn) << 12) + offset;
    232             count = 0x1000 - offset;
    233             cmd_table->entry[buf_id].dba  = (unsigned int)(paddr);
    234             cmd_table->entry[buf_id].dbau = (unsigned int)(paddr >> 32);
    235             cmd_table->entry[buf_id].dbc  = count;
    236 
    237             buf_id++;
    238         }
    239         else                      // middle page and offset == 0: one buffer
    240         {
    241             paddr = (((paddr_t)ppn) << 12);
    242             count = 0x1000;
    243             cmd_table->entry[buf_id].dba  = (unsigned int)(paddr);
    244             cmd_table->entry[buf_id].dbau = (unsigned int)(paddr >> 32);
    245             cmd_table->entry[buf_id].dbc  = count;
    246 
    247             buf_id++;
     341            break;
    248342        }
    249343    }
    250 */
    251 
    252 
    253 //////////////////////////////////////////////
    254 unsigned int _hba_init( unsigned int channel )
    255 {
    256     unsigned int ppn;
    257     unsigned int flags;
    258     unsigned int vbase;
    259     unsigned int c;               // c == command index
    260 
    261     // get page_table pointer
    262     unsigned int pt = _get_context_slot(CTX_PTAB_ID);
    263 
    264     // HBA registers TODO: ne faut_il pas un V2P pour PXCLB/PXCLBU ? (AG)
    265     _hba_set_register( channel, HBA_PXCLB , (unsigned int)&hba_cmd_list[channel] );
    266     _hba_set_register( channel, HBA_PXCLBU, 0 );
    267     _hba_set_register( channel, HBA_PXIE  , 0x40000001 );
    268     _hba_set_register( channel, HBA_PXIS  , 0 );
    269     _hba_set_register( channel, HBA_PXCI  , 0 );
    270     _hba_set_register( channel, HBA_PXCMD , 1 );
    271 
    272     // command list pointer       
    273     hba_cmd_slot[channel] = 0;
    274 
    275     // Command list physical addresse
    276     vbase = (unsigned int)(&hba_cmd_list[channel]);
    277     _v2p_translate( (page_table_t*)pt,
    278                      vbase>>12,
    279                      &ppn,
    280                      &flags );
    281     hba_cmd_list_paddr[channel] = ((paddr_t)ppn) | (vbase & 0xFFF);
    282 
    283     // Command tables physical addresses
    284     for( c=0 ; c<32 ; c++ )
    285     {
    286         vbase = (unsigned int)(&hba_cmd_table[channel][c]);
    287         _v2p_translate( (page_table_t*)pt,
    288                          vbase>>12,
    289                          &ppn,
    290                          &flags );
    291         hba_cmd_table_paddr[channel][c] = ((paddr_t)ppn) | (vbase & 0xFFF);
    292     }
    293 
    294     return 0;
    295 }
    296 
    297 ///////////////////////////////////////////////
    298 unsigned int _hba_write( unsigned int  channel,
    299                          unsigned int  mode,
    300                          unsigned int  lba,
    301                          paddr_t       buffer,
    302                          unsigned int  count )
    303 {
    304     return _hba_cmd_set( channel,
    305                          0,         // write
    306                          lba,
    307                          buffer,
    308                          count );
    309 }
    310 
    311 //////////////////////////////////////////////
    312 unsigned int _hba_read( unsigned int  channel,
    313                         unsigned int  mode,
    314                         unsigned int  lba,
    315                         paddr_t       buffer,
    316                         unsigned int  count )
    317 {
    318     return _hba_cmd_set( channel,
    319                          1,          // read
    320                          lba,
    321                          buffer,
    322                          count );
    323 }
    324 
    325 //////////////////////////////////
    326 unsigned int _hba_get_block_size()
    327 {
    328     // TODO The block size must be obtained from the hardware...
    329     return 512;
    330 }
    331 
    332 ////////////////////////////////////////////////////
    333 unsigned int _hba_get_status( unsigned int channel )
    334 {
    335 
    336     if( channel >= NB_IOC_CHANNELS )
    337     {
    338         _puts("\n[GIET ERROR] in _hba_get_status() : illegal channel\n");
    339         _exit();
    340     }
    341 
    342     // get HBA_PXIS value
    343     unsigned int status = _hba_get_register( channel, HBA_PXIS );
    344 
    345     // reset HBA_PXIS
    346     _hba_set_register( channel, HBA_PXIS, 0 );
    347 
    348     return status;
    349 }
     344} // end _hba_isr()
    350345
    351346// Local Variables:
  • soft/giet_vm/giet_drivers/hba_driver.h

    r437 r529  
    88// This driver supports the SocLib VciMultiAhci component, that is a multi-channels,
    99// block oriented, external storage contrÃŽler, respecting the AHCI standard.
     10//
     11// 1. Each HBA channel define an independant physical disk, but this driver
     12//    supports only channel 0, because the GIET-VM uses only one physical disk.
     13//
     14// 2. The "command list" can contain up to 32 independant commands, posted
     15//    by different user tasks. These independant transfers are handled
     16//    by the HBA device in the same order as they have been written by the
     17//    driver(s) in the command list. There is no global lock protecting the
     18//    the HBA device, but the command list being a shared structure, the driver
     19//    must use an atomic_increment() to get a slot in the command list,
     20//    and increment the write pointer.
     21//
     22// 3. This driver implements two operating mode:
     23//    - In synchronous mode, the calling task poll the HBA_PXCI register to
     24//    detect the command completion (busy waiting).
     25//    - In descheduling mode, the calling task is descheduled, and must be
     26//    restart when the command is completed.
     27//
     28// 4. As several user tasks can concurrently register commands in the command
     29//    list, and there is only one HBA interrupt, this interrupt is not linked
     30//    to a specific task. In descheduling mode, the HBA IRQ is a "global" IRQ
     31//    that is statically routed to processor P[x_io,y_io,0] in cluster_io.
     32//    The associated global HBA_ISR send a WAKUP WTI to all tasks that have
     33//    a completed command. This HBA_ISR uses a read pointer on the command
     34//    to identify the first expected command completion. The incrementation
     35//    of this read pointer does not require atomic_increment as there is
     36//    no concurrent access for this pointer.
    1037//
    1138// The SEG_IOC_BASE virtual address must be defined in the hard_config.h file.
     
    74101
    75102///////////////////////////////////////////////////////////////////////////////////
    76 // Data structures for command list array
     103// Data structure for command descriptor in command list
    77104///////////////////////////////////////////////////////////////////////////////////
    78105
     
    92119} hba_cmd_desc_t;
    93120
    94 typedef struct hba_cmd_list_s  // size = 512 bytes
    95 {
    96     // 32 command descriptors
    97     hba_cmd_desc_t desc[32];
    98 
    99 } hba_cmd_list_t;
    100 
    101121///////////////////////////////////////////////////////////////////////////////////
    102122//              access functions 
     
    110130// - the command tables physical addresses array,
    111131///////////////////////////////////////////////////////////////////////////////////
    112 extern unsigned int _hba_init ( unsigned int channel );
     132extern unsigned int _hba_init ();
    113133
    114134///////////////////////////////////////////////////////////////////////////////////
    115 // This function register a write command in Command List and Command Table
     135// This function register a command in Command List and Command Table
    116136// for a single physical buffer, and updates the HBA_PXCI register.
    117137// Returns 0 if success, > 0 if error.
    118138///////////////////////////////////////////////////////////////////////////////////
    119 extern unsigned int _hba_write( unsigned int channel,     // channel index
    120                                 unsigned int mode,        // BOOT / KERNEL / USER
    121                                 unsigned int lba,         // logic bloc address on device
    122                                 unsigned long long paddr, // memory buffer base address
    123                                 unsigned int count );     // number of blocs
     139extern unsigned int _hba_access( unsigned int       use_irq,
     140                                 unsigned int       to_mem,
     141                                 unsigned int       lba,
     142                                 unsigned long long paddr,
     143                                 unsigned int       count );
    124144
    125 //////////////////////////////////////////////////////////////////////////////////
    126 // This function register a read command in Command List and Command Table
    127 // for a single physical buffer, and updates the HBA_PXCI register.
    128 // Returns 0 if success, > 0 if error.
    129 //////////////////////////////////////////////////////////////////////////////////
    130 extern unsigned int _hba_read ( unsigned int channel,     // channel index
    131                                 unsigned int mode,        // BOOT / KERNEL / USER
    132                                 unsigned int lba,         // logic bloc address on device
    133                                 unsigned long long paddr, // memory buffer base address
    134                                 unsigned int count );     // number of blocks
    135 
    136 /////////////////////////////////////////////////////////////////////////////////
    137 // This function returns the block_size of HBA controller
    138 /////////////////////////////////////////////////////////////////////////////////
    139 extern unsigned int _hba_get_block_size ();
    140 
    141 /////////////////////////////////////////////////////////////////////////////////////
    142 // This function returns the content of the HBA_PXIS register for a given channel,
    143 // and reset this register to acknoledge IRQ.
    144 // return 0 if success, > 0 if error
    145 /////////////////////////////////////////////////////////////////////////////////////
    146 extern unsigned int _hba_get_status( unsigned int   channel );
    147 
    148 
     145///////////////////////////////////////////////////////////////////////////////////
     146// Interrupt Service Routine executed in descheduling mode.
     147///////////////////////////////////////////////////////////////////////////////////
     148extern void _hba_isr( unsigned int irq_type,
     149                      unsigned int irq_id,
     150                      unsigned int channel );
    149151#endif
    150152
  • soft/giet_vm/giet_drivers/mwr_driver.c

    r518 r529  
    1111#include <mwr_driver.h>
    1212#include <utils.h>
     13#include <kernel_locks.h>
    1314#include <tty0.h>
    1415#include <io.h>
     
    3839#endif
    3940
    40 extern unsigned int _coproc_done[X_SIZE*Y_SIZE];
     41
     42/////////////////////////////////////////////////////////////////////////////
     43//      Global variables
     44/////////////////////////////////////////////////////////////////////////////
     45
     46__attribute__((section(".kdata")))
     47simple_lock_t  _coproc_lock[X_SIZE*Y_SIZE];
     48
     49__attribute__((section(".kdata")))
     50unsigned int   _coproc_done[X_SIZE*Y_SIZE];
    4151
    4252/////////////////////////////////////////////////////////////////////////////
  • soft/giet_vm/giet_drivers/rdk_driver.c

    r456 r529  
    1 ///////////////////////////////////////////////////////////////////////////////////
     1///////////////////////////////////////////////////////////////////////////////
    22// File      : rdk_driver.c
    33// Date      : 13/02/2014
     
    55// Maintainer: cesar fuguet
    66// Copyright (c) UPMC-LIP6
    7 ///////////////////////////////////////////////////////////////////////////////////
     7///////////////////////////////////////////////////////////////////////////////
    88
    99#include <giet_config.h>
     
    1717#endif
    1818
    19 //////////////////////////////////////////////
    20 unsigned int _rdk_init( unsigned int channel )
    21 {
    22     return 0;
    23 }
    24 
    25 //////////////////////////////////////////
    26 unsigned int _rdk_read( unsigned int lba,
    27                         unsigned int buffer,
    28                         unsigned int count)
     19/////////////////////////////////////////////////////
     20unsigned int _rdk_access( unsigned int       use_irq,    // not used
     21                          unsigned int       to_mem,
     22                          unsigned int       lba,
     23                          unsigned long long buf_vaddr,  // actually vaddr
     24                          unsigned int       count)
    2925{
    3026#if USE_IOC_RDK
    3127
    3228#if GIET_DEBUG_IOC_DRIVER
    33 _puts("\n[IOC DEBUG] Enter _rdk_read() at cycle ");
    34 _putd( _get_proctime() );
    35 _puts("\n - vaddr   = ");
    36 _putx( buffer );
    37 -puts("\n - sectors = ");
    38 _putd( count );
    39 -puts("\n - lba     = ");
    40 _putx( lba );
    41 _puts("\n");
     29unsigned int procid  = _get_procid();
     30unsigned int x       = procid >> (Y_WIDTH + P_WIDTH);
     31unsigned int y       = (procid >> P_WIDTH) & ((1<<Y_WIDTH) - 1);
     32unsigned int p       = procid & ((1<<P_WIDTH)-1);
     33_printf("\n[RDK DEBUG] P[%d,%d,%d] enters _rdk_access at cycle %d\n"
     34        "  use_irq = %d / to_mem = %d / lba = %x / paddr = %x / count = %d\n",
     35        x , y , p , _get_proctime() , use_irq , to_mem , lba , buf_vaddr, count );
    4236#endif
    4337
    44     char* src = (char*)SEG_RDK_BASE + (512*lba);
    45     char* dst = (char*)buffer;
    46     memcpy( dst, src, count*512 );
     38    char* rdk = (char*)SEG_RDK_BASE + (512*lba);
     39    char* buf = (char*)buf_paddr;
     40
     41    if ( to_mem ) memcpy( buf, rdk, count*512 );
     42    else          memcpy( rdk, buf, count*512 );
     43
    4744    return 0;
    4845
    4946#else
    5047
    51     _puts("[GIET ERROR] _rdk_read() should not be used if USE_IOC_RDK not set\n");
     48    _printf("[RDK ERROR] _rdk_access() but USE_IOC_RDK not set\n");
    5249    return 1;
    5350
    5451#endif
    5552}
    56 
    57 //////////////////////////////////////////
    58 unsigned int _rdk_write( unsigned int lba,
    59                          unsigned int buffer,
    60                          unsigned int count )
    61 {
    62 #if USE_IOC_RDK
    63 
    64 #if GIET_DEBUG_IOC_DRIVER
    65 _puts("\n[IOC DEBUG] Enter _rdk_write() at cycle ");
    66 _putd( _get_proctime() );
    67 _puts("\n - vaddr   = ");
    68 _putx( buffer );
    69 -puts("\n - sectors = ");
    70 _putd( count );
    71 -puts("\n - lba     = ");
    72 _putx( lba );
    73 _puts("\n");
    74 #endif
    75 
    76     char* dst = (char*)SEG_RDK_BASE + (512*lba);
    77     char* src = (char*)buffer;
    78     memcpy( dst, src, count*512 );
    79     return 0;
    80 
    81 #else
    82 
    83     _puts("[GIET ERROR] _rdk_write() should not be used if USE_IOC_RDK not set\n");
    84     return 1;
    85 
    86 #endif
    87 }
    88 
    89 //////////////////////////////////
    90 unsigned int _rdk_get_block_size()
    91 {
    92     return 512;
    93 }
    94 
    95 //////////////////////////////
    96 unsigned int _rdk_get_status()
    97 {
    98     return 0;
    99 }
    100 
    10153
    10254// Local Variables:
  • soft/giet_vm/giet_drivers/rdk_driver.h

    r437 r529  
    1 ///////////////////////////////////////////////////////////////////////////////////
     1///////////////////////////////////////////////////////////////////////////////
    22// File      : rdk_driver.h
    33// Date      : 13/02/2014
    44// Author    : alain greiner
    55// Copyright (c) UPMC-LIP6
    6 ///////////////////////////////////////////////////////////////////////////////////
     6///////////////////////////////////////////////////////////////////////////////
    77// The rdk_driver.c and rdk_driver.h files are part ot the GIET-VM kernel.
    88//
     
    1010// in the physical address space.
    1111//
    12 // The _rdk_read() and _rdk_write() blocking functions use a software memcpy,
    13 // whatever the selected mode. They return only when the transfer is completed.
    14 // As the number of concurrent accesses is not bounded, these functions
    15 // don't use the _ioc_lock variable.
     12// The _rdk_access() function use a software memcpy to implement both the read
     13// and write accesses, whatever the selected IRQ mode. It returns only when
     14// the transfer is completed. The memory buffer address is a virtual address.
     15//
     16// As the number of concurrent accesses is not bounded, it does not use any lock.
    1617//
    1718// The SEG_RDK_BASE virtual address must be defined in the hard_config.h
    1819// file when the USE_RAMDISK flag is set.
    19 ///////////////////////////////////////////////////////////////////////////////////
     20///////////////////////////////////////////////////////////////////////////////
    2021
    2122#ifndef _GIET_RDK_DRIVERS_H_
    2223#define _GIET_RDK_DRIVERS_H_
    2324
    24 ///////////////////////////////////////////////////////////////////////////////////
    25 // BDV access functions and variables (vci_block_device)
    26 ///////////////////////////////////////////////////////////////////////////////////
    27 
    2825///////////////////////////////////////////////////////////////////////////////
    29 // This function does nothing, but is required by the IOC API.
    30 ///////////////////////////////////////////////////////////////////////////////
    31 extern unsigned int _rdk_init();
    32 
    33 ///////////////////////////////////////////////////////////////////////////////
    34 // Transfer data from a memory buffer to the RAMDISK.
    35 // - mode     : BOOT / KERNEL / USER (unused)
    36 // - lba      : first block index on the block device
    37 // - buffer   : virtual base address of the memory buffer
    38 // - count    : number of blocks to be transfered.
     26// Transfer data between a memory buffer and the RAMDISK.
     27// - use_irq   : not used: accees is always synchronous.
     28// - to_mem    : to memory buffer when non zero
     29// - lba       : first block index on the block device
     30// - buf_vaddr : virtual base address of the memory buffer
     31// - count     : number of blocks to be transfered.
    3932// Returns 0 if success, > 0 if error.
    4033///////////////////////////////////////////////////////////////////////////////
    41 extern unsigned int _rdk_write( unsigned int lba,
    42                                 unsigned int buffer,
    43                                 unsigned int count );
    44 
    45 ///////////////////////////////////////////////////////////////////////////////
    46 // Transfer data from the RAMDISK to a memory buffer.
    47 // - mode     : BOOT / KERNEL / USER (unused)
    48 // - lba      : first block index on the block device
    49 // - buffer   : virtual base address of the memory buffer
    50 // - count    : number of blocks to be transfered.
    51 // Returns 0 if success, > 0 if error.
    52 ///////////////////////////////////////////////////////////////////////////////
    53 extern unsigned int _rdk_read(  unsigned int lba,
    54                                 unsigned int buffer,
    55                                 unsigned int count );
    56 
    57 ///////////////////////////////////////////////////////////////////////////////
    58 // This function returns the block size.
    59 ///////////////////////////////////////////////////////////////////////////////
    60 extern unsigned int _rdk_get_block_size();
    61 
    62 ///////////////////////////////////////////////////////////////////////////////////
    63 // This function returns always 0, but is required by the IOC API.
    64 ///////////////////////////////////////////////////////////////////////////////
    65 extern unsigned int _rdk_get_status();
     34extern unsigned int _rdk_access( unsigned int use_irq,
     35                                 unsigned int to_mem,
     36                                 unsigned int lba,
     37                                 unsigned long long buf_vaddr,
     38                                 unsigned int count );
    6639
    6740#endif
  • soft/giet_vm/giet_drivers/sdc_driver.c

    r456 r529  
    372372    if (sdcard_rsp)
    373373    {
    374         _puts("[SDC ERROR] During SD card blocklen initialization\n");
     374        _puts("[SDC ERROR] During SD card block size initialization\n");
    375375        _exit();
    376376    }
     
    389389
    390390    return 0;
    391 }
    392 
    393 
    394 //////////////////////////////////////////
    395 unsigned int _sdc_read( unsigned int mode,
    396                         unsigned int lba,
    397                         paddr_t      buffer,
    398                         unsigned int count )
     391} // end _sdc_init()
     392
     393
     394/////////////////////////////////////////////////////
     395unsigned int _sdc_access( unsigned int       use_irq,  // unused
     396                          unsigned int       to_mem,
     397                          unsigned int       lba,
     398                          unsigned long long buf_paddr,
     399                          unsigned int       count )
    399400{
    400401    unsigned char args[4];
     
    404405    unsigned int last = lba + count;
    405406
    406     for ( ; curr < last ; curr++ )
    407     {
    408         _sdc_lseek(curr);
    409 
    410         for (i = 0; i < 4; i++)
    411         {
    412             args[i] = (sdcard.access_pointer >> (32 - (i+1)*8)) & 0xFF;
     407    if ( to_mem )  // read access
     408    {
     409        for ( ; curr < last ; curr++ )
     410        {
     411            _sdc_lseek(curr);
     412
     413            for (i = 0; i < 4; i++)
     414            {
     415                args[i] = (sdcard.access_pointer >> (32 - (i+1)*8)) & 0xFF;
     416            }
     417
     418            _sdc_enable();
     419
     420            sdcard_rsp = _sdc_send_command(17, SDCARD_CMD, args, 0x00);
     421            if ( SDCARD_CHECK_R1_ERROR(sdcard_rsp) )
     422            {
     423                _sdc_disable();
     424                return sdcard_rsp;
     425            }
     426
     427            _sdc_wait_data_block();
     428
     429            if (spi_get_data(sdcard.spi, buf_paddr, 512 ))
     430            {
     431                _sdc_disable();
     432                return 1;
     433            }
     434
     435            // Get the CRC16 (comes at the end of the data block)
     436            _sdc_receive_char(); // first byte
     437            _sdc_receive_char(); // second byte
     438
     439            _sdc_disable();
     440
     441            buf_paddr += 512;
    413442        }
    414 
    415         _sdc_enable();
    416 
    417         sdcard_rsp = _sdc_send_command(17, SDCARD_CMD, args, 0x00);
    418         if ( SDCARD_CHECK_R1_ERROR(sdcard_rsp) )
    419         {
    420             _sdc_disable();
    421             return sdcard_rsp;
    422         }
    423 
    424         _sdc_wait_data_block();
    425 
    426         if (spi_get_data(sdcard.spi, buffer, 512 ))
    427         {
    428             _sdc_disable();
    429             return 1;
    430         }
    431 
    432         // Get the CRC16 (comes at the end of the data block)
    433         _sdc_receive_char(); // first byte
    434         _sdc_receive_char(); // second byte
    435 
    436         _sdc_disable();
    437 
    438         buffer += 512;
     443    }
     444    else            // write access
     445    {
     446        _printf("[SDC ERROR] function _sdc_write() not iplemented yet\n");
     447        _exit();
    439448    }
    440449
    441450    return 0;
    442 }
    443 
    444 ///////////////////////////////////////////
    445 unsigned int _sdc_write( unsigned int mode,
    446                          unsigned int lba,
    447                          paddr_t      buffer,
    448                          unsigned int count )
    449 {
    450     _puts("[SDC ERROR] function _sdc_write() not iplemented yet\n");
    451     _exit();
    452 
    453     return 0;  // to avoid a warning
    454 }
    455 
    456 //////////////////////////////
    457 unsigned int _sdc_get_status()
    458 {
    459     _puts("[SDC ERROR] function _sdc_get_status() should not be called\n");
    460     _exit();
    461 
    462     return 0;  // to avoid a warning
    463 }
    464 
    465 //////////////////////////////////
    466 unsigned int _sdc_get_block_size()
    467 {
    468     if (sdcard.sdhc) return sdcard.block_length*512;
    469     else             return sdcard.block_length;
    470 }
     451}  // _end sdc_access()
    471452
    472453// Local Variables:
  • soft/giet_vm/giet_drivers/sdc_driver.h

    r437 r529  
    4646
    4747///////////////////////////////////////////////////////////////////////////////
    48 // Transfer data from the block device to a memory buffer.
    49 // - mode     : BOOT / KERNEL / USER
    50 // - lba      : first block index on the block device
    51 // - buffer   : base address of the memory buffer (must be word aligned)
    52 // - count    : number of blocks to be transfered.
     48// Transfer data between the block device and a memory buffer.
     49// - use_irq   : not used, as DMA is not supported yet
     50// - to_mem    : to memory if non zero
     51// - lba       : first block index on the block device
     52// - buf_vaddr : base address of the memory buffer
     53// - count     : number of blocks to be transfered.
    5354// Returns 0 if success, > 0 if error.
    5455///////////////////////////////////////////////////////////////////////////////
    55 unsigned int _sdc_read( unsigned int mode,
    56                         unsigned int lba,
    57                         paddr_t      buffer,
    58                         unsigned int count);
    59 
    60 
    61 ///////////////////////////////////////////////////////////////////////////////
    62 // Transfer data from memory buffer to SD card device.
    63 // - mode     : BOOT / KERNEL / USER
    64 // - lba      : destination first block index on the SD card
    65 // - buffer   : base address of the memory buffer (must be word aligned)
    66 // - count    : number of blocks to be transfered.
    67 // Returns 0 if success, > 0 if error.
    68 // WARNING: The _sdc_write() is not implemented yet.
    69 ///////////////////////////////////////////////////////////////////////////////
    70 unsigned int _sdc_write( unsigned int mode,
    71                          unsigned int lba,
    72                          paddr_t      buffer,
    73                          unsigned int count);
    74 
    75 ///////////////////////////////////////////////////////////////////////////////
    76 // This function should not be called for the SDC card.
    77 ///////////////////////////////////////////////////////////////////////////////
    78 unsigned int _sdc_get_status();
    79 
    80 ///////////////////////////////////////////////////////////////////////////////
    81 // Returns the block size in bytes of the SD card.
    82 ///////////////////////////////////////////////////////////////////////////////
    83 unsigned int _sdc_get_block_size();
    84 
     56unsigned int _sdc_access( unsigned int       use_irq, 
     57                          unsigned int       to_mem,
     58                          unsigned int       lba,
     59                          unsigned long long buf_vaddr,
     60                          unsigned int       count);
    8561
    8662///////////////////////////////////////////////////////////////////////////////
  • soft/giet_vm/giet_drivers/tim_driver.c

    r456 r529  
    1 //////////////////////////////////////////////////////////////////////////////////////
     1/////////////////////////////////////////////////////////////////////////////
    22// File     : tim_driver.c
    33// Date     : 23/05/2013
    44// Author   : alain greiner
    55// Copyright (c) UPMC-LIP6
    6 //////////////////////////////////////////////////////////////////////////////////////
     6/////////////////////////////////////////////////////////////////////////////
    77
    88#include <giet_config.h>
     
    4848#endif
    4949
    50 /////////////////////////////////////////////////////////////////////////////////
     50/////////////////////////////////////////////////////////////////////////////
    5151//                      global variables
    52 /////////////////////////////////////////////////////////////////////////////////
     52/////////////////////////////////////////////////////////////////////////////
    5353
    5454#define in_unckdata __attribute__((section (".unckdata")))
     
    5959#endif
    6060
    61 /////////////////////////////////////////////////////////////////////////////////
     61/////////////////////////////////////////////////////////////////////////////
    6262//                      access functions
    63 /////////////////////////////////////////////////////////////////////////////////
     63/////////////////////////////////////////////////////////////////////////////
    6464
    65 //////////////////////////////////////////////////////////////
     65///////////////////////////////////////////////////////
    6666unsigned int _timer_get_register( unsigned int channel,
    6767                                  unsigned int index )
  • soft/giet_vm/giet_drivers/xcu_driver.c

    r496 r529  
    8787                    unsigned int irq_type )
    8888{
    89 #if USE_XCU
    9089    // parameters checking
    9190    unsigned int x = cluster_xy >> Y_WIDTH;
     
    106105
    107106    _xcu_set_register(cluster_xy, func, channel, value);
    108 
    109 #else
    110     _printf("[GIET ERROR] _xcu_set_mask() should not be used if USE_XCU not set\n");
    111     _exit();
    112 #endif
    113107}
    114108
     
    119113                     unsigned int * irq_type )
    120114{
    121 #if USE_XCU
    122115    // parameters checking
    123116    unsigned int x = cluster_xy >> Y_WIDTH;
     
    153146        *index = 32;
    154147    }
    155  
    156 #else
    157     _printf("[GIET ERROR] _xcu_get_index should not be used if USE_XCU is not set\n");
    158     _exit();
    159 #endif
    160148}
    161149
     
    165153                    unsigned int wdata )
    166154{
    167 #if USE_XCU
    168155    // parameters checking
    169156    unsigned int x = cluster_xy >> Y_WIDTH;
     
    174161
    175162    _xcu_set_register(cluster_xy, XCU_WTI_REG, wti_index, wdata);
    176 
    177 #else
    178     _printf("[GIET ERROR] _xcu_send_wti() should not be used if USE_XCU is not set\n");
    179     _exit();
    180 #endif
    181163}
    182164
     
    186168                          unsigned int wdata )
    187169{
    188 #if USE_XCU
    189170    // parameters checking
    190171    unsigned int x = cluster_xy >> Y_WIDTH;
     
    199180
    200181    _physical_write(paddr, wdata);
    201 
    202 #else
    203     _puts("[GIET ERROR] _xcu_send_wti() should not be used if USE_XCU is not set\n");
    204     _exit();
    205 #endif
    206 }
     182}
     183
    207184///////////////////////////////////////////////////
    208185void _xcu_get_wti_value( unsigned int   cluster_xy,
     
    210187                         unsigned int * value )
    211188{
    212 #if USE_XCU
    213189    // parameters checking
    214190    unsigned int x = cluster_xy >> Y_WIDTH;
     
    219195 
    220196    *value = _xcu_get_register(cluster_xy, XCU_WTI_REG, wti_index);
    221 
    222 #else
    223     _printf("[GIET ERROR] in _xcu_get_wti_value() USE_XCU is not set\n");
    224     _exit();
    225 #endif
    226197}
    227198
     
    230201                           unsigned int * address )
    231202{
    232 #if USE_XCU
    233     if (wti_index >= 32)           _exit();
     203    if (wti_index >= 32)  _exit();
    234204 
    235205    *address = SEG_XCU_BASE + (XCU_REG(XCU_WTI_REG, wti_index)<<2);
    236 
    237 #else
    238     _printf("[GIET ERROR] in _xcu_get_wti_address() USE_XCU is not set\n");
    239     _exit();
    240 #endif
    241206}
    242207
     
    246211                       unsigned int period )
    247212{
    248 #if USE_XCU
    249213    // parameters checking
    250214    unsigned int x = cluster_xy >> Y_WIDTH;
     
    254218
    255219    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, period);
    256 
    257 #else
    258     _printf("[GIET ERROR] in _xcu_timer_start() USE_XCU is not set\n");
    259     _exit();
    260 #endif
    261220}
    262221
     
    265224                      unsigned int pti_index)
    266225{
    267 #if USE_XCU
    268226    // parameters checking
    269227    unsigned int x = cluster_xy >> Y_WIDTH;
     
    273231
    274232    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, 0);
    275 
    276 #else
    277     _printf("[GIET ERROR] in _xcu_timer_stop() USE_XCU is not set\n");
    278     _exit();
    279 #endif
    280233}
    281234
    282235///////////////////////////////////////////////////////////
    283 unsigned int _xcu_timer_reset_irq( unsigned int cluster_xy,
    284                                    unsigned int pti_index )
    285 {
    286 #if USE_XCU
     236void _xcu_timer_reset_irq( unsigned int cluster_xy,
     237                           unsigned int pti_index )
     238{
    287239    // parameters checking
    288240    unsigned int x = cluster_xy >> Y_WIDTH;
     
    292244
    293245    // This return value is not used / avoid a compilation warning.
    294     return _xcu_get_register(cluster_xy, XCU_PTI_ACK, pti_index);
    295 
    296 #else
    297     _puts("[GIET ERROR] in _xcu_timer_reset_irq() USE_XCU is not set\n");
    298     _exit();
    299     return 0;
    300 #endif
     246    x = _xcu_get_register(cluster_xy, XCU_PTI_ACK, pti_index);
    301247}
    302248
     
    305251                           unsigned int pti_index )
    306252{
    307 #if USE_XCU
    308253    // parameters checking
    309254    unsigned int x = cluster_xy >> Y_WIDTH;
     
    318263    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, 0);
    319264    _xcu_set_register(cluster_xy, XCU_PTI_PER, pti_index, per);
    320 
    321 #else
    322     _puts("[GIET ERROR] in _xcu_timer_reset_cpt() USE_XCU is not set\n");
    323     _exit();
    324 #endif
    325265}
    326266
  • soft/giet_vm/giet_drivers/xcu_driver.h

    r490 r529  
    139139// or by the _isr_timer() for an "user" timer.
    140140//////////////////////////////////////////////////////////////////////////////
    141 extern unsigned int _xcu_timer_reset_irq( unsigned int cluster_xy,
    142                                           unsigned int pti_index );
     141extern void _xcu_timer_reset_irq( unsigned int cluster_xy,
     142                                  unsigned int pti_index );
    143143
    144144//////////////////////////////////////////////////////////////////////////////
Note: See TracChangeset for help on using the changeset viewer.