# HG changeset patch # User bartv # Date 1100993519 0 # Node ID a668b95e5f2e8ea4f7f44840abf17a736b411b60 # Parent 9464c6747e99af0f993bcd49818c8e8043a3c5c4 Only include the support for indirect flash reads if there are devices which need it. diff --git a/packages/devs/flash/atmel/dataflash/current/ChangeLog b/packages/devs/flash/atmel/dataflash/current/ChangeLog --- a/packages/devs/flash/atmel/dataflash/current/ChangeLog +++ b/packages/devs/flash/atmel/dataflash/current/ChangeLog @@ -1,3 +1,8 @@ +2004-11-20 Bart Veer + + * cdl/devs_flash_atmel_dataflash.cdl: data flash requires indirect + read support in the main flash code. + 2004-10-07 Savin Zlobec * include/dataflash.h: diff --git a/packages/devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl b/packages/devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl --- a/packages/devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl +++ b/packages/devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl @@ -62,6 +62,7 @@ cdl_package CYGPKG_DEVS_FLASH_ATMEL_DATA active_if CYGPKG_IO_FLASH implements CYGHWR_IO_FLASH_DEVICE implements CYGHWR_IO_FLASH_DEVICE_V2 + implements CYGHWR_IO_FLASH_INDIRECT_READS compile devs_flash_atmel_dataflash_flash_dev_funs.c description "This option will be enabled by platforms which need to support access to DataFlash through IO Flash API." diff --git a/packages/devs/flash/toshiba/tc58xxx/current/ChangeLog b/packages/devs/flash/toshiba/tc58xxx/current/ChangeLog --- a/packages/devs/flash/toshiba/tc58xxx/current/ChangeLog +++ b/packages/devs/flash/toshiba/tc58xxx/current/ChangeLog @@ -1,3 +1,8 @@ +2004-11-20 Bart Veer + + * cdl/flash_toshiba_tc58xxx.cdl: NAND flash requires indirect read + support in the main flash code + 2004-08-03 Andrew Lunn * cdl/flash_toshiba_tc58xxx.cdl: Indicate we need the legacy device API diff --git a/packages/devs/flash/toshiba/tc58xxx/current/cdl/flash_toshiba_tc58xxx.cdl b/packages/devs/flash/toshiba/tc58xxx/current/cdl/flash_toshiba_tc58xxx.cdl --- a/packages/devs/flash/toshiba/tc58xxx/current/cdl/flash_toshiba_tc58xxx.cdl +++ b/packages/devs/flash/toshiba/tc58xxx/current/cdl/flash_toshiba_tc58xxx.cdl @@ -62,6 +62,7 @@ cdl_package CYGPKG_DEVS_FLASH_TOSHIBA_TC implements CYGHWR_IO_FLASH_DEVICE implements CYGHWR_IO_FLASH_DEVICE_LEGACY + implements CYGHWR_IO_FLASH_INDIRECT_READS include_dir cyg/io } diff --git a/packages/io/flash/current/ChangeLog b/packages/io/flash/current/ChangeLog --- a/packages/io/flash/current/ChangeLog +++ b/packages/io/flash/current/ChangeLog @@ -1,5 +1,8 @@ 2004-11-20 Bart Veer + * cdl/io_flash.cdl, src/flash.c(cyg_flash_read): add an interface + for hardware which requires indirect reads, and suppress + unnecessary code if direct reads are always available. * src/flash.c: rearrange loops to avoid address comparisons, which tend to go wrong if the flash is at the end of the address space diff --git a/packages/io/flash/current/cdl/io_flash.cdl b/packages/io/flash/current/cdl/io_flash.cdl --- a/packages/io/flash/current/cdl/io_flash.cdl +++ b/packages/io/flash/current/cdl/io_flash.cdl @@ -95,6 +95,17 @@ cdl_package CYGPKG_IO_FLASH { locking (write-protection) of individual blocks." } + cdl_interface CYGHWR_IO_FLASH_INDIRECT_READS { + display "Hardware requires indirect reads" + flavor booldata + description " + Some flash devices can be read directly like any other + memory. Others can only be accessed indirectly, which + involves extra code. If none of the flash devices on the + target hardware use indirect reads then the extra code + can be eliminated." + } + cdl_interface CYGHWR_IO_FLASH_DEVICE_LEGACY { display "Hardware driver uses the legacy interface" flavor booldata @@ -343,4 +354,4 @@ cdl_package CYGPKG_IO_FLASH { } } } -} \ No newline at end of file +} diff --git a/packages/io/flash/current/src/flash.c b/packages/io/flash/current/src/flash.c --- a/packages/io/flash/current/src/flash.c +++ b/packages/io/flash/current/src/flash.c @@ -586,11 +586,10 @@ cyg_flash_read(cyg_flashaddr_t flash_bas cyg_flashaddr_t *err_address) { struct cyg_flash_dev * dev; - cyg_flashaddr_t addr, end_addr, block; + cyg_flashaddr_t addr, end_addr; unsigned char * ram = (unsigned char *)ram_base; - size_t read_count, offset; + size_t read_count; int stat = CYG_FLASH_ERR_OK; - int d_cache, i_cache; if (!init) return CYG_FLASH_ERR_NOT_INIT; @@ -611,52 +610,61 @@ cyg_flash_read(cyg_flashaddr_t flash_bas } read_count = (end_addr + 1) - flash_base; - // The first read may be in the middle of a block. Do the necessary - // adjustment here rather than inside the loop. - block = flash_block_begin(flash_base, dev); - if (addr == block) { - offset = 0; - } else { - offset = addr - block; - } - #ifdef CYGSEM_IO_FLASH_CHATTER dev->pf("... Read from %p-%p to %p: ", addr, end_addr, ram_base); #endif - - HAL_FLASH_CACHES_OFF(d_cache, i_cache); - FLASH_Enable(flash_base, end_addr); - while (read_count > 0) { - size_t block_size = flash_block_size(dev, addr); - size_t this_read; - if (read_count > (block_size - offset)) { - this_read = block_size - offset; - } else { - this_read = read_count; - } - // Only the first block may need the offset - offset = 0; + + // If the flash is directly accessible, just read it in one go. This + // still happens with the mutex locked to protect against concurrent + // programs/erases. + if (! dev->funs->flash_read) { + memcpy(ram, (void*)addr, read_count); + } else { +#ifndef CYGHWR_IO_FLASH_INDIRECT_READS + CYG_FAIL("read function supplied but indirect reads not enabled"); + stat = CYG_FLASH_ERR_PROTOCOL; +#else + // We have to indirect through the device driver. + // The first read may be in the middle of a block. Do the necessary + // adjustment here rather than inside the loop. + int d_cache, i_cache; + size_t offset; + cyg_flashaddr_t block = flash_block_begin(flash_base, dev); + if (addr == block) { + offset = 0; + } else { + offset = addr - block; + } + HAL_FLASH_CACHES_OFF(d_cache, i_cache); + FLASH_Enable(flash_base, end_addr); + while (read_count > 0) { + size_t block_size = flash_block_size(dev, addr); + size_t this_read; + if (read_count > (block_size - offset)) { + this_read = block_size - offset; + } else { + this_read = read_count; + } + // Only the first block may need the offset + offset = 0; - if (dev->funs->flash_read) { - stat = dev->funs->flash_read(dev, addr, ram, this_read); - stat = dev->funs->flash_hwr_map_error(dev,stat); - } else { - memcpy(ram, (void *)addr, this_read); - stat = CYG_FLASH_ERR_OK; - } - if (CYG_FLASH_ERR_OK != stat && err_address) { - *err_address = addr; - break; - } + stat = dev->funs->flash_read(dev, addr, ram, this_read); + stat = dev->funs->flash_hwr_map_error(dev,stat); + if (CYG_FLASH_ERR_OK != stat && err_address) { + *err_address = addr; + break; + } #ifdef CYGSEM_IO_FLASH_CHATTER - dev->pf("."); + dev->pf("."); #endif - read_count -= this_read; - addr += this_read; - ram += this_read; + read_count -= this_read; + addr += this_read; + ram += this_read; + } + FLASH_Disable(flash_base, end_addr); + HAL_FLASH_CACHES_ON(d_cache, i_cache); +#endif } - FLASH_Disable(flash_base, end_addr); - HAL_FLASH_CACHES_ON(d_cache, i_cache); #ifdef CYGSEM_IO_FLASH_CHATTER dev->pf("\n"); #endif