changeset 3026:a9d12f1a0c5b

synth nand: implement CYGSEM_NAND_SYNTH_ALLOW_MULTIPLE_WRITES
author Ross Younger <wry@ecoscentric.com>
date Mon, 17 May 2010 17:04:23 +0100
parents 1bb791eebd38
children 56fc685b878c
files packages/devs/nand/synth/current/ChangeLog packages/devs/nand/synth/current/cdl/nand_synth.cdl packages/devs/nand/synth/current/src/nand_synth.c
diffstat 3 files changed, 33 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/packages/devs/nand/synth/current/ChangeLog
+++ b/packages/devs/nand/synth/current/ChangeLog
@@ -1,3 +1,9 @@
+2010-05-11  Ross Younger  <wry@ecoscentric.com>
+
+	* nand_synth.c, nand_synth.cdl: Allow simulation of multiple
+	writes to a page if CYGSEM_NAND_SYNTH_ALLOW_MULTIPLE_WRITES
+	is set.
+
 2009-11-13  Ross Younger  <wry@ecoscentric.com>
 
 	* Don't provide BBT data if it's not called for.
--- a/packages/devs/nand/synth/current/cdl/nand_synth.cdl
+++ b/packages/devs/nand/synth/current/cdl/nand_synth.cdl
@@ -156,6 +156,19 @@ cdl_package CYGPKG_DEVS_NAND_SYNTH {
 		description		"This option causes the synthetic NAND device to suffer frequent random bit flips, in order to confirm that they are handled properly (in conjunction with the eccdamage test)."
 	}
 
+	cdl_option CYGSEM_NAND_SYNTH_ALLOW_MULTIPLE_WRITES {
+		display			"Allow multiple writes without erasing"
+		flavor			bool
+		default_value	0
+		description		"Some NAND parts - mostly
+            small-page devices - allow pages to be programmed multiple
+            times without an intervening erase. This driver does
+            not normally allow such writes, but can be made to by
+            setting this option. Note that in this mode, this driver
+            follow the normal NAND semantics - i.e. that a programming
+            operation can only clear a bit from 1 to 0."
+	}
+
 	# Partition table support
 
 	# Every NAND board driver has to decide how it will determine the
--- a/packages/devs/nand/synth/current/src/nand_synth.c
+++ b/packages/devs/nand/synth/current/src/nand_synth.c
@@ -1600,6 +1600,9 @@ synth_writebegin(cyg_nand_device *dev, c
     // Do we make it bad this time?
     if (0 == result) _page_going_bad = write_check_injections(page);
 
+#if CYGSEM_NAND_SYNTH_ALLOW_MULTIPLE_WRITES == 1
+    (void) i;
+#else
     // Do not allow multiple writes to a single page, for now.
     if (0 == result) {
         for (i = 0; i < PAGESIZE; i++) {
@@ -1611,6 +1614,7 @@ synth_writebegin(cyg_nand_device *dev, c
             }
         }
     }
+#endif
 
     if (0 == result) {
         counter                     = CYG_BE32_TO_CPU(image_write_counts[page]);
@@ -1643,7 +1647,12 @@ synth_writestride(cyg_nand_device *dev, 
     }
 
     if (src && (size > 0)) {
+#if CYGSEM_NAND_SYNTH_ALLOW_MULTIPLE_WRITES == 1
+        for (i=0; i<size; i++)
+            image_data[_offset + _stridden + i] &= ((unsigned char*)src)[i];
+#else
         memcpy(&(image_data[_offset + _stridden]), src, size);
+#endif
         if (_page_going_bad) {
             // Fake it so that most of the write has succeeded, but one byte
             // is stuck at 0xFF. That means looking for a byte in src that
@@ -1695,7 +1704,12 @@ synth_writefinish(cyg_nand_device *dev, 
 
     if (0 == result) {
         if (spare && (spare_size > 0)) {
+#if CYGSEM_NAND_SYNTH_ALLOW_MULTIPLE_WRITES == 1
+            for (i=0; i<spare_size; i++)
+                image_data[_offset + PAGESIZE + i] &= ((unsigned char*)spare)[i];
+#else
             memcpy(&(image_data[_offset + PAGESIZE]), spare, spare_size);
+#endif
             if (_page_going_bad) {
                 idx = rand() % spare_size;
                 for (i = 0; i < spare_size; i++) {