Flash infrastructure rework

Andrew Lunn andrew@lunn.ch
Tue Sep 14 16:09:00 GMT 2004


> 2) cyg_flash_erase/program/read loops have their condition set
> to addr <= end_addr, many flash drivers calculate flash end address
> as CYGNUM_FLASH_BASE+ (flash_dev_info->device_size * CYGNUM_FLASH_SERIES).
> If the end address is not in the flash then erase/program/read ops
> beyond the flash space can result in endless loops (the lower layer funs are
> actually called with length = 0).

I decided that the end address should be the last valid address of the
flash, not the first invalid address. Attached (if i remember) is a
patch which makes all the v2 device drivers consistenly set this
correctly. Also the legacy driver interface now correctly sets the end
address. I also added code which checks the end address against the
block info when asserts are enabled.

This will require a minor change to your dataFlash driver. Would you
like me to commit the dataflash driver to the flash_v2 tree?

        Andrew
-------------- next part --------------
Index: devs/flash/intel/stratav2/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/intel/stratav2/current/Attic/ChangeLog,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 ChangeLog
--- devs/flash/intel/stratav2/current/ChangeLog	21 Aug 2004 08:48:17 -0000	1.1.2.3
+++ devs/flash/intel/stratav2/current/ChangeLog	14 Sep 2004 15:57:02 -0000
@@ -1,3 +1,9 @@
+2004-09-14  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* include/flash_strata_v2.inl: Return the end address which is the
+	last valid address, not the first invalid address.
+	Also import Mark Salters changes from the trunk.
+	
 2004-08-21  Andrew Lunn  <andrew.lunn@ascom.ch>
 	
 	* include/flash_strata_v2.inl (flash_unlock_block): 
Index: devs/flash/intel/stratav2/current/include/flash_strata_v2.inl
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/intel/stratav2/current/include/Attic/flash_strata_v2.inl,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 flash_strata_v2.inl
--- devs/flash/intel/stratav2/current/include/flash_strata_v2.inl	21 Aug 2004 08:48:17 -0000	1.1.2.3
+++ devs/flash/intel/stratav2/current/include/flash_strata_v2.inl	14 Sep 2004 15:57:03 -0000
@@ -70,6 +70,17 @@
 extern int strncmp(const char *s1, const char *s2, size_t len);
 extern void *memcpy( void *, const void *, size_t );
 
+// Platforms may define these for special handling when accessing the
+// query data or write buffer .
+#ifndef CYGHWR_FLASH_READ_QUERY 
+#define CYGHWR_FLASH_READ_QUERY(a) (*(a)) 
+#endif
+#ifndef CYGHWR_FLASH_WRITE_BUF
+#define CYGHWR_FLASH_WRITE_BUF(a,b) (*(a) = *(b))
+#endif
+
+
+
 //----------------------------------------------------------------------------
 // Functions that put the flash device into non-read mode must reside
 // in RAM.
@@ -158,7 +169,7 @@
 #endif // Not CYGOPT_FLASH_IS_BOOTBLOCK
         
         dev->end = dev->start +
-          (num_regions*region_size*CYGNUM_FLASH_INTERLEAVE);
+          (num_regions*region_size*CYGNUM_FLASH_INTERLEAVE) -1;
         priv->buffer_size = buffer_size;
         priv->block_info[0].blocks = num_regions;
         priv->block_info[0].block_size = region_size * CYGNUM_FLASH_INTERLEAVE;
@@ -241,10 +252,10 @@
 #endif // Not CYGOPT_FLASH_IS_BOOTBLOCK
 
     for (cnt = CNT;  cnt > 0;  cnt--) ;
-    for ( /* i */;  i > 0;  i-- ) {
+    for ( /* i */;  i > 0;  i--, ++ROM ) {
         // It is very deliberate that data is chars NOT flash_t:
         // The info comes out in bytes regardless of device.
-        *data++ = (unsigned char) (*ROM++);
+        *data++ = (unsigned char) CYGHWR_FLASH_READ_QUERY(ROM);
 #ifndef CYGOPT_FLASH_IS_BOOTBLOCK
 # if  8 == CYGNUM_FLASH_WIDTH
 	// strata flash with 'byte-enable' contains the configuration data
@@ -366,7 +377,7 @@
 #ifdef CYGHWR_FLASH_WRITE_ELEM
             CYGHWR_FLASH_WRITE_ELEM(addr+i, data+i);
 #else
-            *(addr+i) = *(data+i);
+            CYGHWR_FLASH_WRITE_BUF(addr+i, data+i);
 #endif
         }
         *BA = FLASH_Confirm;
Index: devs/flash/sst/39vfxxx/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/sst/39vfxxx/current/ChangeLog,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 ChangeLog
--- devs/flash/sst/39vfxxx/current/ChangeLog	6 Aug 2004 13:11:33 -0000	1.1.2.2
+++ devs/flash/sst/39vfxxx/current/ChangeLog	14 Sep 2004 15:57:04 -0000
@@ -1,3 +1,8 @@
+2004-09-14  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* include/flash_sst_39vfxxx.inl: Set the end address to the last
+	valid address in flash, not the first invalid address.
+
 2004-08-06  Andrew Lunn  <andrew.lunn@ascom.ch>
 
 	* include/flash_sst_39vfxxx.inl: The structure declared by
Index: devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 flash_sst_39vfxxx.inl
--- devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl	6 Aug 2004 13:11:34 -0000	1.1.2.2
+++ devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl	14 Sep 2004 15:57:04 -0000
@@ -64,7 +64,6 @@
 #define  _FLASH_PRIVATE_
 #include <cyg/io/flash.h>
 
-
 //----------------------------------------------------------------------------
 // Common device details.
 #define FLASH_Read_ID                   FLASHWORD( 0x90 )
@@ -170,7 +169,7 @@
   
   // Hard wired for now
   dev->end = dev->start + 
-    (FLASH_NUM_REGIONS * FLASH_BLOCK_SIZE * CYGNUM_FLASH_SERIES);
+    (FLASH_NUM_REGIONS * FLASH_BLOCK_SIZE * CYGNUM_FLASH_SERIES) -1;
   dev->num_block_infos = 1;
   priv->block_info[0].blocks = FLASH_NUM_REGIONS * CYGNUM_FLASH_SERIES;
   priv->block_info[0].block_size = FLASH_BLOCK_SIZE;
@@ -266,7 +265,6 @@
             }
             prev_state = state;
         }
