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

Last change on this file since 371 was 347, checked in by cfuguet, 12 years ago

Introducing dcache line invalidation mechanism in the boot_ioc_read
function, when using platform without cache coherency.

Introducing two parameters in the defs_platform.h file:

CACHE_COHERENCE

Equals to 0 when no cache coherency

CACHE_LINE_SIZE

Number of bytes in a cache line

  • TODO: Use the config register of the cache models to get

this size

Adding new platform configuration file for the

caba_vgsb_xicu_mmu SOCLIB platform.


File size: 4.5 KB
Line 
1#include <boot_ioc.h>
2
3#ifndef SOCLIB_IOC
4
5#ifndef SYSCLK_FREQ
6#warning "Using default value for SYSCLK_FREQ = 50000000"
7#define SYSCLK_FREQ 50000000U
8#endif
9
10static struct sdcard_dev  _sdcard_device;
11static struct spi_dev   * _spi_device   = ( struct spi_dev * )IOC_BASE;
12#endif
13
14
15int boot_ioc_init()
16{
17#ifdef SOCLIB_IOC
18    return 0;
19#else
20    unsigned char sdcard_rsp;
21
22    boot_puts("Initializing block device\n\r");
23
24    /**
25     * Initializing the SPI controller
26     */
27    spi_dev_config (
28      _spi_device   ,
29      200000        , /**< SPI_clk: 200 Khz */
30      SYSCLK_FREQ   , /**< Sys_clk          */
31      8             , /**< Charlen: 8       */
32      SPI_TX_NEGEDGE,
33      SPI_RX_POSEDGE
34    ); 
35
36    /**
37     * Initializing the SD Card
38     */
39    if ( (sdcard_rsp = sdcard_dev_open(&_sdcard_device, _spi_device, 0)) )
40        return sdcard_rsp;
41
42    if ( (sdcard_rsp = sdcard_dev_set_blocklen(&_sdcard_device, 512)) )
43        return sdcard_rsp;
44
45    /**
46     * Incrementing SDCARD clock frequency for normal function
47     */
48    spi_dev_config (
49        _spi_device ,
50        10000000    , /**< SPI_clkL 10 Mhz */
51        SYSCLK_FREQ , /**< Sys_clk         */
52        -1          , /**< Charlen: 8      */
53        -1          ,
54        -1
55    );
56
57    boot_puts("Finish block device initialization\n\r");
58
59    return 0;
60#endif
61}
62
63/**
64 * _boot_ioc_completed()
65 *
66 * This blocking function checks completion of an I/O transfer and reports errors.
67 *
68 * \note It returns 0 if the transfer is successfully completed.
69 *       It returns -1 if an error has been reported.
70 */
71#ifdef SOCLIB_IOC
72static int _boot_ioc_completed()
73{
74    unsigned int status = 0;
75
76
77    unsigned int * ioc_address = ( unsigned int * )VCIBD_BASE;
78 
79    while ( 1 )
80    { 
81        status = ioread32(&ioc_address[BLOCK_DEVICE_STATUS]);
82
83        if (( status == BLOCK_DEVICE_READ_SUCCESS ) ||
84            ( status == BLOCK_DEVICE_READ_ERROR  ))
85        break;
86    }
87   
88    return status;
89}
90#endif
91
92/**
93 * boot_ioc_read()
94 *
95 * Transfer data from a file on the block device to a memory buffer.
96 *
97 * \param lba    : first block index on the disk
98 * \param buffer : base address of the memory buffer
99 * \param count  : number of blocks to be transfered
100 *
101 * \note This is a blocking function. The function returns once the transfer
102 *       has finished
103 */
104
105#ifdef SOCLIB_IOC
106///////////////////////////////////////////////////////////////////////////////
107// SOCLIB version of the boot_ioc_read function
108
109int boot_ioc_read(unsigned int lba, void* buffer, unsigned int count)
110{
111
112    unsigned int * ioc_address  = (unsigned int*)VCIBD_BASE;
113
114    // block_device configuration
115    iowrite32( &ioc_address[BLOCK_DEVICE_BUFFER],
116            ( unsigned int ) buffer );
117
118    iowrite32( &ioc_address[BLOCK_DEVICE_COUNT],
119            ( unsigned int ) count );
120
121    iowrite32( &ioc_address[BLOCK_DEVICE_LBA],
122            ( unsigned int ) lba );
123
124    iowrite32( &ioc_address[BLOCK_DEVICE_IRQ_ENABLE],
125            ( unsigned int ) 0 );
126
127    iowrite32( &ioc_address[BLOCK_DEVICE_OP],
128            ( unsigned int ) BLOCK_DEVICE_READ );
129
130    _boot_ioc_completed();
131
132#if (CACHE_COHERENCE == 0)
133    boot_dbuf_invalidate(buffer, CACHE_LINE_SIZE, count * 512);
134#endif
135    return 0;
136}
137
138#else
139///////////////////////////////////////////////////////////////////////////////
140// FPGA version of the boot_ioc_read function
141
142int boot_ioc_read(unsigned int lba, void* buffer, unsigned int count)
143{
144    unsigned int sdcard_rsp;
145
146    sdcard_dev_lseek(&_sdcard_device, lba);
147
148    unsigned int i;
149    for(i = 0; i < count; i++)
150    {
151        if (( sdcard_rsp = sdcard_dev_read (
152                        &_sdcard_device,
153                        (unsigned char *) buffer + (512 * i),
154                        512
155                        ) 
156            ))
157        {
158            boot_puts("ERROR during read on the SDCARD device. Code: "); 
159            boot_putx(sdcard_rsp);
160            boot_puts("\n\r");
161
162            return 1;
163        }   
164    }
165
166    return 0;
167}
168#endif
169
170/**
171 * _dcache_buf_invalidate()
172 *
173 * Invalidate all data cache lines corresponding to a memory
174 * buffer (identified by an address and a size).
175 */
176#if (CACHE_COHERENCE == 0)
177void boot_dbuf_invalidate (
178        const void * buffer,
179        unsigned int line_size,
180        unsigned int size)
181{
182    unsigned int i;
183
184    // iterate on cache lines
185    for (i = 0; i < size; i += line_size) {
186        asm volatile(
187            " cache %0, %1"
188            :// no outputs
189            :"i" (0x11), "R" (*((unsigned char *) buffer + i))
190            );
191    }
192}
193#endif
194
195/*
196 * vim: tabstop=4 : shiftwidth=4 : expandtab
197 */
Note: See TracBrowser for help on using the repository browser.