source: trunk/softs/tsar_boot/src/reset_ioc.c @ 592

Last change on this file since 592 was 588, checked in by bouyer, 11 years ago

Rename IOC_BASE to IOC_PADDR_BASE for consistency

File size: 8.5 KB
RevLine 
[586]1#include <reset_ioc.h>
[292]2
3#ifndef SOCLIB_IOC
4
[586]5static struct sdcard_dev        _sdcard_device;
[588]6static struct spi_dev   *const  _spi_device   = ( struct spi_dev * )IOC_PADDR_BASE;
[388]7
[586]8#endif
[302]9
[586]10#define SDCARD_RESET_ITER_MAX   4
[302]11
[586]12///////////////////////////////////
13inline void reset_sleep(int cycles)
[388]14{
15    int i;
16    for (i = 0; i < cycles; i++);
17}
18
[586]19#if RESET_DEBUG
20////////////////////////////////////
21inline unsigned int reset_proctime()
[388]22{
23    unsigned int ret;
24    asm volatile ("mfc0 %0, $9":"=r" (ret));
25    return ret;
26}
[412]27#endif
[388]28
29#ifndef SOCLIB_IOC
[586]30/////////////////////////////////////////////////////////////////////////////////
31//     reset_ioc_init
32// This function initializes the SDCARD / required for FPGA.
33/////////////////////////////////////////////////////////////////////////////////
34int reset_ioc_init()
[292]35{
36    unsigned char sdcard_rsp;
37
[586]38    reset_puts("Initializing block device\n\r");
[292]39
40    /**
41     * Initializing the SPI controller
42     */
43    spi_dev_config (
44      _spi_device   ,
45      200000        , /**< SPI_clk: 200 Khz */
46      SYSCLK_FREQ   , /**< Sys_clk          */
47      8             , /**< Charlen: 8       */
48      SPI_TX_NEGEDGE,
49      SPI_RX_POSEDGE
[412]50    );
[292]51
52    /**
53     * Initializing the SD Card
54     */
[388]55    unsigned int iter = 0;
[412]56    while(1)
[388]57    {
[586]58        reset_puts("Trying to initialize SD card... ");
[292]59
[388]60        sdcard_rsp = sdcard_dev_open(&_sdcard_device, _spi_device, 0);
61        if (sdcard_rsp == 0)
62        {
[586]63            reset_puts("OK\n");
[388]64            break;
65        }
[292]66
[586]67        reset_puts("KO\n");
68        reset_sleep(1000);
[388]69        if (++iter >= SDCARD_RESET_ITER_MAX)
70        {
[586]71            reset_puts("\nERROR: During SD card reset to IDLE state\n"
[388]72                      "/ card response = ");
[586]73            reset_putx(sdcard_rsp);
74            reset_puts("\n");
75            reset_exit();
[388]76        }
77    }
78
[292]79    /**
[388]80     * Set the block length of the SD Card
81     */
82    sdcard_rsp = sdcard_dev_set_blocklen(&_sdcard_device, 512);
83    if (sdcard_rsp)
84    {
[586]85        reset_puts("ERROR: During SD card blocklen initialization\n");
86        reset_exit();
[388]87    }
88
89    /**
[292]90     * Incrementing SDCARD clock frequency for normal function
91     */
92    spi_dev_config (
93        _spi_device ,
[388]94        10000000    , /**< SPI_clk 10 Mhz */
95        SYSCLK_FREQ , /**< Sys_clk        */
96        -1          , /**< Charlen: 8     */
[292]97        -1          ,
98        -1
99    );
100
[586]101    reset_puts("Finish block device initialization\n\r");
[292]102
103    return 0;
[586]104} // end reset_ioc_init()
105#endif
[292]106
107#ifdef SOCLIB_IOC
[586]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/////////////////////////////////////////////////////////////////////////////////////
114int reset_ioc_completed()
[292]115{
116    unsigned int status = 0;
117
[586]118    unsigned int * ioc_address = ( unsigned int * )IOC_PADDR_BASE;
[292]119
120    while ( 1 )
[412]121    {
[292]122        status = ioread32(&ioc_address[BLOCK_DEVICE_STATUS]);
123
124        if (( status == BLOCK_DEVICE_READ_SUCCESS ) ||
125            ( status == BLOCK_DEVICE_READ_ERROR  ))
126        break;
127    }
[412]128
[292]129    return status;
[586]130} // end reset_ioc_completed()
[292]131#endif
132
[347]133#ifdef SOCLIB_IOC
[586]134/////////////////////////////////////////////////////////////////////////////////////
135//      reset_ioc_read()
136// Transfer data the block device to a memory buffer: SOCLIB version
137// - param lba    : first block index on the disk
138// - param buffer : base address of the memory buffer
139// - param count  : number of blocks to be transfered
140// This is a blocking function. The function returns once the transfer is completed.
141/////////////////////////////////////////////////////////////////////////////////////
142int reset_ioc_read( unsigned int lba, 
143                    void*        buffer, 
144                    unsigned int count )
[292]145{
146
[586]147    unsigned int * ioc_address  = (unsigned int*)IOC_PADDR_BASE;
[292]148
[586]149#if RESET_DEBUG
[412]150    unsigned int start_time;
151    unsigned int end_time;
[586]152    reset_puts("[RESET DEBUG] Reading blocks ");
153    reset_putd(lba);
154    reset_puts(" to ");
155    reset_putd(lba + count - 1);
[412]156
[586]157    start_time = reset_proctime();
[412]158#endif
159
[292]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
[586]176    reset_ioc_completed();
[292]177
[568]178#if (CACHE_COHERENCE == 0) || (USE_IOB == 1)
[586]179    reset_buf_invalidate(buffer, CACHE_LINE_SIZE, count * 512);
[347]180#endif
[412]181
[586]182#if USE_IOB
183    reset_mcc_invalidate(buffer, count * 512);
[568]184#endif
185
[586]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");
[412]191#endif
192
[347]193    return 0;
[586]194} // end reset_ioc_read()
[347]195
[292]196#else
[388]197
[586]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/////////////////////////////////////////////////////////////////////////////////////
206int reset_ioc_read( unsigned int lba, 
207                    void*        buffer, 
208                    unsigned int count )
[347]209{
[292]210    unsigned int sdcard_rsp;
[388]211    unsigned int i;
[292]212
213    sdcard_dev_lseek(&_sdcard_device, lba);
214
[586]215#if RESET_DEBUG
[388]216    unsigned int start_time;
217    unsigned int end_time;
[586]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();
[388]223#endif
224
[292]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
[412]231                        )
[292]232            ))
233        {
[586]234            reset_puts("ERROR during read on the SDCARD device. Code: ");
235            reset_putx(sdcard_rsp);
236            reset_puts("\n\r");
[292]237
238            return 1;
[388]239        }
[292]240    }
241
[586]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");
[388]247#endif
248
[292]249    return 0;
[586]250} // end reset_ioc_read()
[347]251#endif
[292]252
[586]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/////////////////////////////////////////////////////////////////////////////
[568]258#if (CACHE_COHERENCE == 0) || (USE_IOB == 1)
[586]259void reset_buf_invalidate ( const void * buffer,
260                            unsigned int line_size,
261                            unsigned int size)
[347]262{
263    unsigned int i;
[292]264
[412]265    // iterate on cache lines
[586]266    for (i = 0; i <= size; i += line_size) 
267    {
[347]268        asm volatile(
269            " cache %0, %1"
270            :// no outputs
271            :"i" (0x11), "R" (*((unsigned char *) buffer + i))
272            );
273    }
274}
275#endif
276
[586]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
283void reset_mcc_invalidate ( const void * buffer,
284                            unsigned int size)
[568]285{
[586]286    unsigned int * mcc_address = (unsigned int *)MCC_PADDR_BASE;
[568]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
303
[292]304/*
305 * vim: tabstop=4 : shiftwidth=4 : expandtab
306 */
Note: See TracBrowser for help on using the repository browser.