-
         // Verify loaded data bytes
         while (len > 0) {
             if (*addr_ptr != FLASH_BlankValue) {
@@ -278,7 +276,6 @@
             len -= sizeof(*addr_ptr);
         }
     }
-
     return CYG_FLASH_ERR_OK;
 }
 
Index: devs/flash/synthv2/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/synthv2/current/Attic/ChangeLog,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 ChangeLog
--- devs/flash/synthv2/current/ChangeLog	9 Sep 2004 13:13:22 -0000	1.1.2.3
+++ devs/flash/synthv2/current/ChangeLog	14 Sep 2004 15:57:04 -0000
@@ -1,3 +1,8 @@
+2004-09-14  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* src/synth.c (synth_flash_erase_block): Remove asserts which are
+	no longer true.
+
 2004-09-09  Andrew Lunn  <andrew.lunn@ascom.ch>
 
 	* src/flash_synth.c: Allow the use of arbitary sized block.
Index: devs/flash/synthv2/current/src/synth.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/synthv2/current/src/Attic/synth.c,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 synth.c
--- devs/flash/synthv2/current/src/synth.c	9 Sep 2004 13:13:23 -0000	1.1.2.2
+++ devs/flash/synthv2/current/src/synth.c	14 Sep 2004 15:57:04 -0000
@@ -207,9 +207,6 @@
 synth_flash_erase_block(struct cyg_flash_dev *dev, 
                         const cyg_flashaddr_t block_base)
 {
-#ifdef CYGDBG_USE_ASSERTS
-    struct cyg_flash_synth_config *config = dev->config;
-#endif
     struct cyg_flash_synth_priv *priv = dev->priv;
     int offset = (int)block_base;
     size_t remaining;
@@ -225,11 +222,6 @@
         empty_inited = true;
     }
 
-    CYG_ASSERT(sizeof(empty) < config->block_size,
-               "Eckk! Can't work with such small blocks");
-    CYG_ASSERT(config->boot_blocks && sizeof(empty) < config->boot_block_size,
-               "Eckk! Can't work with such small blocks");
-    
     remaining = flash_block_size(dev, block_base);
 
     while (remaining) {
Index: io/flash/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/flash/current/ChangeLog,v
retrieving revision 1.38.2.7
diff -u -r1.38.2.7 ChangeLog
--- io/flash/current/ChangeLog	9 Sep 2004 13:11:46 -0000	1.38.2.7
+++ io/flash/current/ChangeLog	14 Sep 2004 15:59:38 -0000
@@ -1,3 +1,10 @@
+2004-09-14  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* src/flash.c (cyg_flash_init): Add assert checking that the
+	end address matches the block information.
+	* src/legacy_dev.c (legacy_flash_init): Ensure that the end
+	address is the last valid address, not the first invalid address.
+
 2004-09-09  Andrew Lunn  <andrew.lunn@ascom.ch>
 
 	* src/flash.c: Support flash blocks of arbitary size. The
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.4
diff -u -r1.26.2.4 flash.c
--- io/flash/current/src/flash.c	9 Sep 2004 13:11:47 -0000	1.26.2.4
+++ io/flash/current/src/flash.c	14 Sep 2004 15:59:39 -0000
@@ -170,7 +170,16 @@
     CYG_ASSERT(dev->funs->flash_erase_block, "No erase function");
     CYG_ASSERT(dev->funs->flash_program, "No program function");
     CYG_ASSERT(dev->funs->flash_hwr_map_error, "No hwr map error function");
-
+#ifdef CYGDBG_USE_ASSERTS
+    {
+         int i; 
+         cyg_flashaddr_t addr = dev->start;
+         for (i = 0; i < dev->num_block_infos; i++) {
+              addr += dev->block_info[i].block_size * dev->block_info[i].blocks;
+         }
+         CYG_ASSERT(dev->end == addr-1, "Invalid end address");
+    }
+#endif
     dev->init = true;
     dev->next = flash_head;
     flash_head = dev;
Index: io/flash/current/src/legacy_dev.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/flash/current/src/Attic/legacy_dev.c,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 legacy_dev.c
--- io/flash/current/src/legacy_dev.c	5 Aug 2004 13:50:02 -0000	1.1.2.1
+++ io/flash/current/src/legacy_dev.c	14 Sep 2004 15:59:40 -0000
@@ -92,7 +92,7 @@
 
   if (!err) {
     dev->start = (cyg_flashaddr_t)flash_info.start;
-    dev->end = (cyg_flashaddr_t)flash_info.end;
+    dev->end = flash_info.block_size * flash_info.blocks - 1; 
     dev->num_block_infos = 1;
     dev->block_info = block_info;
     block_info[0].block_size = flash_info.block_size;


More information about the Ecos-patches mailing list