This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
V2 flash - read optimization
- From: Bart Veer <bartv at ecoscentric dot com>
- To: ecos-patches at ecos dot sourceware dot org
- Date: Sat, 20 Nov 2004 23:27:14 +0000 (GMT)
- Subject: V2 flash - read optimization
This patch does two things. First, if direct reads are available then
a cyg_flash_read() now does a single memcpy(), without iterating over
the flash blocks. Second, if none of the flash devices require
indirect reads then the relevant code is suppressed, saving a bit of
code on most targets. This is handled via a new interface
CYGHWR_IO_FLASH_INDIRECT_READS, currently implemented only by the
dataflash and tc58xxx nand flash drivers.
Bart
Index: io/flash/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/flash/current/ChangeLog,v
retrieving revision 1.38.2.11
diff -u -r1.38.2.11 ChangeLog
--- io/flash/current/ChangeLog 20 Nov 2004 19:27:26 -0000 1.38.2.11
+++ io/flash/current/ChangeLog 20 Nov 2004 23:05:17 -0000
@@ -1,5 +1,8 @@
2004-11-20 Bart Veer <bartv@ecoscentric.com>
+ * 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
Index: io/flash/current/cdl/io_flash.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/flash/current/cdl/io_flash.cdl,v
retrieving revision 1.17.2.1
diff -u -r1.17.2.1 io_flash.cdl
--- io/flash/current/cdl/io_flash.cdl 5 Aug 2004 13:50:00 -0000 1.17.2.1
+++ io/flash/current/cdl/io_flash.cdl 20 Nov 2004 23:05:18 -0000
@@ -95,6 +95,17 @@
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 @@
}
}
}
-}
\ No newline at end of file
+}
Index: io/flash/current/src/flash.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/flash/current/src/flash.c,v
retrieving revision 1.26.2.7
diff -u -r1.26.2.7 flash.c
--- io/flash/current/src/flash.c 20 Nov 2004 19:27:26 -0000 1.26.2.7
+++ io/flash/current/src/flash.c 20 Nov 2004 23:05:21 -0000
@@ -586,11 +586,10 @@
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,62 @@
}
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
Index: devs/flash/atmel/dataflash/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/atmel/dataflash/current/Attic/ChangeLog,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 ChangeLog
--- devs/flash/atmel/dataflash/current/ChangeLog 7 Oct 2004 19:59:27 -0000 1.1.2.3
+++ devs/flash/atmel/dataflash/current/ChangeLog 20 Nov 2004 23:04:20 -0000
@@ -1,3 +1,8 @@
+2004-11-20 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/devs_flash_atmel_dataflash.cdl: data flash requires indirect
+ read support in the main flash code.
+
2004-10-07 Savin Zlobec <savin@elatec.si>
* include/dataflash.h:
Index: devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/atmel/dataflash/current/cdl/Attic/devs_flash_atmel_dataflash.cdl,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 devs_flash_atmel_dataflash.cdl
--- devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl 7 Oct 2004 19:59:28 -0000 1.1.2.3
+++ devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl 20 Nov 2004 23:04:20 -0000
@@ -62,6 +62,7 @@
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."
Index: devs/flash/toshiba/tc58xxx/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/toshiba/tc58xxx/current/ChangeLog,v
retrieving revision 1.3.2.1
diff -u -r1.3.2.1 ChangeLog
--- devs/flash/toshiba/tc58xxx/current/ChangeLog 5 Aug 2004 13:38:21 -0000 1.3.2.1
+++ devs/flash/toshiba/tc58xxx/current/ChangeLog 20 Nov 2004 23:04:22 -0000
@@ -1,3 +1,8 @@
+2004-11-20 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/flash_toshiba_tc58xxx.cdl: NAND flash requires indirect read
+ support in the main flash code
+
2004-08-03 Andrew Lunn <andrew.lunn@ascom.ch>
* cdl/flash_toshiba_tc58xxx.cdl: Indicate we need the legacy device API
Index: devs/flash/toshiba/tc58xxx/current/cdl/flash_toshiba_tc58xxx.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/toshiba/tc58xxx/current/cdl/flash_toshiba_tc58xxx.cdl,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 flash_toshiba_tc58xxx.cdl
--- devs/flash/toshiba/tc58xxx/current/cdl/flash_toshiba_tc58xxx.cdl 5 Aug 2004 13:38:21 -0000 1.1.2.1
+++ devs/flash/toshiba/tc58xxx/current/cdl/flash_toshiba_tc58xxx.cdl 20 Nov 2004 23:04:23 -0000
@@ -62,6 +62,7 @@
implements CYGHWR_IO_FLASH_DEVICE
implements CYGHWR_IO_FLASH_DEVICE_LEGACY
+ implements CYGHWR_IO_FLASH_INDIRECT_READS
include_dir cyg/io
}