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

Last change on this file since 468 was 425, checked in by cfuguet, 11 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
RevLine 
[292]1#include <boot_ioc.h>
2
3#ifndef SOCLIB_IOC
4
[388]5static struct sdcard_dev  _sdcard_device;
6static struct spi_dev   * _spi_device   = ( struct spi_dev * )IOC_BASE;
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
[292]147int boot_ioc_read(unsigned int lba, void* buffer, unsigned int count)
148{
149
[412]150    unsigned int * ioc_address  = (unsigned int*)IOC_BASE;
[292]151
[412]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
[292]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
[347]181#if (CACHE_COHERENCE == 0)
182    boot_dbuf_invalidate(buffer, CACHE_LINE_SIZE, count * 512);
183#endif
[412]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
[347]193    return 0;
194}
195
[292]196#else
[388]197
[347]198///////////////////////////////////////////////////////////////////////////////
199// FPGA version of the boot_ioc_read function
200
201int boot_ioc_read(unsigned int lba, void* buffer, unsigned int count)
202{
[292]203    unsigned int sdcard_rsp;
[388]204    unsigned int i;
[292]205
206    sdcard_dev_lseek(&_sdcard_device, lba);
207
[412]208#if (BOOT_DEBUG ==1 && BOOT_DEBUG_IOC == 1)
[388]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
[292]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
[412]225                        )
[292]226            ))
227        {
[412]228            boot_puts("ERROR during read on the SDCARD device. Code: ");
[292]229            boot_putx(sdcard_rsp);
230            boot_puts("\n\r");
231
232            return 1;
[388]233        }
[292]234    }
235
[412]236#if (BOOT_DEBUG == 1 && BOOT_DEBUG_IOC == 1)
[388]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
[292]244    return 0;
245}
[347]246#endif
[292]247
248/**
249 * _dcache_buf_invalidate()
250 *
[412]251 * Invalidate all data cache lines corresponding to a memory
[347]252 * buffer (identified by an address and a size).
[292]253 */
[347]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;
[292]261
[412]262    // iterate on cache lines
[425]263    for (i = 0; i <= size; i += line_size) {
[347]264        asm volatile(
265            " cache %0, %1"
266            :// no outputs
267            :"i" (0x11), "R" (*((unsigned char *) buffer + i))
268            );
269    }
270}
271#endif
272
[292]273/*
274 * vim: tabstop=4 : shiftwidth=4 : expandtab
275 */
Note: See TracBrowser for help on using the repository browser.