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

Last change on this file since 292 was 292, checked in by cfuguet, 11 years ago

Changing directory structure of the TSAR boot loader.
A README.txt file has been included to explain the new structure
and the MAKEFILE parameters.

Erasing the heap segment for the boot elf loader. All the work space
is allocated in the stack.

The stack size is defined in the include/defs.h.

Important modification in the reset.S file. The non-boot
processors (processor id != 0) wait in a low comsumption energy
mode to be wake up by processor 0 using an IPI. Each processor
has a private mailbox in the local XICU. The value written in
the mailbox will be used as address to jump by the processors.

The waking up of non-boot processors is not done in this boot loader
so it must be done in the application loaded.

The boot_loader_elf function loads into memory an executable .elf file
which must be placed in the BOOT_LOADER_LBA block of the disk. This
constant can be defined in the include/defs.h file.

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