source: trunk/softs/tsar_boot/src/boot_ioc.c @ 568

Last change on this file since 568 was 568, checked in by cfuguet, 10 years ago

Adding support for TSAR platforms using the vci_io_bridge component.

In this case (USE_IOB=1), when a block is read from the disk controller,
the buffer containing the read data must be invalidated in the Memory
Cache as the transfer is done between the disk controller and the RAM.

File size: 7.4 KB
Line 
1#include <boot_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 // end ifndef SOCLIB_IOC
9
10#define SDCARD_RESET_ITER_MAX 4
11
12inline void boot_sleep(int cycles)
13{
14    int i;
15    for (i = 0; i < cycles; i++);
16}
17
18#if (BOOT_DEBUG == 1 && BOOT_DEBUG_IOC == 1)
19inline unsigned int boot_proctime()
20{
21    unsigned int ret;
22    asm volatile ("mfc0 %0, $9":"=r" (ret));
23    return ret;
24}
25#endif
26
27#ifndef SOCLIB_IOC
28int boot_ioc_init()
29{
30    unsigned char sdcard_rsp;
31
32    boot_puts("Initializing block device\n\r");
33
34    /**
35     * Initializing the SPI controller
36     */
37    spi_dev_config (
38      _spi_device   ,
39      200000        , /**< SPI_clk: 200 Khz */
40      SYSCLK_FREQ   , /**< Sys_clk          */
41      8             , /**< Charlen: 8       */
42      SPI_TX_NEGEDGE,
43      SPI_RX_POSEDGE
44    );
45
46    /**
47     * Initializing the SD Card
48     */
49    unsigned int iter = 0;
50    while(1)
51    {
52        boot_puts("Trying to initialize SD card... ");
53
54        sdcard_rsp = sdcard_dev_open(&_sdcard_device, _spi_device, 0);
55        if (sdcard_rsp == 0)
56        {
57            boot_puts("OK\n");
58            break;
59        }
60
61        boot_puts("KO\n");
62        boot_sleep(1000);
63        if (++iter >= SDCARD_RESET_ITER_MAX)
64        {
65            boot_puts("\nERROR: During SD card reset to IDLE state\n"
66                      "/ card response = ");
67            boot_putx(sdcard_rsp);
68            boot_puts("\n");
69            boot_exit();
70        }
71    }
72
73    /**
74     * Set the block length of the SD Card
75     */
76    sdcard_rsp = sdcard_dev_set_blocklen(&_sdcard_device, 512);
77    if (sdcard_rsp)
78    {
79        boot_puts("ERROR: During SD card blocklen initialization\n");
80        boot_exit();
81    }
82
83    /**
84     * Incrementing SDCARD clock frequency for normal function
85     */
86    spi_dev_config (
87        _spi_device ,
88        10000000    , /**< SPI_clk 10 Mhz */
89        SYSCLK_FREQ , /**< Sys_clk        */
90        -1          , /**< Charlen: 8     */
91        -1          ,
92        -1
93    );
94
95    boot_puts("Finish block device initialization\n\r");
96
97    return 0;
98}
99#endif // end ifndef SOCLIB_IOC
100
101/**
102 * _boot_ioc_completed()
103 *
104 * This blocking function checks completion of an I/O transfer and reports errors.
105 *
106 * \note It returns 0 if the transfer is successfully completed.
107 *       It returns -1 if an error has been reported.
108 */
109#ifdef SOCLIB_IOC
110static int _boot_ioc_completed()
111{
112    unsigned int status = 0;
113
114
115    unsigned int * ioc_address = ( unsigned int * )IOC_BASE;
116
117    while ( 1 )
118    {
119        status = ioread32(&ioc_address[BLOCK_DEVICE_STATUS]);
120
121        if (( status == BLOCK_DEVICE_READ_SUCCESS ) ||
122            ( status == BLOCK_DEVICE_READ_ERROR  ))
123        break;
124    }
125
126    return status;
127}
128#endif
129
130/**
131 * boot_ioc_read()
132 *
133 * Transfer data from a file on the block device to a memory buffer.
134 *
135 * \param lba    : first block index on the disk
136 * \param buffer : base address of the memory buffer
137 * \param count  : number of blocks to be transfered
138 *
139 * \note This is a blocking function. The function returns once the transfer
140 *       has finished
141 */
142
143#ifdef SOCLIB_IOC
144///////////////////////////////////////////////////////////////////////////////
145// SOCLIB version of the boot_ioc_read function
146
147void boot_buf_invalidate (
148        const void * buffer,
149        unsigned int line_size,
150        unsigned int size);
151
152void boot_mcc_invalidate (
153        const void * buffer,
154        unsigned int size);
155
156int boot_ioc_read(unsigned int lba, void* buffer, unsigned int count)
157{
158
159    unsigned int * ioc_address  = (unsigned int*)IOC_BASE;
160
161#if (BOOT_DEBUG == 1 && BOOT_DEBUG_IOC == 1)
162    unsigned int start_time;
163    unsigned int end_time;
164    boot_puts("[ DEBUG ] Reading blocks ");
165    boot_putd(lba);
166    boot_puts(" to ");
167    boot_putd(lba + count - 1);
168
169    start_time = boot_proctime();
170#endif
171
172    // block_device configuration
173    iowrite32( &ioc_address[BLOCK_DEVICE_BUFFER],
174            ( unsigned int ) buffer );
175
176    iowrite32( &ioc_address[BLOCK_DEVICE_COUNT],
177            ( unsigned int ) count );
178
179    iowrite32( &ioc_address[BLOCK_DEVICE_LBA],
180            ( unsigned int ) lba );
181
182    iowrite32( &ioc_address[BLOCK_DEVICE_IRQ_ENABLE],
183            ( unsigned int ) 0 );
184
185    iowrite32( &ioc_address[BLOCK_DEVICE_OP],
186            ( unsigned int ) BLOCK_DEVICE_READ );
187
188    _boot_ioc_completed();
189
190#if (CACHE_COHERENCE == 0) || (USE_IOB == 1)
191    boot_buf_invalidate(buffer, CACHE_LINE_SIZE, count * 512);
192#endif
193
194#if (USE_IOB == 1)
195    boot_mcc_invalidate(buffer, count * 512);
196#endif
197
198#if (BOOT_DEBUG == 1 && BOOT_DEBUG_IOC == 1)
199    end_time = boot_proctime();
200
201    boot_puts(" / cycles for transfert: ");
202    boot_putd(end_time - start_time);
203    boot_puts("\n");
204#endif
205
206    return 0;
207}
208
209#else
210
211///////////////////////////////////////////////////////////////////////////////
212// FPGA version of the boot_ioc_read function
213
214int boot_ioc_read(unsigned int lba, void* buffer, unsigned int count)
215{
216    unsigned int sdcard_rsp;
217    unsigned int i;
218
219    sdcard_dev_lseek(&_sdcard_device, lba);
220
221#if (BOOT_DEBUG ==1 && BOOT_DEBUG_IOC == 1)
222    unsigned int start_time;
223    unsigned int end_time;
224    boot_puts("[ DEBUG ] Reading blocks ");
225    boot_putd(lba);
226    boot_puts(" to ");
227    boot_putd(lba + count - 1);
228
229    start_time = boot_proctime();
230#endif
231
232    for(i = 0; i < count; i++)
233    {
234        if (( sdcard_rsp = sdcard_dev_read (
235                        &_sdcard_device,
236                        (unsigned char *) buffer + (512 * i),
237                        512
238                        )
239            ))
240        {
241            boot_puts("ERROR during read on the SDCARD device. Code: ");
242            boot_putx(sdcard_rsp);
243            boot_puts("\n\r");
244
245            return 1;
246        }
247    }
248
249#if (BOOT_DEBUG == 1 && BOOT_DEBUG_IOC == 1)
250    end_time = boot_proctime();
251
252    boot_puts(" / cycles for transfert: ");
253    boot_putd(end_time - start_time);
254    boot_puts("\n");
255#endif
256
257    return 0;
258}
259#endif
260
261/**
262 * _dcache_buf_invalidate()
263 *
264 * Invalidate all data cache lines corresponding to a memory
265 * buffer (identified by an address and a size).
266 */
267#if (CACHE_COHERENCE == 0) || (USE_IOB == 1)
268void boot_buf_invalidate (
269        const void * buffer,
270        unsigned int line_size,
271        unsigned int size)
272{
273    unsigned int i;
274
275    // iterate on cache lines
276    for (i = 0; i <= size; i += line_size) {
277        asm volatile(
278            " cache %0, %1"
279            :// no outputs
280            :"i" (0x11), "R" (*((unsigned char *) buffer + i))
281            );
282    }
283}
284#endif
285
286/**
287 * boot_mcc_inval()
288 *
289 * Invalidate all data cache lines corresponding to a memory
290 * buffer (identified by an address and a size).
291 */
292#if (USE_IOB == 1)
293void boot_mcc_invalidate (
294        const void * buffer,
295        unsigned int size)
296{
297    unsigned int * mcc_address = (unsigned int *)MCC_BASE;
298
299    // get the hard lock assuring exclusive access to MEMC
300    while (ioread32(&mcc_address[MCC_LOCK]));
301
302    // write invalidate paremeters on the memory cache
303    // this preloader use only the cluster 0 and then the HI bits are not used
304   
305    iowrite32(&mcc_address[MCC_ADDR_LO], (unsigned int) buffer);
306    iowrite32(&mcc_address[MCC_ADDR_HI], (unsigned int) 0);
307    iowrite32(&mcc_address[MCC_LENGTH] , (unsigned int) size);
308    iowrite32(&mcc_address[MCC_CMD]    , (unsigned int) MCC_CMD_INVAL);
309
310    // release the lock protecting MEMC
311    iowrite32(&mcc_address[MCC_LOCK], (unsigned int) 0);
312}
313#endif
314
315/*
316 * vim: tabstop=4 : shiftwidth=4 : expandtab
317 */
Note: See TracBrowser for help on using the repository browser.