#include #include #ifndef SOCLIB_IOC static struct sdcard_dev _sdcard_device; static struct spi_dev * _spi_device = ( struct spi_dev * )IOC_BASE; #endif #ifndef SYSCLK_FREQ #warning "Using default value for SYSCLK_FREQ = 50000000" #define SYSCLK_FREQ 50000000U #endif int boot_ioc_init() { #ifndef SOCLIB_IOC unsigned char sdcard_rsp; boot_puts("Initializing block device\n\r"); /** * Initializing the SPI controller */ spi_dev_config ( _spi_device , 200000 , /**< SPI_clk: 200 Khz */ SYSCLK_FREQ , /**< Sys_clk */ 8 , /**< Charlen: 8 */ SPI_TX_NEGEDGE, SPI_RX_POSEDGE ); /** * Initializing the SD Card */ if ( (sdcard_rsp = sdcard_dev_open(&_sdcard_device, _spi_device, 0)) ) return sdcard_rsp; if ( (sdcard_rsp = sdcard_dev_set_blocklen(&_sdcard_device, 512)) ) return sdcard_rsp; /** * Incrementing SDCARD clock frequency for normal function */ spi_dev_config ( _spi_device , 10000000 , /**< SPI_clkL 10 Mhz */ SYSCLK_FREQ , /**< Sys_clk */ -1 , /**< Charlen: 8 */ -1 , -1 ); boot_puts("Finish block device initialization\n\r"); #endif return 0; } /** * _boot_ioc_completed() * * This blocking function checks completion of an I/O transfer and reports errors. * * \note It returns 0 if the transfer is successfully completed. * It returns -1 if an error has been reported. */ #ifdef SOCLIB_IOC static int _boot_ioc_completed() { unsigned int status = 0; unsigned int * ioc_address = ( unsigned int * )VCIBD_BASE; while ( 1 ) { status = ioread32(&ioc_address[BLOCK_DEVICE_STATUS]); if (( status == BLOCK_DEVICE_READ_SUCCESS ) || ( status == BLOCK_DEVICE_READ_ERROR )) break; } return status; } #endif /** * boot_ioc_read() * * Transfer data from a file on the block device to a memory buffer. * * \param lba : first block index on the disk * \param buffer : base address of the memory buffer * \param count : number of blocks to be transfered * * \note This is a blocking function. The function returns once the transfer * has finished */ int boot_ioc_read(unsigned int lba, void* buffer, unsigned int count) { #ifdef SOCLIB_IOC unsigned int * ioc_address = (unsigned int*)VCIBD_BASE; // block_device configuration iowrite32( &ioc_address[BLOCK_DEVICE_BUFFER], ( unsigned int ) buffer ); iowrite32( &ioc_address[BLOCK_DEVICE_COUNT], ( unsigned int ) count ); iowrite32( &ioc_address[BLOCK_DEVICE_LBA], ( unsigned int ) lba ); iowrite32( &ioc_address[BLOCK_DEVICE_IRQ_ENABLE], ( unsigned int ) 0 ); iowrite32( &ioc_address[BLOCK_DEVICE_OP], ( unsigned int ) BLOCK_DEVICE_READ ); _boot_ioc_completed(); #else unsigned int sdcard_rsp; sdcard_dev_lseek(&_sdcard_device, lba); unsigned int i; for(i = 0; i < count; i++) { if (( sdcard_rsp = sdcard_dev_read ( &_sdcard_device, (unsigned char *) buffer + (512 * i), 512 ) )) { boot_puts("ERROR during read on the SDCARD device. Code: "); boot_putx(sdcard_rsp); boot_puts("\n\r"); return 1; } } #endif return 0; } /** * boot_ioc_write() * * Transfer data from a memory buffer to a file on the block_device. * * \param lba : first block index on the disk * \param buffer : base address of the memory buffer * \param count : number of blocks to be transfered * * \note The source buffer must be in user address space. * *in_reset int _ioc_write(unsigned int lba, void* buffer, unsigned int count) *{ *#ifdef SOCLIB_IOC * * unsigned int * ioc_address = ( unsigned int * )VCIBD_BASE; * * // block_device configuration * iowrite32( &ioc_address[BLOCK_DEVICE_BUFFER], * ( unsigned int ) buffer ); * * iowrite32( &ioc_address[BLOCK_DEVICE_COUNT], * ( unsigned int ) count ); * * iowrite32( &ioc_address[BLOCK_DEVICE_LBA], * ( unsigned int ) lba ); * * iowrite32( &ioc_address[BLOCK_DEVICE_IRQ_ENABLE], * ( unsigned int ) 0 ); * * iowrite32( &ioc_address[BLOCK_DEVICE_OP], * ( unsigned int ) BLOCK_DEVICE_WRITE); * * _boot_ioc_completed(); * *#else * * sdcard_dev_lseek(&_sdcard_device, lba); * sdcard_dev_write(&_sdcard_device, buffer, count*512); * *#endif * * return 0; *} */ /** * _dcache_buf_invalidate() * * Invalidate all cache lines corresponding to a memory buffer. * This is used by the block_device driver. * *in_reset static void _dcache_buf_invalidate(const void * buffer, unsigned int size) *{ * unsigned int i; * unsigned int dcache_line_size; * * // retrieve dcache line size from config register (bits 12:10) * asm volatile("mfc0 %0, $16, 1" : "=r" (dcache_line_size)); * * dcache_line_size = 2 << ((dcache_line_size>>10) & 0x7); * * // iterate on lines to invalidate each one of them * for ( i=0; i