Ignore:
Timestamp:
Mar 3, 2014, 5:11:06 PM (10 years ago)
Author:
cfuguet
Message:

Introducing a RAMDISK driver in the preloader.

When using RAMDISK, execute the make command with the flags
SOCLIB=1 and RAMDISK=1. The RDK_PADDR_BASE variable must
also be set on the conf/<platform>/defs_platform.h

These modifications are backward compatibles. Therefore,
when no using RAMDISK, none modifications applied on the
platform configuration file.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/softs/tsar_boot/src/reset_ioc.c

    r588 r653  
    11#include <reset_ioc.h>
    22
    3 #ifndef SOCLIB_IOC
    4 
    5 static struct sdcard_dev        _sdcard_device;
    6 static struct spi_dev   *const  _spi_device   = ( struct spi_dev * )IOC_PADDR_BASE;
    7 
     3#if USE_SPI
     4static struct sdcard_dev     _sdcard_device;
     5static struct spi_dev *const _spi_device = (struct spi_dev*) IOC_PADDR_BASE;
    86#endif
    97
     
    1715}
    1816
    19 #if RESET_DEBUG
    20 ////////////////////////////////////
    21 inline unsigned int reset_proctime()
    22 {
    23     unsigned int ret;
    24     asm volatile ("mfc0 %0, $9":"=r" (ret));
    25     return ret;
    26 }
    27 #endif
    28 
    29 #ifndef SOCLIB_IOC
    30 /////////////////////////////////////////////////////////////////////////////////
     17#if USE_SPI
     18///////////////////////////////////////////////////////////////////////////////
    3119//     reset_ioc_init
    3220// This function initializes the SDCARD / required for FPGA.
    33 /////////////////////////////////////////////////////////////////////////////////
     21///////////////////////////////////////////////////////////////////////////////
    3422int reset_ioc_init()
    3523{
     
    10593#endif
    10694
    107 #ifdef SOCLIB_IOC
    108 /////////////////////////////////////////////////////////////////////////////////////
    109 //      reset_ioc_completed()
    110 // This blocking function checks completion of an I/O transfer and reports errors.
    111 // It returns 0 if the transfer is successfully completed.
    112 // It returns -1 if an error has been reported.
    113 /////////////////////////////////////////////////////////////////////////////////////
    114 int reset_ioc_completed()
    115 {
     95//////////////////////////////////////////////////////////////////////////////
     96// reset_bdv_read()
     97/////////////////////////////////////////////////////////////////////////////
     98#if USE_BDV
     99int reset_bdv_read( unsigned int lba,
     100                    void*        buffer,
     101                    unsigned int count )
     102{
     103    unsigned int * ioc_address = (unsigned int*)IOC_PADDR_BASE;
     104
     105    // block_device configuration
     106    iowrite32( &ioc_address[BLOCK_DEVICE_BUFFER], (unsigned int) buffer );
     107    iowrite32( &ioc_address[BLOCK_DEVICE_COUNT], count );
     108    iowrite32( &ioc_address[BLOCK_DEVICE_LBA], lba );
     109    iowrite32( &ioc_address[BLOCK_DEVICE_IRQ_ENABLE], 0 );
     110
     111    // block_device trigger transfer
     112    iowrite32( &ioc_address[BLOCK_DEVICE_OP], ( unsigned int )
     113               BLOCK_DEVICE_READ );
     114
    116115    unsigned int status = 0;
    117 
    118     unsigned int * ioc_address = ( unsigned int * )IOC_PADDR_BASE;
    119 
    120116    while ( 1 )
    121117    {
    122118        status = ioread32(&ioc_address[BLOCK_DEVICE_STATUS]);
    123 
    124         if (( status == BLOCK_DEVICE_READ_SUCCESS ) ||
    125             ( status == BLOCK_DEVICE_READ_ERROR  ))
    126         break;
    127     }
    128 
    129     return status;
    130 } // end reset_ioc_completed()
    131 #endif
    132 
    133 #ifdef SOCLIB_IOC
    134 /////////////////////////////////////////////////////////////////////////////////////
     119        if ( status == BLOCK_DEVICE_READ_SUCCESS )
     120        {
     121            break;
     122        }
     123        if ( status == BLOCK_DEVICE_READ_ERROR   ) {
     124            reset_puts("ERROR during read on the BLK device\n");
     125            return 1;
     126        }
     127    }
     128#if (CACHE_COHERENCE == 0) || USE_IOB
     129    reset_buf_invalidate(buffer, CACHE_LINE_SIZE, count * 512);
     130#endif
     131    return 0;
     132}
     133#endif
     134
     135//////////////////////////////////////////////////////////////////////////////
     136// reset_spi_read()
     137/////////////////////////////////////////////////////////////////////////////
     138#if USE_SPI
     139static int reset_spi_read( unsigned int lba,
     140                           void*        buffer,
     141                           unsigned int count )
     142{
     143    unsigned int sdcard_rsp;
     144    unsigned int i;
     145
     146    sdcard_dev_lseek(&_sdcard_device, lba);
     147    for(i = 0; i < count; i++)
     148    {
     149        unsigned char* buf = (unsigned char *) buffer + (512 * i);
     150        if (( sdcard_rsp = sdcard_dev_read ( &_sdcard_device, buf, 512 ) ))
     151        {
     152            reset_puts("ERROR during read on the SDCARD device. Code: ");
     153            reset_putx(sdcard_rsp);
     154            reset_puts("\n");
     155            return 1;
     156        }
     157    }
     158    return 0;
     159}
     160#endif
     161
     162//////////////////////////////////////////////////////////////////////////////
     163// reset_rdk_read()
     164/////////////////////////////////////////////////////////////////////////////
     165#if USE_RDK
     166static int reset_rdk_read( unsigned int lba,
     167                           void*        buffer,
     168                           unsigned int count )
     169{
     170    unsigned int* rdk_address = (unsigned int*) RDK_PADDR_BASE;
     171    char* src = (char*) rdk_address + (lba * 512);
     172
     173    memcpy(buffer, (void*) src, count * 512);
     174    return 0;
     175}
     176#endif
     177
     178///////////////////////////////////////////////////////////////////////////////
    135179//      reset_ioc_read()
    136 // Transfer data the block device to a memory buffer: SOCLIB version
     180// Transfer data from disk to a memory buffer
    137181// - param lba    : first block index on the disk
    138182// - param buffer : base address of the memory buffer
    139183// - param count  : number of blocks to be transfered
    140 // This is a blocking function. The function returns once the transfer is completed.
    141 /////////////////////////////////////////////////////////////////////////////////////
     184// This is a blocking function. The function returns once the transfer is
     185// completed.
     186//
     187// The USE_BDV, USE_SPI and USE_RDK variables signal if the disk is accessed
     188// through a BLOCK DEVICE, SPI or RAMDISK respectively
     189///////////////////////////////////////////////////////////////////////////////
    142190int reset_ioc_read( unsigned int lba,
    143191                    void*        buffer,
    144192                    unsigned int count )
    145193{
    146 
    147     unsigned int * ioc_address  = (unsigned int*)IOC_PADDR_BASE;
    148 
    149 #if RESET_DEBUG
    150     unsigned int start_time;
    151     unsigned int end_time;
    152     reset_puts("[RESET DEBUG] Reading blocks ");
    153     reset_putd(lba);
    154     reset_puts(" to ");
    155     reset_putd(lba + count - 1);
    156 
    157     start_time = reset_proctime();
    158 #endif
    159 
    160     // block_device configuration
    161     iowrite32( &ioc_address[BLOCK_DEVICE_BUFFER],
    162             ( unsigned int ) buffer );
    163 
    164     iowrite32( &ioc_address[BLOCK_DEVICE_COUNT],
    165             ( unsigned int ) count );
    166 
    167     iowrite32( &ioc_address[BLOCK_DEVICE_LBA],
    168             ( unsigned int ) lba );
    169 
    170     iowrite32( &ioc_address[BLOCK_DEVICE_IRQ_ENABLE],
    171             ( unsigned int ) 0 );
    172 
    173     iowrite32( &ioc_address[BLOCK_DEVICE_OP],
    174             ( unsigned int ) BLOCK_DEVICE_READ );
    175 
    176     reset_ioc_completed();
    177 
    178 #if (CACHE_COHERENCE == 0) || (USE_IOB == 1)
    179     reset_buf_invalidate(buffer, CACHE_LINE_SIZE, count * 512);
    180 #endif
    181 
    182 #if USE_IOB
    183     reset_mcc_invalidate(buffer, count * 512);
    184 #endif
    185 
    186 #if RESET_DEBUG
    187     end_time = reset_proctime();
    188     reset_puts(" / cycles for transfert: ");
    189     reset_putd(end_time - start_time);
    190     reset_puts("\n");
    191 #endif
    192 
    193     return 0;
    194 } // end reset_ioc_read()
    195 
    196 #else
    197 
    198 /////////////////////////////////////////////////////////////////////////////////////
    199 //      reset_ioc_read()
    200 // Transfer data the block device to a memory buffer: FPGA version
    201 // - param lba    : first block index on the disk
    202 // - param buffer : base address of the memory buffer
    203 // - param count  : number of blocks to be transfered
    204 // This is a blocking function. The function returns once the transfer is completed.
    205 /////////////////////////////////////////////////////////////////////////////////////
    206 int reset_ioc_read( unsigned int lba,
    207                     void*        buffer,
    208                     unsigned int count )
    209 {
    210     unsigned int sdcard_rsp;
    211     unsigned int i;
    212 
    213     sdcard_dev_lseek(&_sdcard_device, lba);
    214 
    215 #if RESET_DEBUG
    216     unsigned int start_time;
    217     unsigned int end_time;
    218     reset_puts("[RESET DEBUG] Reading blocks ");
    219     reset_putd(lba);
    220     reset_puts(" to ");
    221     reset_putd(lba + count - 1);
    222     start_time = reset_proctime();
    223 #endif
    224 
    225     for(i = 0; i < count; i++)
    226     {
    227         if (( sdcard_rsp = sdcard_dev_read (
    228                         &_sdcard_device,
    229                         (unsigned char *) buffer + (512 * i),
    230                         512
    231                         )
    232             ))
    233         {
    234             reset_puts("ERROR during read on the SDCARD device. Code: ");
    235             reset_putx(sdcard_rsp);
    236             reset_puts("\n\r");
    237 
    238             return 1;
    239         }
    240     }
    241 
    242 #if RESET_DEBUG
    243     end_time = reset_proctime();
    244     reset_puts(" / cycles for transfert: ");
    245     reset_putd(end_time - start_time);
    246     reset_puts("\n");
    247 #endif
    248 
    249     return 0;
    250 } // end reset_ioc_read()
    251 #endif
    252 
    253 //////////////////////////////////////////////////////////////////////////////
    254 // reset_dcache_buf_invalidate()
    255 // Invalidate all data cache lines corresponding to a memory buffer
    256 // (identified by an address and a size) in L1 cache.
    257 /////////////////////////////////////////////////////////////////////////////
    258 #if (CACHE_COHERENCE == 0) || (USE_IOB == 1)
    259 void reset_buf_invalidate ( const void * buffer,
    260                             unsigned int line_size,
    261                             unsigned int size)
    262 {
    263     unsigned int i;
    264 
    265     // iterate on cache lines
    266     for (i = 0; i <= size; i += line_size)
    267     {
    268         asm volatile(
    269             " cache %0, %1"
    270             :// no outputs
    271             :"i" (0x11), "R" (*((unsigned char *) buffer + i))
    272             );
    273     }
    274 }
    275 #endif
    276 
    277 //////////////////////////////////////////////////////////////////////////////
    278 // reset_mcc_inval()
    279 // Invalidate all data cache lines corresponding to a memory buffer
    280 // (identified by an address and a size) in L2 cache.
    281 /////////////////////////////////////////////////////////////////////////////
    282 #if USE_IOB
    283 void reset_mcc_invalidate ( const void * buffer,
    284                             unsigned int size)
    285 {
    286     unsigned int * mcc_address = (unsigned int *)MCC_PADDR_BASE;
    287 
    288     // get the hard lock assuring exclusive access to MEMC
    289     while (ioread32(&mcc_address[MCC_LOCK]));
    290 
    291     // write invalidate paremeters on the memory cache
    292     // this preloader use only the cluster 0 and then the HI bits are not used
    293    
    294     iowrite32(&mcc_address[MCC_ADDR_LO], (unsigned int) buffer);
    295     iowrite32(&mcc_address[MCC_ADDR_HI], (unsigned int) 0);
    296     iowrite32(&mcc_address[MCC_LENGTH] , (unsigned int) size);
    297     iowrite32(&mcc_address[MCC_CMD]    , (unsigned int) MCC_CMD_INVAL);
    298 
    299     // release the lock protecting MEMC
    300     iowrite32(&mcc_address[MCC_LOCK], (unsigned int) 0);
    301 }
    302 #endif
     194    int status;
     195#if USE_BDV
     196    status = reset_bdv_read(lba, buffer, count);
     197#endif
     198#if USE_SPI
     199    status = reset_spi_read(lba, buffer, count);
     200#endif
     201#if USE_RDK
     202    status = reset_rdk_read(lba, buffer, count);
     203#endif
     204    return status;
     205}
    303206
    304207/*
Note: See TracChangeset for help on using the changeset viewer.