This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]