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

Last change on this file since 586 was 586, checked in by alain, 10 years ago

Modify the name "boot" to "reset" to avoid confusion
between the pre-loader and the boot-loader...
Increase the size of the segment containing the stacks.

File size: 8.5 KB
Line 
1#include <reset_ioc.h>
2
3#ifndef SOCLIB_IOC
4
5static struct sdcard_dev        _sdcard_device;
6static struct spi_dev   *const  _spi_device   = ( struct spi_dev * )IOC_BASE;
7
8#endif
9
10#define SDCARD_RESET_ITER_MAX   4
11
12///////////////////////////////////
13inline void reset_sleep(int cycles)
14{
15    int i;
16    for (i = 0; i < cycles; i++);
17}
18
19#if RESET_DEBUG
20////////////////////////////////////
21inline 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/////////////////////////////////////////////////////////////////////////////////
31//     reset_ioc_init
32// This function initializes the SDCARD / required for FPGA.
33/////////////////////////////////////////////////////////////////////////////////
34int reset_ioc_init()
35{
36    unsigned char sdcard_rsp;
37
38    reset_puts("Initializing block device\n\r");
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
50    );
51
52    /**
53     * Initializing the SD Card
54     */
55    unsigned int iter = 0;
56    while(1)
57    {
58        reset_puts("Trying to initialize SD card... ");
59
60        sdcard_rsp = sdcard_dev_open(&_sdcard_device, _spi_device, 0);
61        if (sdcard_rsp == 0)
62        {
63            reset_puts("OK\n");
64            break;
65        }
66
67        reset_puts("KO\n");
68        reset_sleep(1000);
69        if (++iter >= SDCARD_RESET_ITER_MAX)
70        {
71            reset_puts("\nERROR: During SD card reset to IDLE state\n"
72                      "/ card response = ");
73            reset_putx(sdcard_rsp);
74            reset_puts("\n");
75            reset_exit();
76        }
77    }
78
79    /**
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    {
85        reset_puts("ERROR: During SD card blocklen initialization\n");
86        reset_exit();
87    }
88
89    /**
90     * Incrementing SDCARD clock frequency for normal function
91     */
92    spi_dev_config (
93        _spi_device ,
94        10000000    , /**< SPI_clk 10 Mhz */
95        SYSCLK_FREQ , /**< Sys_clk        */
96        -1          , /**< Charlen: 8     */
97        -1          ,
98        -1
99    );
100
101    reset_puts("Finish block device initialization\n\r");
102
103    return 0;
104} // end reset_ioc_init()
105#endif
106
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/////////////////////////////////////////////////////////////////////////////////////
114int reset_ioc_completed()
115{
116    unsigned int status = 0;
117
118    unsigned int * ioc_address = ( unsigned int * )IOC_PADDR_BASE;
119
120    while ( 1 )
121    {
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    }
128
129    return status;
130} // end reset_ioc_completed()
131#endif
132
133#ifdef SOCLIB_IOC
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 )
145{
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/////////////////////////////////////////////////////////////////////////////////////
206int 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)
259void 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
283void 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
303
304/*
305 * vim: tabstop=4 : shiftwidth=4 : expandtab
306 */
Note: See TracBrowser for help on using the repository browser.