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

Last change on this file since 457 was 425, checked in by cfuguet, 12 years ago

Modifications in tsar_boot:

  • Creating new files boot_utils.[c h] containing the memcpy, memset and some ELF format debug functions
  • Introducing assert in the boot_elf_loader to show an error when some of segments to load conflicts with some of the pre-loader segments
  • Cosmetic changes in boot_elf_loader to improve code readibility
  • Fixing bug in dcache_buf_invalidate function used by boot_ioc_read when cache coherence not supported. The condition in the for loop was erroneous.
  • Modification in Makefile: The SYSCLK_FREQ parameter is not passed anymore

as a Makefile parameter but it is definesd in the defs_platform.h file

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   * _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.