Ignore:
Timestamp:
Mar 26, 2014, 6:44:44 PM (10 years ago)
Author:
alain
Message:

Introducing a major release, to suppoort the tsar_generic_leti platform
and the various (external or internal) peripherals configurations.
The map.xml format has been modified, in order to support the new
vci_iopic componentand a new policy for peripherals initialisation.
The IRQs are nom described in the XICU and IOPIC components
(and not anymore in the processors).
To enforce this major change, the map.xml file signature changed:
The signature value must be: 0xDACE2014

This new release has been tested on the tsar_generic_leti platform
for the following mappings:

  • 4c_4p_sort_leti
  • 4c_4p_sort_leti_ext
  • 4c_4p_transpose_leti
  • 4c_4p_transpose_leti_ext
  • 4c_1p_four_leti_ext
File:
1 edited

Legend:

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

    r289 r295  
    77///////////////////////////////////////////////////////////////////////////////////
    88// The ioc_driver.c and ioc_driver.h files are part ot the GIET-VM kernel.
    9 // This driver supports the SocLib vci_block_device component, that is
    10 // a single channel, block oriented, external storage contrÃŽler.
    11 //
    12 // It can exist only one block-device controler in the architecture.
    13 //
    14 // The _ioc_read() and _ioc_write() functions use the _ioc_access() function,
    15 // that is always blocking. The _ioc_access function will call the read or
    16 // write function in the driver of the choosen IOC peripheral, which can be for
    17 // now: BDV, HBA and SPI. This function can be called in 4 modes:
    18 //
    19 // - In BOOT_PA mode, the _ioc_access() function use the buffer virtual address
    20 //   as a physical address (as the page tables are not build). This mode is
    21 //   used by the boot code to load the map.bin file into memory.
    22 //
    23 // - In BOOT_VA mode, the _ioc_access() function makes a V2P translation to
    24 //   compute the buffer physical address. This mode is used by the boot code to
    25 //   load the various .elf files into memory.
    26 //
    27 // - In KERNEL mode, the _ioc_access() function makes a V2P translation to
    28 //   compute the buffer physical address. There is no checking of user access
    29 //   right to the memory buffer.  This mode must be used to access IOC, for an
    30 //   "open" system call.
    31 //
    32 // - In USER mode, the _ioc_access() function makes a V2P translation to
    33 //   compute the buffer physical address. The user access right to the memory
    34 //   buffer must be checked.  This mode must be used to access IOC, for a
    35 //   "read/write" system call.
     9//
     10// This abstact driver define a generic API, supporting various physical
     11// block device controlers, including:
     12// - vci_block_device : single channel)                    => bdv_driver
     13// - vci_ahci         : multi channels                     => hba_driver
     14// - sd_card          : single channel                     => sdc_driver
     15// - ramdisk (single channel meory mapped virtual disk)    => rdk_driver
     16//
     17// It can exist only one block-device type in the architecture, that must be
     18// defined by one of the following configuration variables in hard_config.h file:
     19// USE_IOC_BDV, USE_IOC_SDC, USE_IOC_HBA, USE_IOC_RDK.
     20//
     21// Any physical driver xxx must provide the following API:
     22// - _xxx_init()
     23// - _xxx_read()
     24// - _xxx_write()
     25// - _xxx_get_status()
     26// - _xxx_get_block_size()
     27// The "channel" parameter is no transmited to single channel devices.
     28//
     29// The _ioc_read() and _ioc_write() functions are always blocking for
     30// the calling user program.
     31//
     32// These functions compute the physical address of the memory buffer before
     33// calling the proper physical device. They can be called in 3 modes:
     34//
     35// - In BOOT mode, these functions use the buffer virtual address
     36//   as a physical address if the MMU is not activated.
     37//   They make a V2P translation if the MMU is activated.
     38//   This mode is used to load the map.bin file (before memory activation),
     39//   or to load the various .elf files (after MMU activation).
     40//
     41// - In KERNEL mode, these functions make a V2P translation to
     42//   compute the buffer physical address.
     43//   There is no checking of user access right to the memory buffer. 
     44//   This mode must be used for an "open" system call.
     45//
     46// - In USER mode, these functions make a V2P translation to
     47//   compute the buffer physical address.
     48//   The user access right to the memory buffer are checked. 
     49//   This mode must be used for a "read" or "write" system call.
    3650//
    3751// The IOMMU can be activated or not:
     
    6074//   if the IOMMU is not activated.
    6175// An error code is returned if these conditions are not verified.
     76//
     77// The "seg_ioc_base" virtual base address of the segment containing the
     78// memory-mapped registers of the device must be defined in the giet_vsegs.ld file.
     79// If the RAMDISK is used, an extra memory segment with virtual base address
     80// "seg_ramdisk_base" must be defined in the giet_vsegs.ld file.
    6281///////////////////////////////////////////////////////////////////////////////////
    63 // The seg_ioc_base virtual base addresses must be defined in giet_vsegs.ld file.
     82// Implementation note:
     83// In order to share the code, the two _ioc_read() and _ioc_write() functions
     84// call the same _ioc_access() function.
    6485///////////////////////////////////////////////////////////////////////////////////
    6586
    6687#include <giet_config.h>
    6788#include <ioc_driver.h>
     89#include <bdv_driver.h>
     90#include <hba_driver.h>
     91#include <sdc_driver.h>
     92#include <rdk_driver.h>
    6893#include <utils.h>
    6994#include <tty_driver.h>
     
    81106#endif
    82107
    83 #if (USE_BDV + USE_SPI + USE_HBA) != 1
    84 # error: You must use only one IOC controller (BDV or SPI or HBA)
    85 #endif
    86 
    87 #if USE_BDV
     108#if (USE_IOC_BDV + USE_IOC_SPI + USE_IOC_HBA + USE_IOC_RDK) != 1
     109# error: You must use only one IOC controller type (BDV or SPI or HBA or RDK)
     110#endif
     111
     112#if USE_IOC_BDV
    88113# include <bdv_driver.h>
    89114#endif
    90115
    91 #if USE_SPI
     116#if USE_IOC_SPI
    92117# include <sdc_driver.h>
    93118#endif
    94119
    95 #if USE_HBA
     120#if USE_IOC_HBA
    96121# include <hba_driver.h>
    97122#endif
    98123
     124#if USE_IOC_RDK
     125# include <rdk_driver.h>
     126#endif
     127
     128///////////////////////////////////////////////////////////////////////////////
     129// IOC global variables
     130///////////////////////////////////////////////////////////////////////////////
    99131
    100132#define in_unckdata __attribute__((section (".unckdata")))
    101133
    102 ///////////////////// IOC global variables
    103 
    104 in_unckdata unsigned int _ioc_lock = 0;
    105 in_unckdata unsigned int _ioc_status = 0;
    106 in_unckdata volatile unsigned int _ioc_gtid;
    107134in_unckdata volatile unsigned int _ioc_iommu_ix1 = 0;
    108135in_unckdata volatile unsigned int _ioc_iommu_npages;
    109136
    110137///////////////////////////////////////////////////////////////////////////////
    111 //      _ioc_access()
    112138// This function transfer data between a memory buffer and the block device.
    113139// The buffer lentgth is (count*block_size) bytes.
    114140// Arguments are:
    115141// - to_mem     : from external storage to memory when non 0.
    116 // - kernel     : kernel buffer with identity mapping when non 0.
     142// - mode       : BOOT_PA / BOOT_VA / KERNEL / USER
    117143// - lba        : first block index on the external storage.
    118144// - buf_vaddr  : virtual base address of the memory buffer.
     
    121147///////////////////////////////////////////////////////////////////////////////
    122148static unsigned int _ioc_access( unsigned int to_mem,
     149                                 unsigned int channel,
    123150                                 unsigned int mode,
    124151                                 unsigned int lba,
     
    128155
    129156#if GIET_DEBUG_IOC_DRIVER
    130 _tty_get_lock( 0 );
    131 _puts("\n[IOC DEBUG] Enter _ioc_access() at cycle ");
    132 _putd( _get_proctime() );
    133 _puts(" for processor ");
    134 _putd( _get_procid() );
    135 _puts("\n - mode    = ");
    136 _putd( mode );
    137 _puts("\n - vaddr   = ");
    138 _putx( buf_vaddr );
    139 _puts("\n - sectors = ");
    140 _putd( count );
    141 _puts("\n - lba     = ");
    142 _putx( lba );
    143 _puts("\n");
    144 _tty_release_lock( 0 );
     157unsigned int procid  = _get_procid();
     158unsigned int cid     = procid / NB_PROCS_MAX;
     159unsigned int lpid    = procid % NB_PROCS_MAX;
     160unsigned int x       = cid >> Y_WIDTH;
     161unsigned int y       = cid & ((1<<Y_WIDTH) - 1);
     162
     163_printf("\n[IOC DEBUG] Processor[%d,%d,%d] enters _ioc_access() at cycle %d\n"
     164        " - channel  = %d\n"
     165        " - mode     = %d\n"
     166        " - vaddr    = %d\n"
     167        " - sectors  = %d\n"
     168        " - lba      = %d\n",
     169        x, y, lpid, _get_proctime(), channel, mode, buf_vaddr, count, lba );
    145170#endif
    146171
     
    160185    if ((unsigned int) buf_vaddr & 0x3)
    161186    {
    162         _tty_get_lock( 0 );
    163         _puts("\n[GIET ERROR] in _ioc_access() : buffer not word aligned\n");
    164         _tty_release_lock( 0 );
    165         return 1;
     187        _printf("\n[GIET ERROR] in _ioc_access() : buffer not word aligned\n");
     188        _exit();
     189    }
     190
     191    // check channel
     192    if ( (USE_IOC_HBA == 0) && (channel > 0) )
     193    {
     194        _printf("\n[GIET ERROR] in _ioc_access() : channel must be 0 when HBA not used\n");
     195        _exit();
    166196    }
    167197
    168198    unsigned int length = count << 9;  // count * 512 bytes
    169199
    170     // computing target buffer physical address
    171     if ( mode == IOC_BOOT_PA_MODE )                // identity mapping
     200    // computing memory buffer physical address
     201    if ( (mode == IOC_BOOT_MODE) && ((_get_mmu_mode() & 0x4) == 0) ) // identity mapping
    172202    {
    173203        buf_paddr = (paddr_t)buf_vaddr;
    174204    }
    175     else                                           // V2P translation
     205    else                                                    // V2P translation required
    176206    {
    177207        // get page table virtual address
    178208        pt_vbase = _get_context_slot(CTX_PTAB_ID);
    179         vpn_min = buf_vaddr >> 12;
    180         vpn_max = (buf_vaddr + length - 1) >> 12;
     209        vpn_min  = buf_vaddr >> 12;
     210        vpn_max  = (buf_vaddr + length - 1) >> 12;
    181211
    182212        // loop on all virtual pages covering the user buffer
    183         for (vpn = vpn_min, ix2 = 0 ;
    184              vpn <= vpn_max ;
    185              vpn++, ix2++ )
     213        for (vpn = vpn_min, ix2 = 0 ; vpn <= vpn_max ; vpn++, ix2++ )
    186214        {
    187215            // get ppn and flags for each vpn
     
    193221            if ( ko )
    194222            {
    195                 _tty_get_lock( 0 );
    196                 _puts("\n[GIET ERROR] in _ioc_access() : buffer unmapped\n");
    197                 _tty_release_lock( 0 );
     223                _printf("\n[GIET ERROR] in _ioc_access() : buffer unmapped\n");
    198224                return 1;
    199225            }
     
    201227            if ( (mode == IOC_USER_MODE) && ((flags & PTE_U) == 0) )
    202228            {
    203                 _tty_get_lock( 0 );
    204                 _puts("\n[GIET ERROR] in _ioc_access() : buffer not user accessible\n");
    205                 _tty_release_lock( 0 );
     229                _printf("\n[GIET ERROR] in _ioc_access() : buffer not user accessible\n");
    206230                return 1;
    207231            }
     
    209233            if ( ((flags & PTE_W) == 0 ) && to_mem )
    210234            {
    211                 _tty_get_lock( 0 );
    212                 _puts("\n[GIET ERROR] in _ioc_access() : buffer not writable\n");
    213                 _tty_release_lock( 0 );
     235                _printf("\n[GIET ERROR] in _ioc_access() : buffer not writable\n");
    214236                return 1;
    215237            }
     
    223245            if (ix2 > 511) // check buffer length < 2 Mbytes
    224246            {
    225                 _tty_get_lock( 0 );
    226                 _puts("\n[GIET ERROR] in _ioc_access() : user buffer > 2 Mbytes\n");
    227                 _tty_release_lock( 0 );
     247                _printf("\n[GIET ERROR] in _ioc_access() : user buffer > 2 Mbytes\n");
    228248                return 1;
    229249            }
     
    242262            if ((ppn - ppn_first) != ix2)
    243263            {
    244                 _tty_get_lock( 0 );
    245                 _puts("[GIET ERROR] in _ioc_access() : split physical buffer\n");
    246                 _tty_release_lock( 0 );
     264                _printf("[GIET ERROR] in _ioc_access() : split physical buffer\n");
    247265                return 1;
    248266            }
     
    272290    else         // memory read : update data caches
    273291    {
    274         // L1 cache : nothing to do if L1 write-through
     292        // L1 cache : nothing to do for L1 write-through
    275293
    276294        // L2 cache (only if IOB used)
     
    280298    if ( GIET_USE_IOMMU ) buf_paddr = (paddr_t) buf_xaddr;
    281299
    282 #if   USE_BDV
    283     if (to_mem) error = _bdv_read (mode, lba, buf_paddr, count);
    284     else        error = _bdv_write(mode, lba, buf_paddr, count);
    285 #elif USE_SPI
    286     if (to_mem) error = _sdc_read (mode, lba, buf_paddr, count);
    287     else        error = _sdc_write(mode, lba, buf_paddr, count);
    288 #elif USE_HBA
    289     if (to_mem) error = _hba_read (mode, lba, buf_paddr, count);
    290     else        error = _hba_write(mode, lba, buf_paddr, count);
     300    ///////////////////////////////////////////
     301    // select the proper physical device
     302    ///////////////////////////////////////////
     303
     304#if       ( USE_IOC_BDV )
     305
     306#if GIET_DEBUG_IOC_DRIVER
     307_printf("\n[IOC DEBUG] Calling BDV driver\n");
     308#endif
     309        if (to_mem) error = _bdv_read ( mode, lba, buf_paddr, count);
     310        else        error = _bdv_write( mode, lba, buf_paddr, count);
     311
     312#elif ( USE_IOC_SPI )
     313
     314#if GIET_DEBUG_IOC_DRIVER
     315_printf("\n[IOC DEBUG] Calling SPI driver\n");
     316#endif
     317        if (to_mem) error = _sdc_read (mode, lba, buf_paddr, count);
     318        else        error = _sdc_write(mode, lba, buf_paddr, count);
     319
     320#elif ( USE_IOC_HBA )
     321
     322#if GIET_DEBUG_IOC_DRIVER
     323_printf("\n[IOC DEBUG] Calling HBA driver\n");
     324#endif
     325        if (to_mem) error = _hba_read (channel, mode, lba, buf_paddr, count);
     326        else        error = _hba_write(channel, mode, lba, buf_paddr, count);
     327
     328#elif ( USE_IOC_RDK )
     329
     330#if GIET_DEBUG_IOC_DRIVER
     331_printf("\n[IOC DEBUG] Calling RDK driver\n");
     332#endif
     333        if (to_mem) error = _rdk_read (lba, buf_vaddr, count);
     334        else        error = _rdk_write(lba, buf_vaddr, count);
     335
    291336#endif
    292337
     
    295340
    296341///////////////////////////////////////////////////////////////////////////////
    297 //       _ioc_init()
    298342// This function cheks block size, and activates the IOC interrupts.
    299343// Return 0 for success.
     
    301345unsigned int _ioc_init( unsigned int channel )
    302346{
    303 #if   USE_BDV
    304     return _bdv_init( channel );
    305 #elif USE_SPI
    306     return _sdc_init( channel );
    307 #elif USE_HBA
     347
     348#if   ( USE_IOC_BDV )
     349
     350    return _bdv_init();
     351
     352#elif ( USE_IOC_SPI )
     353
     354    return _sdc_init();
     355   
     356#elif ( USE_IOC_HBA )
     357
    308358    return _hba_init( channel );
    309 #endif
     359   
     360#elif ( USE_IOC_RDK )
     361
     362    return _rdk_init();
     363   
     364#endif
     365   
    310366}
    311367
    312368///////////////////////////////////////////////////////////////////////////////
    313 //     _ioc_read()
    314369// Transfer data from the block device to a memory buffer.
    315 // - mode     : BOOT / KERNEL / USER
     370// - mode     : BOOT_PA / BOOT_VA / KERNEL / USER
    316371// - lba      : first block index on the block device
    317372// - buffer   : base address of the memory buffer (must be word aligned)
     
    319374// Returns 0 if success, > 0 if error.
    320375///////////////////////////////////////////////////////////////////////////////
    321 unsigned int _ioc_read( unsigned int mode, 
     376unsigned int _ioc_read( unsigned int channel,
     377                        unsigned int mode, 
    322378                        unsigned int lba,
    323379                        void*        buffer,
     
    325381{
    326382    return _ioc_access( 1,        // read access
     383                        channel,
    327384                        mode, 
    328385                        lba,
     
    332389
    333390///////////////////////////////////////////////////////////////////////////////
    334 //     _ioc_write()
    335391// Transfer data from a memory buffer to the block device.
    336 // - mode     : BOOT / KERNEL / USER
     392// - mode     : BOOT_PA / BOOT_VA / KERNEL / USER
    337393// - lba      : first block index on the block device
    338394// - buffer   : base address of the memory buffer (must be word aligned)
     
    340396// Returns 0 if success, > 0 if error.
    341397///////////////////////////////////////////////////////////////////////////////
    342 unsigned int _ioc_write( unsigned int mode, 
     398unsigned int _ioc_write( unsigned int channel,
     399                         unsigned int mode, 
    343400                         unsigned int lba,
    344401                         const void*  buffer,
     
    346403{
    347404    return _ioc_access( 0,        // write access
     405                        channel,
    348406                        mode, 
    349407                        lba,
     
    353411
    354412///////////////////////////////////////////////////////////////////////////////
    355 //     _ioc_get_status()
    356413// This function returns in the status variable, the transfert status, and
    357414// acknowledge the IRQ if the IOC controler is not busy.
    358415// Returns 0 if success, > 0 if error
    359416///////////////////////////////////////////////////////////////////////////////
    360 unsigned int _ioc_get_status( unsigned int  channel,
    361                               unsigned int* status )
    362 {
    363 #if   USE_BDV
    364     return _bdv_get_status(channel, status);
    365 #elif USE_SPI
    366     return _sdc_get_status(channel, status);
    367 #elif USE_HBA
    368     return _hba_get_status(channel, status);
    369 #endif
     417unsigned int _ioc_get_status( unsigned int  channel )
     418{
     419
     420#if   ( USE_IOC_BDV )
     421
     422    return _bdv_get_status( );
     423
     424#elif ( USE_IOC_SPI )
     425
     426    return _sdc_get_status( );
     427
     428#elif ( USE_IOC_HBA )
     429
     430    return _hba_get_status( channel );
     431
     432#elif ( USE_IOC_RDK )
     433
     434    _printf("[GIET ERROR] _ioc_get_status() should not be called");
     435    _printf(" when RAMDISK  is used...\n");
     436    _exit();
     437
     438    return 0;
     439
     440#endif
     441
    370442}
    371443
    372444///////////////////////////////////////////////////////////////////////////////
    373 //     _ioc_get_block_size()
    374445// This function returns the block_size with which the IOC has been configured.
    375446///////////////////////////////////////////////////////////////////////////////
    376447unsigned int _ioc_get_block_size()
    377448{
    378 #if   USE_BDV
     449
     450#if   ( USE_IOC_BDV )
     451
    379452    return _bdv_get_block_size();
    380 #elif USE_SPI
     453   
     454#elif ( USE_IOC_SPI )
     455
    381456    return _sdc_get_block_size();
    382 #elif USE_HBA
     457   
     458#elif ( USE_IOC_HBA )
     459
    383460    return _hba_get_block_size();
    384 #endif
     461   
     462#elif ( USE_IOC_RDK )
     463
     464    return 512;
     465
     466#endif
     467
    385468}
    386469
Note: See TracChangeset for help on using the changeset viewer.