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

Last change on this file since 558 was 554, checked in by bouyer, 11 years ago

Make sure the boot loader won't try to write to the ROM.
Store read-write data in BSS along with the stack at seg_stack_base.

File size: 6.2 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
147int boot_ioc_read(unsigned int lba, void* buffer, unsigned int count)
148{
149
150    unsigned int * ioc_address  = (unsigned int*)IOC_BASE;
151
152#if (BOOT_DEBUG == 1 && BOOT_DEBUG_IOC == 1)
153    unsigned int start_time;
154    unsigned int end_time;
155    boot_puts("[ DEBUG ] Reading blocks ");
156    boot_putd(lba);
157    boot_puts(" to ");
158    boot_putd(lba + count - 1);
159
160    start_time = boot_proctime();
161#endif
162
163    // block_device configuration
164    iowrite32( &ioc_address[BLOCK_DEVICE_BUFFER],
165            ( unsigned int ) buffer );
166
167    iowrite32( &ioc_address[BLOCK_DEVICE_COUNT],
168            ( unsigned int ) count );
169
170    iowrite32( &ioc_address[BLOCK_DEVICE_LBA],
171            ( unsigned int ) lba );
172
173    iowrite32( &ioc_address[BLOCK_DEVICE_IRQ_ENABLE],
174            ( unsigned int ) 0 );
175
176    iowrite32( &ioc_address[BLOCK_DEVICE_OP],
177            ( unsigned int ) BLOCK_DEVICE_READ );
178
179    _boot_ioc_completed();
180
181#if (CACHE_COHERENCE == 0)
182    boot_dbuf_invalidate(buffer, CACHE_LINE_SIZE, count * 512);
183#endif
184
185#if (BOOT_DEBUG == 1 && BOOT_DEBUG_IOC == 1)
186    end_time = boot_proctime();
187
188    boot_puts(" / cycles for transfert: ");
189    boot_putd(end_time - start_time);
190    boot_puts("\n");
191#endif
192
193    return 0;
194}
195
196#else
197
198///////////////////////////////////////////////////////////////////////////////
199// FPGA version of the boot_ioc_read function
200
201int boot_ioc_read(unsigned int lba, void* buffer, unsigned int count)
202{
203    unsigned int sdcard_rsp;
204    unsigned int i;
205
206    sdcard_dev_lseek(&_sdcard_device, lba);
207
208#if (BOOT_DEBUG ==1 && BOOT_DEBUG_IOC == 1)
209    unsigned int start_time;
210    unsigned int end_time;
211    boot_puts("[ DEBUG ] Reading blocks ");
212    boot_putd(lba);
213    boot_puts(" to ");
214    boot_putd(lba + count - 1);
215
216    start_time = boot_proctime();
217#endif
218
219    for(i = 0; i < count; i++)
220    {
221        if (( sdcard_rsp = sdcard_dev_read (
222                        &_sdcard_device,
223                        (unsigned char *) buffer + (512 * i),
224                        512
225                        )
226            ))
227        {
228            boot_puts("ERROR during read on the SDCARD device. Code: ");
229            boot_putx(sdcard_rsp);
230            boot_puts("\n\r");
231
232            return 1;
233        }
234    }
235
236#if (BOOT_DEBUG == 1 && BOOT_DEBUG_IOC == 1)
237    end_time = boot_proctime();
238
239    boot_puts(" / cycles for transfert: ");
240    boot_putd(end_time - start_time);
241    boot_puts("\n");
242#endif
243
244    return 0;
245}
246#endif
247
248/**
249 * _dcache_buf_invalidate()
250 *
251 * Invalidate all data cache lines corresponding to a memory
252 * buffer (identified by an address and a size).
253 */
254#if (CACHE_COHERENCE == 0)
255void boot_dbuf_invalidate (
256        const void * buffer,
257        unsigned int line_size,
258        unsigned int size)
259{
260    unsigned int i;
261
262    // iterate on cache lines
263    for (i = 0; i <= size; i += line_size) {
264        asm volatile(
265            " cache %0, %1"
266            :// no outputs
267            :"i" (0x11), "R" (*((unsigned char *) buffer + i))
268            );
269    }
270}
271#endif
272
273/*
274 * vim: tabstop=4 : shiftwidth=4 : expandtab
275 */
Note: See TracBrowser for help on using the repository browser.