Ignore:
Timestamp:
Jan 31, 2014, 11:35:57 AM (10 years ago)
Author:
cfuguet
Message:

Introducing branch to test ioc drivers before merging on trunk

Location:
branch
Files:
1 added
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branch/giet_vm_ioc_drivers/giet_drivers/ioc_driver.c

    r279 r283  
    8787#endif
    8888
     89#if (USE_BDV + USE_SPI + USE_HBA) != 1
     90# error: You must use only one IOC controller (BDV or SPI or HBA)
     91#endif
     92
     93#if USE_BDV
     94# include <bdv_driver.h>
     95#endif
     96
     97#if USE_SPI
     98# include <sdc_driver.h>
     99#endif
     100
     101#if USE_HBA
     102# include <hba_driver.h>
     103#endif
     104
     105
    89106#define in_unckdata __attribute__((section (".unckdata")))
    90107
    91108///////////////////// IOC global variables
    92109
    93 in_unckdata unsigned int          _ioc_lock = 0;
    94 in_unckdata volatile unsigned int _ioc_status = 0;
     110in_unckdata unsigned int _ioc_lock = 0;
     111in_unckdata unsigned int _ioc_status = 0;
    95112in_unckdata volatile unsigned int _ioc_gtid;
    96113in_unckdata volatile unsigned int _ioc_iommu_ix1 = 0;
     
    154171        return 1;
    155172    }
    156 
    157     volatile unsigned int * ioc_address = (unsigned int *) &seg_ioc_base ;
    158173
    159174    unsigned int length = count << 9;  // count * 512 bytes
     
    269284    }
    270285
    271     // get the lock protecting IOC
    272     _get_lock(&_ioc_lock);
    273 
    274     // set the _ioc_status polling variable
    275     _ioc_status = BLOCK_DEVICE_BUSY;
    276 
    277 #if GIET_DEBUG_IOC_DRIVER
    278 _tty_get_lock( 0 );
    279 _puts("\n[IOC DEBUG] _ioc_access() : configure IOC\n");
    280 _puts(" - buf_paddr = ");
    281 _putl( buf_paddr );
    282 _puts("\n");
    283 _puts(" - count     = ");
    284 _putd( count );
    285 _puts("\n");
    286 _puts(" - lba       = ");
    287 _putx( lba );
    288 _puts("\n");
    289 _tty_release_lock( 0 );
    290 #endif
    291 
    292     // send command to IOC   
    293     if ( GIET_USE_IOMMU )
    294     {
    295         ioc_address[BLOCK_DEVICE_BUFFER] = buf_xaddr;
    296         ioc_address[BLOCK_DEVICE_COUNT]  = count;
    297         ioc_address[BLOCK_DEVICE_LBA]    = lba;
    298     }
    299     else
    300     {
    301         ioc_address[BLOCK_DEVICE_BUFFER]     = (unsigned int)buf_paddr;
    302         ioc_address[BLOCK_DEVICE_BUFFER_EXT] = (unsigned int)(buf_paddr>>32);
    303         ioc_address[BLOCK_DEVICE_COUNT]      = count;
    304         ioc_address[BLOCK_DEVICE_LBA]        = lba;
    305     }
    306 
    307     // There is two policies for transfer completion
    308         // detection, depending on the mode argument:
    309 
    310     if ( (mode == IOC_BOOT_PA_MODE) ||    // We poll directly the IOC_STATUS register
    311          (mode == IOC_BOOT_VA_MODE) )     // as IRQs are masked.
    312     {
    313         // Launch transfert
    314         if (to_mem == 0) ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_WRITE;
    315         else             ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_READ;
    316 
    317         unsigned int status;
    318         if ( _ioc_get_status(0, &status) ) return 1;
    319 
    320         while( (status != BLOCK_DEVICE_READ_SUCCESS)  &&
    321                (status != BLOCK_DEVICE_READ_ERROR)    &&
    322                (status != BLOCK_DEVICE_WRITE_SUCCESS) &&
    323                (status != BLOCK_DEVICE_WRITE_ERROR) )
    324         {
    325             if ( _ioc_get_status(0, &status) ) return 1;
    326 
    327 #if GIET_DEBUG_IOC_DRIVER
    328 _tty_get_lock( 0 );
    329 _puts("\n[IOC DEBUG] _ioc_access() : ... waiting on IOC_STATUS register ...\n");
    330 _tty_release_lock( 0 );
    331 #endif
    332 
    333         }
    334         // analyse status
    335         error = ( (status == BLOCK_DEVICE_READ_ERROR) ||
    336                   (status == BLOCK_DEVICE_WRITE_ERROR) );
    337 
    338         // release lock
    339         _release_lock(&_ioc_lock);     
    340     }
    341     else                           // in USER or KERNEL mode, we deschedule the task.
    342                                    // When the task is rescheduled by the ISR, we reset
    343                                    // the _ioc_status variable, and release the lock
    344     {
    345         // We need a critical section, because we must reset the RUN bit
    346                 // before to launch the transfer, and we want to avoid to be descheduled
    347                 // between these two operations.
    348 
    349         // Enter critical section
    350         _it_disable();
    351        
    352         // set _ioc_gtid and reset runnable
    353         unsigned int ltid = _get_proc_task_id();
    354         unsigned int pid = _get_procid();
    355         _ioc_gtid = (pid<<16) + ltid;
    356         _set_task_slot( pid, ltid, CTX_RUN_ID, 0 ); 
    357        
    358         // Launch transfert
    359         if (to_mem == 0) ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_WRITE;
    360         else             ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_READ;
    361 
    362         // deschedule task
    363         _ctx_switch();                     
    364 
    365         // analyse status
    366         error = ( (_ioc_status == BLOCK_DEVICE_READ_ERROR) ||
    367                   (_ioc_status == BLOCK_DEVICE_WRITE_ERROR) );
    368 
    369         // reset _ioc_status and release lock
    370         _ioc_status = BLOCK_DEVICE_IDLE;
    371         _release_lock(&_ioc_lock);     
    372     }
    373 
    374 #if GIET_DEBUG_IOC_DRIVER
    375 _tty_get_lock( 0 );
    376 _puts("\n[IOC DEBUG] _ioc_access completed at cycle ");
    377 _putd( _get_proctime() );
    378 _puts(" for processor ");
    379 _putd( _get_procid() );
    380 _puts(" : error = ");
    381 _putd( (unsigned int)error );
    382 _puts("\n");
    383 _tty_release_lock( 0 );
     286    if ( GIET_USE_IOMMU ) buf_paddr = (paddr_t) buf_xaddr;
     287
     288#if   USE_BDV
     289    if (to_mem) error = _bdv_read (mode, lba, buf_paddr, count);
     290    else        error = _bdv_write(mode, lba, buf_paddr, count);
     291#elif USE_SPI
     292    if (to_mem) error = _sdc_read (mode, lba, buf_paddr, count);
     293    else        error = _sdc_write(mode, lba, buf_paddr, count);
     294#elif USE_HBA
     295    if (to_mem) error = _hba_read (mode, lba, buf_paddr, count);
     296    else        error = _hba_write(mode, lba, buf_paddr, count);
    384297#endif
    385298
     
    392305// Return 0 for success.
    393306///////////////////////////////////////////////////////////////////////////////
    394 unsigned int _ioc_init()
    395 {
    396     volatile unsigned int * ioc_address = (unsigned int *) &seg_ioc_base ;
    397    
    398     if ( ioc_address[BLOCK_DEVICE_BLOCK_SIZE] != 512 )
    399     {
    400         _puts("\n[GIET ERROR] in _ioc_init() : block size must be 512 bytes\n");
    401         _exit();
    402     }
    403 
    404     ioc_address[BLOCK_DEVICE_IRQ_ENABLE] = 1;
    405     return 0;
     307unsigned int _ioc_init( unsigned int channel )
     308{
     309#if   USE_BDV
     310    return _bdv_init( channel );
     311#elif USE_SPI
     312    return _sdc_init( channel );
     313#elif USE_HBA
     314    return _hba_init( channel );
     315#endif
    406316}
    407317
     
    457367                              unsigned int* status )
    458368{
    459     if ( channel != 0 )
    460     {
    461         _tty_get_lock( 0 );
    462         _puts("\n[GIET ERROR] in _ioc_get_status : illegal channel\n");
    463         _tty_release_lock( 0 );
    464 
    465         return 1;
    466     }
    467 
    468     // get IOC base address
    469     volatile unsigned int * ioc_address = (unsigned int *) &seg_ioc_base;
    470     *status = ioc_address[BLOCK_DEVICE_STATUS];
    471 
    472     return 0;
     369#if   USE_BDV
     370    return _bdv_get_status(channel, status);
     371#elif USE_SPI
     372    return _sdc_get_status(channel, status);
     373#elif USE_HBA
     374    return _hba_get_status(channel, status);
     375#endif
    473376}
    474377
     
    479382unsigned int _ioc_get_block_size()
    480383{
    481     // get IOC base address
    482     volatile unsigned int * ioc_address = (unsigned int *) &seg_ioc_base;
    483    
    484     return  ioc_address[BLOCK_DEVICE_BLOCK_SIZE];
     384#if   USE_BDV
     385    return _bdv_get_block_size();
     386#elif USE_SPI
     387    return _sdc_get_block_size();
     388#elif USE_HBA
     389    return _hba_get_block_size();
     390#endif
    485391}
    486392
Note: See TracChangeset for help on using the changeset viewer.