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

Last change on this file since 404 was 388, checked in by cfuguet, 12 years ago

Modifications in tsar/trunk/softs/tsar_boot:

  • Improving the boot_ioc_read when using a SD card in FPGA platform.
  • Adding some instrumentation on the SD card driver (under preprocessor conditional directives).
  • Including Doxyfile for generate documentation using doxygen.
  • Improving the Makefile to include doc generation.
File size: 5.9 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 INSTRUMENTATION
24inline unsigned int boot_proctime()
25{
26    unsigned int ret;
27    asm volatile ("mfc0 %0, $9":"=r" (ret));
28    return ret;
29}
30#endif // end if INSTRUMENTATION
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 * )VCIBD_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*)VCIBD_BASE;
156
157    // block_device configuration
158    iowrite32( &ioc_address[BLOCK_DEVICE_BUFFER],
159            ( unsigned int ) buffer );
160
161    iowrite32( &ioc_address[BLOCK_DEVICE_COUNT],
162            ( unsigned int ) count );
163
164    iowrite32( &ioc_address[BLOCK_DEVICE_LBA],
165            ( unsigned int ) lba );
166
167    iowrite32( &ioc_address[BLOCK_DEVICE_IRQ_ENABLE],
168            ( unsigned int ) 0 );
169
170    iowrite32( &ioc_address[BLOCK_DEVICE_OP],
171            ( unsigned int ) BLOCK_DEVICE_READ );
172
173    _boot_ioc_completed();
174
175#if (CACHE_COHERENCE == 0)
176    boot_dbuf_invalidate(buffer, CACHE_LINE_SIZE, count * 512);
177#endif
178    return 0;
179}
180
181#else
182
183///////////////////////////////////////////////////////////////////////////////
184// FPGA version of the boot_ioc_read function
185
186int boot_ioc_read(unsigned int lba, void* buffer, unsigned int count)
187{
188    unsigned int sdcard_rsp;
189    unsigned int i;
190
191    sdcard_dev_lseek(&_sdcard_device, lba);
192
193#if INSTRUMENTATION
194    unsigned int start_time;
195    unsigned int end_time;
196    boot_puts("[ DEBUG ] Reading blocks ");
197    boot_putd(lba);
198    boot_puts(" to ");
199    boot_putd(lba + count - 1);
200
201    start_time = boot_proctime();
202#endif
203
204    for(i = 0; i < count; i++)
205    {
206        if (( sdcard_rsp = sdcard_dev_read (
207                        &_sdcard_device,
208                        (unsigned char *) buffer + (512 * i),
209                        512
210                        ) 
211            ))
212        {
213            boot_puts("ERROR during read on the SDCARD device. Code: "); 
214            boot_putx(sdcard_rsp);
215            boot_puts("\n\r");
216
217            return 1;
218        }
219    }
220
221#if INSTRUMENTATION
222    end_time = boot_proctime();
223
224    boot_puts(" / cycles for transfert: ");
225    boot_putd(end_time - start_time);
226    boot_puts("\n");
227#endif
228
229    return 0;
230}
231#endif
232
233/**
234 * _dcache_buf_invalidate()
235 *
236 * Invalidate all data cache lines corresponding to a memory
237 * buffer (identified by an address and a size).
238 */
239#if (CACHE_COHERENCE == 0)
240void boot_dbuf_invalidate (
241        const void * buffer,
242        unsigned int line_size,
243        unsigned int size)
244{
245    unsigned int i;
246
247    // iterate on cache lines
248    for (i = 0; i < size; i += line_size) {
249        asm volatile(
250            " cache %0, %1"
251            :// no outputs
252            :"i" (0x11), "R" (*((unsigned char *) buffer + i))
253            );
254    }
255}
256#endif
257
258/*
259 * vim: tabstop=4 : shiftwidth=4 : expandtab
260 */
Note: See TracBrowser for help on using the repository browser.