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

Last change on this file since 412 was 412, checked in by porquet, 11 years ago

boot_tsar: bug fix and more debug

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