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

Last change on this file since 577 was 568, checked in by cfuguet, 11 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
RevLine 
[292]1#include <boot_ioc.h>
2
3#ifndef SOCLIB_IOC
4
[388]5static struct sdcard_dev  _sdcard_device;
[554]6static struct spi_dev   *const  _spi_device   = ( struct spi_dev * )IOC_BASE;
[388]7
8#endif // end ifndef SOCLIB_IOC
[302]9
[388]10#define SDCARD_RESET_ITER_MAX 4
[302]11
[388]12inline void boot_sleep(int cycles)
13{
14    int i;
15    for (i = 0; i < cycles; i++);
16}
17
[412]18#if (BOOT_DEBUG == 1 && BOOT_DEBUG_IOC == 1)
[388]19inline unsigned int boot_proctime()
20{
21    unsigned int ret;
22    asm volatile ("mfc0 %0, $9":"=r" (ret));
23    return ret;
24}
[412]25#endif
[388]26
27#ifndef SOCLIB_IOC
[292]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
[412]44    );
[292]45
46    /**
47     * Initializing the SD Card
48     */
[388]49    unsigned int iter = 0;
[412]50    while(1)
[388]51    {
52        boot_puts("Trying to initialize SD card... ");
[292]53
[388]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        }
[292]60
[388]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
[292]73    /**
[388]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    /**
[292]84     * Incrementing SDCARD clock frequency for normal function
85     */
86    spi_dev_config (
87        _spi_device ,
[388]88        10000000    , /**< SPI_clk 10 Mhz */
89        SYSCLK_FREQ , /**< Sys_clk        */
90        -1          , /**< Charlen: 8     */
[292]91        -1          ,
92        -1
93    );
94
95    boot_puts("Finish block device initialization\n\r");
96
97    return 0;
98}
[388]99#endif // end ifndef SOCLIB_IOC
[292]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
[412]115    unsigned int * ioc_address = ( unsigned int * )IOC_BASE;
116
[292]117    while ( 1 )
[412]118    {
[292]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    }
[412]125
[292]126    return status;
127}
128#endif
129
130/**
131 * boot_ioc_read()
[412]132 *
[292]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 */
[347]142
143#ifdef SOCLIB_IOC
144///////////////////////////////////////////////////////////////////////////////
145// SOCLIB version of the boot_ioc_read function
146
[568]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
[292]156int boot_ioc_read(unsigned int lba, void* buffer, unsigned int count)
157{
158
[412]159    unsigned int * ioc_address  = (unsigned int*)IOC_BASE;
[292]160
[412]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
[292]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
[568]190#if (CACHE_COHERENCE == 0) || (USE_IOB == 1)
191    boot_buf_invalidate(buffer, CACHE_LINE_SIZE, count * 512);
[347]192#endif
[412]193
[568]194#if (USE_IOB == 1)
195    boot_mcc_invalidate(buffer, count * 512);
196#endif
197
[412]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
[347]206    return 0;
207}
208
[292]209#else
[388]210
[347]211///////////////////////////////////////////////////////////////////////////////
212// FPGA version of the boot_ioc_read function
213
214int boot_ioc_read(unsigned int lba, void* buffer, unsigned int count)
215{
[292]216    unsigned int sdcard_rsp;
[388]217    unsigned int i;
[292]218
219    sdcard_dev_lseek(&_sdcard_device, lba);
220
[412]221#if (BOOT_DEBUG ==1 && BOOT_DEBUG_IOC == 1)
[388]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
[292]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
[412]238                        )
[292]239            ))
240        {
[412]241            boot_puts("ERROR during read on the SDCARD device. Code: ");
[292]242            boot_putx(sdcard_rsp);
243            boot_puts("\n\r");
244
245            return 1;
[388]246        }
[292]247    }
248
[412]249#if (BOOT_DEBUG == 1 && BOOT_DEBUG_IOC == 1)
[388]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
[292]257    return 0;
258}
[347]259#endif
[292]260
261/**
262 * _dcache_buf_invalidate()
263 *
[412]264 * Invalidate all data cache lines corresponding to a memory
[347]265 * buffer (identified by an address and a size).
[292]266 */
[568]267#if (CACHE_COHERENCE == 0) || (USE_IOB == 1)
268void boot_buf_invalidate (
[347]269        const void * buffer,
270        unsigned int line_size,
271        unsigned int size)
272{
273    unsigned int i;
[292]274
[412]275    // iterate on cache lines
[425]276    for (i = 0; i <= size; i += line_size) {
[347]277        asm volatile(
278            " cache %0, %1"
279            :// no outputs
280            :"i" (0x11), "R" (*((unsigned char *) buffer + i))
281            );
282    }
283}
284#endif
285
[568]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
[292]315/*
316 * vim: tabstop=4 : shiftwidth=4 : expandtab
317 */
Note: See TracBrowser for help on using the repository browser.