This is the mail archive of the ecos-patches@sourceware.org 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]

[flashv2 merge] Everything else


Little bits around the place. ecos.db, doclist, etc. Attached.

Jifl
-- 
eCosCentric Limited      http://www.eCosCentric.com/     The eCos experts
Barnwell House, Barnwell Drive, Cambridge, UK.       Tel: +44 1223 245571
Registered in England and Wales: Reg No 4422071.
------["Si fractum non sit, noli id reficere"]------       Opinions==mine
Index: doc/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/doc/ChangeLog,v
retrieving revision 1.34
diff -u -5 -p -r1.34 ChangeLog
--- doc/ChangeLog	8 Oct 2008 14:48:14 -0000	1.34
+++ doc/ChangeLog	18 Nov 2008 01:26:49 -0000
@@ -1,5 +1,10 @@
+2008-11-17  Jonathan Larmour  <jifl@eCosCentric.com>
+
+	* sgml/doclist: Add AMD AM29XXXXX and Intel StrataFlash v2 flash
+	driver documentation.
+
 2008-10-08  Bart Veer  <bartv@ecoscentric.com>
 
 	* sgml/doclist: added generic framebuffer and synthetic target
 	framebuffer driver documentation.
 
Index: doc/sgml/doclist
===================================================================
RCS file: /cvs/ecos/ecos/doc/sgml/doclist,v
retrieving revision 1.24
diff -u -5 -p -r1.24 doclist
--- doc/sgml/doclist	8 Oct 2008 14:48:14 -0000	1.24
+++ doc/sgml/doclist	18 Nov 2008 01:26:49 -0000
@@ -46,5 +46,7 @@ devs/usb/nec_upd985xx/current/doc/usbs_u
 devs/eth/synth/ecosynth/current/doc/syntheth.sgml
 devs/watchdog/synth/current/doc/synth_watchdog.sgml
 devs/wallclock/dallas/ds1307/current/doc/ds1307.sgml
 devs/disk/generic/mmc/current/doc/disk_mmc.sgml
 devs/framebuf/synth/current/doc/synth_framebuf.sgml
+devs/flash/amd/am29xxxxxv2/current/doc/am29xxxxx.sgml
+devs/flash/intel/stratav2/current/doc/strata.sgml
Index: packages/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/ChangeLog,v
retrieving revision 1.196
diff -u -5 -p -r1.196 ChangeLog
--- packages/ChangeLog	11 Nov 2008 17:56:03 -0000	1.196
+++ packages/ChangeLog	18 Nov 2008 01:26:50 -0000
@@ -1,5 +1,26 @@
+2008-11-16  Jonathan Larmour  <jifl@eCosCentric.com>
+
+	* ecos.db: Use v2 drivers for adder/adderII and IXDP425.
+
+2008-11-16  Jonathan Larmour  <jifl@eCosCentric.com>
+
+	* ecos.db: Merge flash_v2 branch to trunk including these changes:
+
+ 2004-11-20  Bart Veer  <bartv@ecoscentric.com>
+
+	* ecos.db: Add new AM29xxxxxx driver which supports the V2 API
+
+ 2004-08-06  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* ecos.db: Added the new strata driver which uses the V2 API.
+
+ 2004-08-05  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* ecos.db: Added the new synthetic target flash device which uses
+	the new API and has some extra goodies like boot blocks.
+
 2008-11-11  Nick Garnett  <nickg@ecoscentric.com>
 
 	* ecos.db: Add STM32 wallclock driver.
 
 2008-11-11  John Dallaway  <jld@ecoscentric.com>
Index: packages/NEWS
===================================================================
RCS file: /cvs/ecos/ecos/packages/NEWS,v
retrieving revision 1.116
diff -u -5 -p -r1.116 NEWS
--- packages/NEWS	4 Nov 2008 16:22:46 -0000	1.116
+++ packages/NEWS	18 Nov 2008 01:26:50 -0000
@@ -1,5 +1,7 @@
+* Intel Strataflash v2 flash driver contributed by eCosCentric Ltd.
+* New Flash API with lots of new goodies.
 * ADC device driver for EA2468 OEM board
 * ADC device driver for LP24XXX devices.
 * Cortex-M Architecture HAL contributed by eCosCentric Ltd.
 * STM32 Variant HAL, STM3210E platform HAL, serial device driver,
   on-chip flash driver contributed by eCosCentric Ltd.
Index: packages/ecos.db
===================================================================
RCS file: /cvs/ecos/ecos/packages/ecos.db,v
retrieving revision 1.182
diff -u -5 -p -r1.182 ecos.db
--- packages/ecos.db	11 Nov 2008 17:56:03 -0000	1.182
+++ packages/ecos.db	18 Nov 2008 01:26:51 -0000
@@ -207,19 +207,29 @@ package CYGPKG_DEVS_FLASH_ARM_AAED2000 {
            This package contains hardware support for flash memory
 	   on the Agilent AAED2000 platform."
 }
 
 package CYGPKG_DEVS_FLASH_AMD_AM29XXXXX {
-	alias 		{ "Support for AMD AM29xxxxx flash memory" flash_amd_am29xxxxx }
+	alias 		{ "Support for AMD AM29xxxxx flash memory (deprecated)" flash_amd_am29xxxxx }
 	directory	devs/flash/amd/am29xxxxx
 	script		flash_amd_am29xxxxx.cdl
 	hardware
         description "
            This package contains hardware support for AMD AM29xxxxx
            flash memory devices."
 }
 
+package CYGPKG_DEVS_FLASH_AMD_AM29XXXXX_V2 {
+	alias 		{ "Support for AMD AM29xxxxx flash memory" flash_amd_am29xxxxx_v2 }
+	directory	devs/flash/amd/am29xxxxxv2
+	script		flash_am29xxxxx_v2.cdl
+	hardware
+        description "
+           This package contains hardware support for AMD AM29xxxxx
+           flash memory devices."
+}
+
 package CYGPKG_DEVS_FLASH_ATMEL_AT29CXXXX {
 	alias 		{ "Support for Atmel AT29Cxxxx flash memory" flash_atmel_at29cxxxx }
 	directory	devs/flash/atmel/at29cxxxx
 	script		flash_atmel_at29cxxxx.cdl
 	hardware
@@ -587,19 +597,29 @@ package CYGPKG_DEVS_FLASH_NANO {
            This package contains hardware support for FLASH memory
 	   on the StrongARM SA-1110 nanoEngine platform."
 }
 
 package CYGPKG_DEVS_FLASH_STRATA {
-	alias 		{ "Generic FLASH memory support for Intel StrataFLASH" strata }
+	alias 		{ "Generic FLASH memory support for Intel StrataFLASH (deprecated)" strata }
 	directory	devs/flash/intel/strata
 	script		flash_strata.cdl
 	hardware
         description "
            This package contains generic hardware support for Intel
 	   StrataFLASH memory devices."
 }
 
+package CYGPKG_DEVS_FLASH_STRATA_V2 {
+	alias 		{ "Generic FLASH memory support for Intel StrataFLASH" strata_v2 }
+	directory	devs/flash/intel/stratav2
+	script		flash_strata_v2.cdl
+	hardware
+        description "
+           This package contains generic hardware support for Intel
+	   StrataFLASH memory devices using the V2 device API."
+}
+
 package CYGPKG_DEVS_FLASH_SST_39VFXXX {
     alias       { "Support for SST 39VFXXX flash memory" flash_sst_39vfXXX }
     directory   devs/flash/sst/39vfxxx
     script      flash_sst_39vfxxx.cdl
     hardware
@@ -797,18 +817,27 @@ package CYGPKG_DEVS_FLASH_ATLAS {
         description "
            This package contains hardware support for FLASH memory
 	   on the MIPS Atlas platform."
 }
 package CYGPKG_DEVS_FLASH_SYNTH {
-    alias               { "Synthetic FLASH memory support" synth_flash flash_synth }
+    alias               { "Synthetic FLASH memory support (legacy)" synth_flash flash_synth }
     directory           devs/flash/synth
     script              flash_synth.cdl
     hardware
     description   "
         FLASH memory device support for Synthetic target"
 }
 
+package CYGPKG_DEVS_FLASH_SYNTH_V2 {
+    alias               { "Synthetic FLASH memory support" synth_flashv2 flash_synthv2 }
+    directory           devs/flash/synthv2
+    script              flash_synth.cdl
+    hardware
+    description   "
+        FLASH memory device support for Synthetic target using the new API"
+}
+
 package CYGPKG_DEVS_FLASH_TOSHIBA_TC58XXX {
 	alias 		{ "Support for Toshiba TC58xxx flash memory" flash_toshiba_tc58xxx }
 	directory	devs/flash/toshiba/tc58xxx
 	script		flash_toshiba_tc58xxx.cdl
 	hardware
@@ -4700,10 +4729,11 @@ target eb55 {
 	packages { CYGPKG_HAL_ARM
                    CYGPKG_HAL_ARM_AT91
                    CYGPKG_HAL_ARM_AT91_EB55
                    CYGPKG_DEVS_FLASH_EB55
                    CYGPKG_DEVS_FLASH_ATMEL_AT49XXXX
+                   CYGPKG_DEVS_FLASH_ATMEL_DATAFLASH
                    CYGPKG_IO_SERIAL_ARM_AT91
                    CYGPKG_DEVS_SPI_ARM_EB55
                    CYGPKG_DEVS_SPI_ARM_AT91
                    CYGPKG_DEVICES_WATCHDOG_ARM_AT91
         }
@@ -5135,12 +5165,11 @@ target ixdp425 {
 	           CYGPKG_HAL_ARM_XSCALE_IXP425
                    CYGPKG_HAL_ARM_XSCALE_IXDP425
 		   CYGPKG_IO_PCI
                    CYGPKG_DEVS_ETH_INTEL_I82559
 		   CYGPKG_DEVS_ETH_ARM_IXDP425_I82559
-                   CYGPKG_DEVS_FLASH_STRATA
-		   CYGPKG_DEVS_FLASH_IXDP425
+                   CYGPKG_DEVS_FLASH_STRATA_V2
         }
         description "
         The ixdp425 target provides the packages needed to run
         eCos on an Intel network processor evaluation board."
 }
@@ -6328,12 +6357,11 @@ target adder {
         alias		{ "A&M Adder PPC850 board" adder850 }
 	packages        { CYGPKG_HAL_POWERPC
                           CYGPKG_HAL_POWERPC_MPC8xx
                           CYGPKG_HAL_POWERPC_ADDER
                           CYGPKG_HAL_QUICC 
-                          CYGPKG_DEVS_FLASH_POWERPC_ADDER
-                          CYGPKG_DEVS_FLASH_AMD_AM29XXXXX
+                          CYGPKG_DEVS_FLASH_AMD_AM29XXXXX_V2
                           CYGPKG_DEVS_ETH_POWERPC_QUICC
                           CYGPKG_DEVS_ETH_POWERPC_ADDER
                           CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC
         }
         enable { CYGHWR_HAL_POWERPC_ADDER_I }
@@ -6346,12 +6374,11 @@ target adderII {
         alias		{ "A&M Adder PPC852T board" adder852T }
 	packages        { CYGPKG_HAL_POWERPC
                           CYGPKG_HAL_POWERPC_MPC8xx
                           CYGPKG_HAL_POWERPC_ADDER
                           CYGPKG_HAL_QUICC 
-                          CYGPKG_DEVS_FLASH_POWERPC_ADDER
-                          CYGPKG_DEVS_FLASH_AMD_AM29XXXXX
+                          CYGPKG_DEVS_FLASH_AMD_AM29XXXXX_V2
                           CYGPKG_DEVS_ETH_POWERPC_FEC
                           CYGPKG_DEVS_ETH_POWERPC_ADDERII
                           CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC
         }
         enable { CYGHWR_HAL_POWERPC_ADDER_II }
Index: packages/fs/jffs2/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/ChangeLog,v
retrieving revision 1.52
diff -u -5 -p -r1.52 ChangeLog
--- packages/fs/jffs2/current/ChangeLog	1 May 2008 09:35:19 -0000	1.52
+++ packages/fs/jffs2/current/ChangeLog	18 Nov 2008 01:26:54 -0000
@@ -1,5 +1,23 @@
+2008-11-18  Jonathan Larmour  <jifl@eCosCentric.com>
+
+	* tests/jffs2_1.c, tests/jffs2_2.c, tests/jffs2_3.c: 
+	Select device name to use according to configury, including flash
+	API in use.
+
+2008-06-09  Jonathan Larmour  <jifl@eCosCentric.com>
+
+	* cdl/jffs2.cdl (CYGPKG_FS_JFFS2_CFLAGS_ADD): Conditionalise use of
+	workaround for building with native linux tools so that it only
+	applies when using synth target. Otherwise it can cause problems
+	with some other third-party builds of the toolchain.
+
+2004-07-14  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* tests/fileio1.c (main): If we have two filesystem configured
+	mount the second one on /mnt and list the root of it.
+
 2008-04-02  Xinghua Yang <yxinghua@sunnorth.com.cn>
             Taiyun  Wang <taiyun@sunnorth.com.cn>
             Andrew Lunn <andrew.lunn@ascom.ch>
 
 	* cdl/jffs2.cdl: Use CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE to control
@@ -92,10 +110,15 @@
 2004-08-12  Andrew Lunn <andrew.lunn@ascom.ch>
 	    Gary Thomas <gary@mlbassoc.com>
 
 	* Merge from public MTD.
 	
+2004-07-10  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* src/flashio.c (jffs2_flash_erase): Minor update for new
+	flash API.
+
 2004-04-19  Oyvind Harboe <oyvind.harboe@zylin.com>
 	
 	* src/build.c: JFFS2 can now be used as a write-once, read many mode
 	for really small flash disks, e.g. configuration parameters.
 	
Index: packages/fs/jffs2/current/cdl/jffs2.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/cdl/jffs2.cdl,v
retrieving revision 1.24
diff -u -5 -p -r1.24 jffs2.cdl
--- packages/fs/jffs2/current/cdl/jffs2.cdl	1 May 2008 09:35:19 -0000	1.24
+++ packages/fs/jffs2/current/cdl/jffs2.cdl	18 Nov 2008 01:26:54 -0000
@@ -232,11 +232,12 @@ cdl_package CYGPKG_FS_JFFS2 {
 	flavor  data
 	no_define
 	# We add '-D__ECOS' to trigger eCos-specific code in places.
 	# We add '-nostdinc -iwithprefix include' to avoid picking up
 	#    native <linux/*.h> include files when building on Linux.
-	default_value { "-D__ECOS -nostdinc -iwithprefix include" }
+	default_value { "-D__ECOS " . \
+            (CYGPKG_HAL_SYNTH ? " -nostdinc -iwithprefix include" : "") }
 	description   "
 	    This option modifies the set of compiler flags for
             building the JFFS2 package.
             These flags are used in addition
             to the set of global flags."
Index: packages/fs/jffs2/current/src/flashio.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/src/flashio.c,v
retrieving revision 1.2
diff -u -5 -p -r1.2 flashio.c
--- packages/fs/jffs2/current/src/flashio.c	30 Jul 2005 15:30:42 -0000	1.2
+++ packages/fs/jffs2/current/src/flashio.c	18 Nov 2008 01:26:54 -0000
@@ -142,11 +142,11 @@ jffs2_flash_direct_writev(struct jffs2_s
 
 cyg_bool jffs2_flash_erase(struct jffs2_sb_info * c,
 			   struct jffs2_eraseblock * jeb)
 {
 	cyg_io_flash_getconfig_erase_t e;
-	void *err_addr;
+	cyg_flashaddr_t err_addr;
 	Cyg_ErrNo err;
 	cyg_uint32 len = sizeof (e);
 	struct super_block *sb = OFNI_BS_2SFFJ(c);
 
 	e.offset = jeb->offset;
Index: packages/fs/jffs2/current/tests/jffs2_1.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/tests/jffs2_1.c,v
retrieving revision 1.6
diff -u -5 -p -r1.6 jffs2_1.c
--- packages/fs/jffs2/current/tests/jffs2_1.c	1 May 2008 09:35:19 -0000	1.6
+++ packages/fs/jffs2/current/tests/jffs2_1.c	18 Nov 2008 01:26:54 -0000
@@ -59,10 +59,11 @@
 //==========================================================================
 
 #include <pkgconf/hal.h>
 #include <pkgconf/kernel.h>
 #include <pkgconf/io_fileio.h>
+#include <pkgconf/io_flash.h>
 
 #include <cyg/kernel/ktypes.h>         // base kernel types
 #include <cyg/infra/cyg_trac.h>        // tracing macros
 #include <cyg/infra/cyg_ass.h>         // assertion macros
 #include <cyg/io/flash.h>
@@ -72,19 +73,36 @@
 #include <sys/stat.h>
 #include <errno.h>
 #include <string.h>
 #include <dirent.h>
 #include <stdio.h>
+#include <stdlib.h>
 
 #include <cyg/fileio/fileio.h>
 
 #include <cyg/infra/testcase.h>
 #include <cyg/infra/diag.h>            // HAL polled output
 
 #include <pkgconf/fs_jffs2.h>	// Address of JFFS2
 
 //==========================================================================
+// Mount details
+
+#define stringify2(_x_) #_x_
+#define stringify(_x_) stringify2(_x_)
+
+#if defined(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1)
+# define JFFS2_TEST_DEV CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
+#elif defined(CYGFUN_IO_FLASH_BLOCK_FROM_FIS)
+# define JFFS2_TEST_DEV "/dev/flash/fis/jffs2test"
+#else
+// fall back to using a user set area in the first device (only)
+# define JFFS2_TEST_DEV "/dev/flash/0/" stringify(CYGNUM_FS_JFFS2_TEST_OFFSET) "," stringify(CYGNUM_FS_JFFS2_TEST_LENGTH)
+#endif
+
+// we could use an mtab but we don't in order to get better diagnostics
+// by calling mount() directly.
 
 #if 0
 MTAB_ENTRY( jffs2_mte1,
                    "/",
                    "jffs2",
@@ -426,15 +444,21 @@ int main( int argc, char **argv )
 {
     int err;
     //int i;
     int existingdirents=-1;
 
+    struct mallinfo info;
+
+    info =  mallinfo();
+    diag_printf("arenasize %d, freeblocks %d, totalallocated %d, totalfree %d, maxfree %d\n",
+                info.arena, info.ordblks, info.uordblks, info.fordblks, info.maxfree);
+
     CYG_TEST_INIT();
 
     // --------------------------------------------------------------
 
-    err = mount( CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1, "/", "jffs2" );
+    err = mount( JFFS2_TEST_DEV, "/", "jffs2" );
     if( err < 0 ) SHOW_RESULT( mount, err );    
 
     err = chdir( "/" );
     if( err < 0 ) SHOW_RESULT( chdir, err );
 
@@ -521,11 +545,11 @@ int main( int argc, char **argv )
     listdir( "/", false, existingdirents, NULL );
 
     // --------------------------------------------------------------
 
     diag_printf("<INFO>: mount /jffs2 \n");
-    err = mount( CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1, "/jffs2", "jffs2" );
+    err = mount( JFFS2_TEST_DEV, "/jffs2", "jffs2" );
     if( err < 0 ) SHOW_RESULT( mount, err );    
 
     createfile( "/jffs2/tinky", 456 );
     copyfile( "/jffs2/tinky", "/jffs2/laalaa" );
     checkfile( "/jffs2/tinky");
@@ -668,10 +692,33 @@ int main( int argc, char **argv )
     
     diag_printf("<INFO>: umount /jffs2\n");    
     err = umount( "/jffs2" );
     if( err < 0 ) SHOW_RESULT( umount, err );    
     
+#ifdef CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_2
+    diag_printf("<INFO>: mounting second JFFS2 filesystem on /mnt\n");
+    
+    err = mount( CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_2, "/mnt", "jffs2" );
+    if( err < 0 ) SHOW_RESULT( mount, err );    
+
+    err = chdir( "/" );
+    if( err < 0 ) SHOW_RESULT( chdir, err );
+
+    checkcwd( "/" );
+    
+    listdir( "/", true, -1, &existingdirents );
+    if ( existingdirents < 2 )
+        CYG_TEST_FAIL("Not enough dir entries\n");
+
+    listdir( "/mnt", true, -1, &existingdirents );
+    if ( existingdirents < 2 )
+        CYG_TEST_FAIL("Not enough dir entries\n");
+
+    diag_printf("<INFO>: umount /mnt\n");    
+    err = umount( "/mnt" );
+#endif
+
     diag_printf("<INFO>: umount /\n");    
     err = umount( "/" );
     if( err < 0 ) SHOW_RESULT( umount, err );    
     
     CYG_TEST_PASS_FINISH("jffs2_1");
Index: packages/fs/jffs2/current/tests/jffs2_2.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/tests/jffs2_2.c,v
retrieving revision 1.4
diff -u -5 -p -r1.4 jffs2_2.c
--- packages/fs/jffs2/current/tests/jffs2_2.c	27 Mar 2005 18:21:37 -0000	1.4
+++ packages/fs/jffs2/current/tests/jffs2_2.c	18 Nov 2008 01:26:54 -0000
@@ -55,10 +55,12 @@
 //              
 //
 //####DESCRIPTIONEND####
 //
 //==========================================================================
+
+#include <pkgconf/io_flash.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <string.h>
@@ -66,10 +68,28 @@
 #include <cyg/fileio/fileio.h>
 #include <cyg/io/flash.h>
 
 #include <cyg/infra/testcase.h>
 #include <cyg/infra/diag.h>            // HAL polled output
+
+#include <pkgconf/fs_jffs2.h>	// Address of JFFS2
+
+//==========================================================================
+// Mount details
+
+#define stringify2(_x_) #_x_
+#define stringify(_x_) stringify2(_x_)
+
+#if defined(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1)
+# define JFFS2_TEST_DEV CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
+#elif defined(CYGFUN_IO_FLASH_BLOCK_FROM_FIS)
+# define JFFS2_TEST_DEV "/dev/flash/fis/jffs2test"
+#else
+// fall back to using a user set area in the first device (only)
+# define JFFS2_TEST_DEV "/dev/flash/0/" stringify(CYGNUM_FS_JFFS2_TEST_OFFSET) "," stringify(CYGNUM_FS_JFFS2_TEST_LENGTH)
+#endif
+
 //==========================================================================
 
 #define SHOW_RESULT( _fn, _res ) \
 diag_printf("FAIL: " #_fn "() returned %ld %s\n", \
            (unsigned long)_res, _res<0?strerror(errno):"");
@@ -92,11 +112,11 @@ int main( int argc, char **argv )
     CYG_TEST_INIT();
 
     // --------------------------------------------------------------
 
     CYG_TEST_INFO("mount /");    
-    err = mount( CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1, "/", "jffs2" );
+    err = mount( JFFS2_TEST_DEV, "/", "jffs2" );
 
     if( err < 0 ) SHOW_RESULT( mount, err );    
     
     CYG_TEST_INFO("creating /fseek");    
     stream = fopen("/fseek","w+");
Index: packages/fs/jffs2/current/tests/jffs2_3.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/tests/jffs2_3.c,v
retrieving revision 1.3
diff -u -5 -p -r1.3 jffs2_3.c
--- packages/fs/jffs2/current/tests/jffs2_3.c	30 Jul 2005 15:30:42 -0000	1.3
+++ packages/fs/jffs2/current/tests/jffs2_3.c	18 Nov 2008 01:26:54 -0000
@@ -46,10 +46,12 @@
 //                      to test the garbage collection code.
 //                      
 //####DESCRIPTIONEND####
 //
 //==========================================================================
+
+#include <pkgconf/io_flash.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <string.h>
@@ -60,10 +62,26 @@
 #include <cyg/crc/crc.h>
 
 #include <cyg/infra/testcase.h>
 #include <cyg/infra/diag.h>            // HAL polled output
 
+#include <pkgconf/fs_jffs2.h>	// Address of JFFS2
+
+//==========================================================================
+
+#define stringify2(_x_) #_x_
+#define stringify(_x_) stringify2(_x_)
+
+#if defined(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1)
+# define JFFS2_TEST_DEV CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
+#elif defined(CYGFUN_IO_FLASH_BLOCK_FROM_FIS)
+# define JFFS2_TEST_DEV "/dev/flash/fis/jffs2test"
+#else
+// fall back to using a user set area in the first device (only)
+# define JFFS2_TEST_DEV "/dev/flash/0/" stringify(CYGNUM_FS_JFFS2_TEST_OFFSET) "," stringify(CYGNUM_FS_JFFS2_TEST_LENGTH)
+#endif
+
 //==========================================================================
 
 #define ITERATIONS 1000000
 #define NELEM(_x_) (sizeof(_x_)/sizeof(*(_x_)))
 
@@ -149,11 +167,11 @@ int main( int argc, char **argv )
     CYG_TEST_INIT();
 
     // --------------------------------------------------------------
 
     CYG_TEST_INFO("mount /");    
-    err = mount( CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1, "/", "jffs2" );
+    err = mount( JFFS2_TEST_DEV, "/", "jffs2" );
     if( err < 0 ) SHOW_RESULT( mount, err );    
     
     chdir ("/");
     
     iteration=0;
Index: packages/hal/arm/xscale/ixdp425/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/xscale/ixdp425/current/ChangeLog,v
retrieving revision 1.13
diff -u -5 -p -r1.13 ChangeLog
--- packages/hal/arm/xscale/ixdp425/current/ChangeLog	2 Mar 2006 01:02:36 -0000	1.13
+++ packages/hal/arm/xscale/ixdp425/current/ChangeLog	18 Nov 2008 01:26:55 -0000
@@ -1,9 +1,26 @@
+2006-08-02  Jonathan Larmour  <jifl@eCosCentric.com>
+
+	* src/ixdp425_strataflash.c: In CYG_FLASH_FUNS, replace query
+        function with generic nop version.
+        Remove hwr_map_error: it no longer exists for CYG_FLASH_FUNS.
+
 2006-03-01  Mark Salter  <msalter@sadr.localdomain>
 
 	* include/hal_platform_setup.h: Fix DELAY macro.
 
+2006-01-31  Jonathan Larmour  <jifl@eCosCentric.com>
+
+	* cdl/hal_arm_xscale_ixdp425.cdl
+	(CYGHWR_HAL_ARM_XSCALE_IXDP425_FLASH): New option to support
+	v2 Flash driver.
+	* src/ixdp425_strataflash.c: New v2 flash driver.
+	* include/hal_platform_setup.h: Add uncached Flash mapping.
+	* include/ixdp425.h: Add uncached flash mappings.
+	* include/plf_io.h: Provide CYGARC_UNCACHED_ADDRESS.
+	* misc/redboot*.ecm: Use Strata V2 Flash driver.
+
 2004-09-27  Mark Salter  <msalter@redhat.com>
 
 	* misc/redboot_ROMRAM.ecm: Remove CYGHWR_HAL_IXP425_PCI_NP_WORKAROUND.
 	* misc/redboot_ROMRAMLE.ecm: Ditto.
 
Index: packages/hal/arm/xscale/ixdp425/current/cdl/hal_arm_xscale_ixdp425.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/xscale/ixdp425/current/cdl/hal_arm_xscale_ixdp425.cdl,v
retrieving revision 1.7
diff -u -5 -p -r1.7 hal_arm_xscale_ixdp425.cdl
--- packages/hal/arm/xscale/ixdp425/current/cdl/hal_arm_xscale_ixdp425.cdl	20 Sep 2004 19:35:49 -0000	1.7
+++ packages/hal/arm/xscale/ixdp425/current/cdl/hal_arm_xscale_ixdp425.cdl	18 Nov 2008 01:26:55 -0000
@@ -89,10 +89,25 @@ cdl_package CYGPKG_HAL_ARM_XSCALE_IXDP42
            debug software such as RedBoot or eCos GDB stubs. Select 'romram'
            when building a stand-alone application which will be put
            into ROM, but execute from RAM."
     }
 
+    cdl_option CYGHWR_HAL_ARM_XSCALE_IXDP425_FLASH {
+        display         "External Intel StrataFLASH memory support"
+        parent          CYGPKG_IO_FLASH
+        active_if       CYGPKG_IO_FLASH
+        flavor          bool
+        default_value   1
+        no_define
+        implements      CYGHWR_IO_FLASH_BLOCK_LOCKING
+        compile         -library=libextras.a ixdp425_strataflash.c
+        description "
+            The IXDP425 development board is fitted with an external Intel
+            StrataFLASH 28F128J3 FLASH memory device. This option enables
+            support for the StrataFlash."
+    }
+
     cdl_component CYGBLD_GLOBAL_OPTIONS {
         display "Global build options"
         flavor  none
         no_define
         description   "
Index: packages/hal/arm/xscale/ixdp425/current/include/hal_platform_setup.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/xscale/ixdp425/current/include/hal_platform_setup.h,v
retrieving revision 1.5
diff -u -5 -p -r1.5 hal_platform_setup.h
--- packages/hal/arm/xscale/ixdp425/current/include/hal_platform_setup.h	2 Mar 2006 01:02:36 -0000	1.5
+++ packages/hal/arm/xscale/ixdp425/current/include/hal_platform_setup.h	18 Nov 2008 01:26:55 -0000
@@ -303,10 +303,11 @@ icache_boundary:
 	IXP_MAP_EXP 2, IXDP425_LED_SIZE,      0, 0, 0, 0   // LED
 	IXP_MAP_EXP 4, (1 << 20),             0, 0, 0, 0   // NPE use
 	IXP_MAP_EXP 5, (1 << 20),             0, 0, 0, 0   // NPE use
 
 	IXP_MAP_EXP_V 0, IXDP_FLASH_DC_BASE, IXDP_FLASH_SIZE, 1, 0, 0, 1  // data coherent flash
+        IXP_MAP_EXP_V 0, IXDP_FLASH_UNCACHED_BASE, IXDP_FLASH_SIZE, 0, 0, 0, 0  // uncached flash
 
 	IXP_MAP_IO      IXP425_PCI_WINDOW_BASE,  IXP425_PCI_WINDOW_SIZE
 	IXP_MAP_IO      IXP425_QMGR_BASE,        IXP425_QMGR_SIZE
 	IXP_MAP_IO	IXP425_PCI_CFG_BASE,     IXP425_PCI_CFG_SIZE
 	IXP_MAP_IO	IXP425_EXP_CFG_BASE,     IXP425_EXP_CFG_SIZE
Index: packages/hal/arm/xscale/ixdp425/current/include/ixdp425.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/xscale/ixdp425/current/include/ixdp425.h,v
retrieving revision 1.3
diff -u -5 -p -r1.3 ixdp425.h
--- packages/hal/arm/xscale/ixdp425/current/include/ixdp425.h	2 Sep 2004 20:17:45 -0000	1.3
+++ packages/hal/arm/xscale/ixdp425/current/include/ixdp425.h	18 Nov 2008 01:26:55 -0000
@@ -72,10 +72,11 @@
 #define IXDP425_LED_DATA                   REG16(0, IXDP425_LED_BASE)
 
 #define IXDP_FLASH_BASE                    0x50000000
 #define IXDP_FLASH_SIZE                    0x01000000
 #define IXDP_FLASH_DC_BASE                 0xA0000000
+#define IXDP_FLASH_UNCACHED_BASE           0xB0000000
 
 // CS0 (flash optimum timing)
 #define IXP425_EXP_CS0_INIT \
  (EXP_ADDR_T(3) | EXP_SETUP_T(3) | EXP_STROBE_T(15) | EXP_HOLD_T(3) | \
   EXP_RECOVERY_T(15) | EXP_SZ_16M | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN)
Index: packages/hal/arm/xscale/ixdp425/current/include/plf_io.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/xscale/ixdp425/current/include/plf_io.h,v
retrieving revision 1.1
diff -u -5 -p -r1.1 plf_io.h
--- packages/hal/arm/xscale/ixdp425/current/include/plf_io.h	18 Mar 2003 13:10:03 -0000	1.1
+++ packages/hal/arm/xscale/ixdp425/current/include/plf_io.h	18 Nov 2008 01:26:55 -0000
@@ -53,12 +53,20 @@
 //####DESCRIPTIONEND####
 //
 //=============================================================================
 
 #include <pkgconf/hal.h>
-#include <cyg/hal/hal_io.h>             // IO macros
 #include <cyg/hal/ixdp425.h>
 #include CYGBLD_HAL_PLF_INTS_H
 
+// Override IXP425 variant CYGARC_UNCACHED_ADDRESS definition
+#define CYGARC_UNCACHED_ADDRESS(x)                                       \
+    ((((cyg_uint32)(x)) < 0x10000000) ? (((cyg_uint32)(x))+0x20000000) : \
+     ((((cyg_uint32)(x)) >= IXDP_FLASH_BASE) && (((cyg_uint32)(x)) < (IXDP_FLASH_BASE+IXDP_FLASH_SIZE))) ? \
+     ((x)+(IXDP_FLASH_UNCACHED_BASE-IXDP_FLASH_BASE)) :                  \
+     (x))
+
+#include <cyg/hal/hal_io.h>             // IO macros
+
 //-----------------------------------------------------------------------------
 // end of plf_io.h
 #endif // CYGONCE_PLF_IO_H
Index: packages/hal/arm/xscale/ixdp425/current/misc/redboot_RAM.ecm
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/xscale/ixdp425/current/misc/redboot_RAM.ecm,v
retrieving revision 1.5
diff -u -5 -p -r1.5 redboot_RAM.ecm
--- packages/hal/arm/xscale/ixdp425/current/misc/redboot_RAM.ecm	19 Sep 2004 17:49:59 -0000	1.5
+++ packages/hal/arm/xscale/ixdp425/current/misc/redboot_RAM.ecm	18 Nov 2008 01:26:55 -0000
@@ -13,12 +13,11 @@ cdl_configuration eCos {
     template    redboot ;
     package -hardware CYGPKG_HAL_ARM current ;
     package -hardware CYGPKG_HAL_ARM_XSCALE_CORE current ;
     package -hardware CYGPKG_HAL_ARM_XSCALE_IXP425 current ;
     package -hardware CYGPKG_HAL_ARM_XSCALE_IXDP425 current ;
-    package -hardware CYGPKG_DEVS_FLASH_STRATA current ;
-    package -hardware CYGPKG_DEVS_FLASH_IXDP425 current ;
+    package -hardware CYGPKG_DEVS_FLASH_STRATA_V2 current ;
     package -hardware CYGPKG_DEVS_ETH_INTEL_I82559 current ;
     package -hardware CYGPKG_DEVS_ETH_ARM_IXDP425_I82559 current ;
     package -template CYGPKG_HAL current ;
     package -template CYGPKG_INFRA current ;
     package -template CYGPKG_REDBOOT current ;
Index: packages/hal/arm/xscale/ixdp425/current/misc/redboot_RAMLE.ecm
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/xscale/ixdp425/current/misc/redboot_RAMLE.ecm,v
retrieving revision 1.3
diff -u -5 -p -r1.3 redboot_RAMLE.ecm
--- packages/hal/arm/xscale/ixdp425/current/misc/redboot_RAMLE.ecm	19 Sep 2004 17:49:59 -0000	1.3
+++ packages/hal/arm/xscale/ixdp425/current/misc/redboot_RAMLE.ecm	18 Nov 2008 01:26:55 -0000
@@ -13,12 +13,11 @@ cdl_configuration eCos {
     template    redboot ;
     package -hardware CYGPKG_HAL_ARM current ;
     package -hardware CYGPKG_HAL_ARM_XSCALE_CORE current ;
     package -hardware CYGPKG_HAL_ARM_XSCALE_IXP425 current ;
     package -hardware CYGPKG_HAL_ARM_XSCALE_IXDP425 current ;
-    package -hardware CYGPKG_DEVS_FLASH_STRATA current ;
-    package -hardware CYGPKG_DEVS_FLASH_IXDP425 current ;
+    package -hardware CYGPKG_DEVS_FLASH_STRATA_V2 current ;
     package -hardware CYGPKG_DEVS_ETH_INTEL_I82559 current ;
     package -hardware CYGPKG_DEVS_ETH_ARM_IXDP425_I82559 current ;
     package -template CYGPKG_HAL current ;
     package -template CYGPKG_INFRA current ;
     package -template CYGPKG_REDBOOT current ;
Index: packages/hal/arm/xscale/ixdp425/current/misc/redboot_ROM.ecm
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/xscale/ixdp425/current/misc/redboot_ROM.ecm,v
retrieving revision 1.5
diff -u -5 -p -r1.5 redboot_ROM.ecm
--- packages/hal/arm/xscale/ixdp425/current/misc/redboot_ROM.ecm	19 Sep 2004 17:49:59 -0000	1.5
+++ packages/hal/arm/xscale/ixdp425/current/misc/redboot_ROM.ecm	18 Nov 2008 01:26:55 -0000
@@ -13,12 +13,11 @@ cdl_configuration eCos {
     template    redboot ;
     package -hardware CYGPKG_HAL_ARM current ;
     package -hardware CYGPKG_HAL_ARM_XSCALE_CORE current ;
     package -hardware CYGPKG_HAL_ARM_XSCALE_IXP425 current ;
     package -hardware CYGPKG_HAL_ARM_XSCALE_IXDP425 current ;
-    package -hardware CYGPKG_DEVS_FLASH_STRATA current ;
-    package -hardware CYGPKG_DEVS_FLASH_IXDP425 current ;
+    package -hardware CYGPKG_DEVS_FLASH_STRATA_V2 current ;
     package -hardware CYGPKG_DEVS_ETH_INTEL_I82559 current ;
     package -hardware CYGPKG_DEVS_ETH_ARM_IXDP425_I82559 current ;
     package -template CYGPKG_HAL current ;
     package -template CYGPKG_INFRA current ;
     package -template CYGPKG_REDBOOT current ;
Index: packages/hal/arm/xscale/ixdp425/current/misc/redboot_ROMLE.ecm
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/xscale/ixdp425/current/misc/redboot_ROMLE.ecm,v
retrieving revision 1.3
diff -u -5 -p -r1.3 redboot_ROMLE.ecm
--- packages/hal/arm/xscale/ixdp425/current/misc/redboot_ROMLE.ecm	19 Sep 2004 17:49:59 -0000	1.3
+++ packages/hal/arm/xscale/ixdp425/current/misc/redboot_ROMLE.ecm	18 Nov 2008 01:26:55 -0000
@@ -13,12 +13,11 @@ cdl_configuration eCos {
     template    redboot ;
     package -hardware CYGPKG_HAL_ARM current ;
     package -hardware CYGPKG_HAL_ARM_XSCALE_CORE current ;
     package -hardware CYGPKG_HAL_ARM_XSCALE_IXP425 current ;
     package -hardware CYGPKG_HAL_ARM_XSCALE_IXDP425 current ;
-    package -hardware CYGPKG_DEVS_FLASH_STRATA current ;
-    package -hardware CYGPKG_DEVS_FLASH_IXDP425 current ;
+    package -hardware CYGPKG_DEVS_FLASH_STRATA_V2 current ;
     package -hardware CYGPKG_DEVS_ETH_INTEL_I82559 current ;
     package -hardware CYGPKG_DEVS_ETH_ARM_IXDP425_I82559 current ;
     package -template CYGPKG_HAL current ;
     package -template CYGPKG_INFRA current ;
     package -template CYGPKG_REDBOOT current ;
Index: packages/hal/arm/xscale/ixdp425/current/misc/redboot_ROMRAM.ecm
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/xscale/ixdp425/current/misc/redboot_ROMRAM.ecm,v
retrieving revision 1.3
diff -u -5 -p -r1.3 redboot_ROMRAM.ecm
--- packages/hal/arm/xscale/ixdp425/current/misc/redboot_ROMRAM.ecm	27 Sep 2004 18:37:06 -0000	1.3
+++ packages/hal/arm/xscale/ixdp425/current/misc/redboot_ROMRAM.ecm	18 Nov 2008 01:26:55 -0000
@@ -13,12 +13,11 @@ cdl_configuration eCos {
     template    redboot ;
     package -hardware CYGPKG_HAL_ARM current ;
     package -hardware CYGPKG_HAL_ARM_XSCALE_CORE current ;
     package -hardware CYGPKG_HAL_ARM_XSCALE_IXP425 current ;
     package -hardware CYGPKG_HAL_ARM_XSCALE_IXDP425 current ;
-    package -hardware CYGPKG_DEVS_FLASH_STRATA current ;
-    package -hardware CYGPKG_DEVS_FLASH_IXDP425 current ;
+    package -hardware CYGPKG_DEVS_FLASH_STRATA_V2 current ;
     package -hardware CYGPKG_DEVS_ETH_INTEL_I82559 current ;
     package -hardware CYGPKG_DEVS_ETH_ARM_IXDP425_I82559 current ;
     package -template CYGPKG_HAL current ;
     package -template CYGPKG_INFRA current ;
     package -template CYGPKG_REDBOOT current ;
Index: packages/hal/arm/xscale/ixdp425/current/misc/redboot_ROMRAMLE.ecm
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/xscale/ixdp425/current/misc/redboot_ROMRAMLE.ecm,v
retrieving revision 1.3
diff -u -5 -p -r1.3 redboot_ROMRAMLE.ecm
--- packages/hal/arm/xscale/ixdp425/current/misc/redboot_ROMRAMLE.ecm	27 Sep 2004 18:37:06 -0000	1.3
+++ packages/hal/arm/xscale/ixdp425/current/misc/redboot_ROMRAMLE.ecm	18 Nov 2008 01:26:55 -0000
@@ -13,12 +13,11 @@ cdl_configuration eCos {
     template    redboot ;
     package -hardware CYGPKG_HAL_ARM current ;
     package -hardware CYGPKG_HAL_ARM_XSCALE_CORE current ;
     package -hardware CYGPKG_HAL_ARM_XSCALE_IXP425 current ;
     package -hardware CYGPKG_HAL_ARM_XSCALE_IXDP425 current ;
-    package -hardware CYGPKG_DEVS_FLASH_STRATA current ;
-    package -hardware CYGPKG_DEVS_FLASH_IXDP425 current ;
+    package -hardware CYGPKG_DEVS_FLASH_STRATA_V2 current ;
     package -hardware CYGPKG_DEVS_ETH_INTEL_I82559 current ;
     package -hardware CYGPKG_DEVS_ETH_ARM_IXDP425_I82559 current ;
     package -template CYGPKG_HAL current ;
     package -template CYGPKG_INFRA current ;
     package -template CYGPKG_REDBOOT current ;
Index: packages/hal/arm/xscale/ixdp425/current/src/ixdp425_strataflash.c
===================================================================
RCS file: packages/hal/arm/xscale/ixdp425/current/src/ixdp425_strataflash.c
diff -N packages/hal/arm/xscale/ixdp425/current/src/ixdp425_strataflash.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ packages/hal/arm/xscale/ixdp425/current/src/ixdp425_strataflash.c	18 Nov 2008 01:26:55 -0000
@@ -0,0 +1,96 @@
+//==========================================================================
+//
+//      ixdp425_strataflash.c
+//
+//      Support for the Strata flash device on Intel IXDP425
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005, 2006 eCosCentric Limited
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   jlarmour based on original by bartv
+// Date:        2006-01-17
+//
+//####DESCRIPTIONEND####
+//=============================================================================
+
+// There is a single Intel StrataFLASH device on the IXDP425, supported via the
+// generic Strata flash package. By default this is the 28F128J3 which is a
+// 16MByte device, arranged as 128*128K blocks with no boot blocks, 16-bits
+// wide. There is a 32-byte program buffer and locking is supported.
+//
+// But CFI is used to determine Flash geometry as the part is fitted in a socket
+// to allow replacement with other StrataFLASH parts.
+
+#include <pkgconf/system.h>
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+#include <cyg/io/strata_dev.h>
+#include <cyg/hal/plf_io.h>
+
+static const CYG_FLASH_FUNS(hal_ixdp425_flash_strata_funs,
+                            &cyg_strata_init_cfi_16,
+                            &cyg_flash_devfn_query_nop,
+                            &cyg_strata_erase_16,
+                            &cyg_strata_bufprogram_16,
+                            (int (*)(struct cyg_flash_dev*, const cyg_flashaddr_t, void*, size_t))0,
+                            &cyg_strata_lock_j3_16,
+                            &cyg_strata_unlock_j3_16);
+
+static cyg_strata_dev hal_ixdp425_flash_priv;
+#ifdef notusingcfianymore
+ = {
+    .manufacturer_code  = 0x0089,
+    .device_code        = 0x0018,
+    .bufsize            = 16,       // 32 bytes -> 16 words
+    .block_info = {
+        { 0x00020000, 128 }
+    }
+};
+#endif
+
+// The Flash driver initially claims to use the cached mapping of the Flash
+// device, but through CYGARC_UNCACHED_ADDRESS, will actually use the *uncached*
+// mapping when it comes to driver operations. That way things like
+// RedBoot's FIS directory still correctly use the cached flash addresses.
+
+CYG_FLASH_DRIVER(hal_ixdp425_flash,
+                 &hal_ixdp425_flash_strata_funs,
+                 0,
+                 IXDP_FLASH_BASE,
+                 (IXDP_FLASH_BASE+IXDP_FLASH_SIZE-1),
+                 1,
+                 hal_ixdp425_flash_priv.block_info,
+                 &hal_ixdp425_flash_priv
+);
+
+// EOF ixdp425_strataflash.c
Index: packages/hal/powerpc/adder/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/powerpc/adder/current/ChangeLog,v
retrieving revision 1.19
diff -u -5 -p -r1.19 ChangeLog
--- packages/hal/powerpc/adder/current/ChangeLog	11 Nov 2008 04:29:07 -0000	1.19
+++ packages/hal/powerpc/adder/current/ChangeLog	18 Nov 2008 01:26:56 -0000
@@ -1,5 +1,22 @@
+2008-11-13  Jonathan Larmour  <jifl@eCosCentric.com>
+
+	* src/adder_flash.c: Dev id is really 0x22f6, not 0xf6.
+
+2006-08-02  Jonathan Larmour  <jifl@eCosCentric.com>
+
+	* src/adder_flash.c: In CYG_FLASH_FUNS, replace query, lock and unlock
+        functions with generic nop versions.
+        Remove hwr_map_error: it no longer exists for CYG_FLASH_FUNS.
+	Replace use of cyg/io/flash_priv.h with cyg/io/flash_dev.h as per
+	io/flash changes.
+
+2005-08-18  Jonathan Larmour  <jifl@eCosCentric.com>
+
+	* cdl/hal_powerpc_adder.cdl: Indicate to the AMD flash driver
+        that Flash accesses are cached.
+
 2005-03-27  Andrew Lunn  <andrew.lunn@ascom.ch>
 
 	* src/hal_aux.c: Added prototype of _adder_set_led() to remove
 	compiler warning
 	
@@ -11,10 +28,16 @@
 	* include/pkgconf/mlt_powerpc_adder_ram.ldi: Allow up to 0x60000 to be used
 	by ROM.
 	* include/pkgconf/mlt_powerpc_adder_ram.h
 	(CYGMEM_SECTION_reserved_for_rom_SIZE): Ditto.
 
+2004-11-25  Bart Veer  <bartv@ecoscentric.com>
+
+	* cdl/hal_powerpc_adder.cdl, misc/adder_redboot_ROMRAM.ecm,
+	misc/adderII_redboot_ROMRAM.ecm, src/adder_flash.c:
+	Switch to V2 flash
+
 2004-11-04  John Dallaway  <jld@ecoscentric.com>
 
 	* cdl/hal_powerpc_adder.cdl: Remove "-fvtable-gc" and "-finit-priority"
 	from the set of default compilation flags.
 
Index: packages/hal/powerpc/adder/current/cdl/hal_powerpc_adder.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/powerpc/adder/current/cdl/hal_powerpc_adder.cdl,v
retrieving revision 1.12
diff -u -5 -p -r1.12 hal_powerpc_adder.cdl
--- packages/hal/powerpc/adder/current/cdl/hal_powerpc_adder.cdl	11 Nov 2008 04:29:07 -0000	1.12
+++ packages/hal/powerpc/adder/current/cdl/hal_powerpc_adder.cdl	18 Nov 2008 01:26:56 -0000
@@ -59,10 +59,13 @@ cdl_package CYGPKG_HAL_POWERPC_ADDER {
     description   "
         The ADDER HAL package provides the support needed to run
         eCos on a A&M ADDER board equipped with a PowerPC processor."
 
     compile       hal_diag.c hal_aux.c adder.S
+    requires      { CYGPKG_IO_FLASH implies CYGPKG_DEVS_FLASH_AMD_AM29XXXXX_V2 }
+    implements    CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_CACHED_ONLY
+    compile       -library=libextras.a adder_flash.c
 
     implements    CYGINT_HAL_DEBUG_GDB_STUBS
     implements    CYGINT_HAL_DEBUG_GDB_STUBS_BREAK
     implements    CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT
 
Index: packages/hal/powerpc/adder/current/misc/adderII_redboot_ROMRAM.ecm
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/powerpc/adder/current/misc/adderII_redboot_ROMRAM.ecm,v
retrieving revision 1.3
diff -u -5 -p -r1.3 adderII_redboot_ROMRAM.ecm
--- packages/hal/powerpc/adder/current/misc/adderII_redboot_ROMRAM.ecm	11 Nov 2008 04:29:07 -0000	1.3
+++ packages/hal/powerpc/adder/current/misc/adderII_redboot_ROMRAM.ecm	18 Nov 2008 01:26:56 -0000
@@ -13,12 +13,11 @@ cdl_configuration eCos {
     template    redboot ;
     package -hardware CYGPKG_HAL_POWERPC current ;
     package -hardware CYGPKG_HAL_POWERPC_MPC8xx current ;
     package -hardware CYGPKG_HAL_POWERPC_ADDER current ;
     package -hardware CYGPKG_HAL_QUICC current ;
-    package -hardware CYGPKG_DEVS_FLASH_POWERPC_ADDER current ;
-    package -hardware CYGPKG_DEVS_FLASH_AMD_AM29XXXXX current ;
+    package -hardware CYGPKG_DEVS_FLASH_AMD_AM29XXXXX_V2 current ;
     package -hardware CYGPKG_DEVS_ETH_POWERPC_FEC current ;
     package -hardware CYGPKG_DEVS_ETH_POWERPC_ADDERII current ;
     package -hardware CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC current ;
     package -template CYGPKG_HAL current ;
     package -template CYGPKG_INFRA current ;
@@ -27,10 +26,11 @@ cdl_configuration eCos {
     package -template CYGPKG_LIBC_STRING current ;
     package -template CYGPKG_CRC current ;
     package CYGPKG_NS_DNS current ;
     package CYGPKG_IO_FLASH current ;
     package CYGPKG_IO_ETH_DRIVERS current ;
+    package CYGPKG_COMPRESS_ZLIB current ;
 };
 
 cdl_option CYGFUN_LIBC_STRING_BSD_FUNCS {
     inferred_value 0
 };
@@ -109,10 +109,7 @@ cdl_option CYGBLD_ISO_DNS_HEADER {
 
 cdl_option CYGPKG_NS_DNS_BUILD {
     inferred_value 0
 };
 
-cdl_option CYGHWR_DEVS_FLASH_AMD_AM29LV320D {
-    inferred_value 1
-};
 
 
Index: packages/hal/powerpc/adder/current/misc/adder_redboot_ROMRAM.ecm
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/powerpc/adder/current/misc/adder_redboot_ROMRAM.ecm,v
retrieving revision 1.2
diff -u -5 -p -r1.2 adder_redboot_ROMRAM.ecm
--- packages/hal/powerpc/adder/current/misc/adder_redboot_ROMRAM.ecm	21 Sep 2003 12:27:57 -0000	1.2
+++ packages/hal/powerpc/adder/current/misc/adder_redboot_ROMRAM.ecm	18 Nov 2008 01:26:56 -0000
@@ -13,12 +13,11 @@ cdl_configuration eCos {
     template    redboot ;
     package -hardware CYGPKG_HAL_POWERPC current ;
     package -hardware CYGPKG_HAL_POWERPC_MPC8xx current ;
     package -hardware CYGPKG_HAL_POWERPC_ADDER current ;
     package -hardware CYGPKG_HAL_QUICC current ;
-    package -hardware CYGPKG_DEVS_FLASH_POWERPC_ADDER current ;
-    package -hardware CYGPKG_DEVS_FLASH_AMD_AM29XXXXX current ;
+    package -hardware CYGPKG_DEVS_FLASH_AMD_AM29XXXXX_V2 current ;
     package -hardware CYGPKG_DEVS_ETH_POWERPC_QUICC current ;
     package -hardware CYGPKG_DEVS_ETH_POWERPC_ADDER current ;
     package -hardware CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC current ;
     package -template CYGPKG_HAL current ;
     package -template CYGPKG_INFRA current ;
@@ -27,10 +26,11 @@ cdl_configuration eCos {
     package -template CYGPKG_LIBC_STRING current ;
     package -template CYGPKG_CRC current ;
     package CYGPKG_NS_DNS current ;
     package CYGPKG_IO_FLASH current ;
     package CYGPKG_IO_ETH_DRIVERS current ;
+    package CYGPKG_COMPRESS_ZLIB current ;
 };
 
 cdl_option CYGFUN_LIBC_STRING_BSD_FUNCS {
     inferred_value 0
 };
@@ -108,11 +108,5 @@ cdl_option CYGBLD_ISO_DNS_HEADER {
 };
 
 cdl_option CYGPKG_NS_DNS_BUILD {
     inferred_value 0
 };
-
-cdl_option CYGHWR_DEVS_FLASH_AMD_AM29LV320D {
-    inferred_value 1
-};
-
-
Index: packages/hal/powerpc/adder/current/src/adder_flash.c
===================================================================
RCS file: packages/hal/powerpc/adder/current/src/adder_flash.c
diff -N packages/hal/powerpc/adder/current/src/adder_flash.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ packages/hal/powerpc/adder/current/src/adder_flash.c	18 Nov 2008 01:26:56 -0000
@@ -0,0 +1,85 @@
+//==========================================================================
+//
+//      adder_flash.c
+//
+//      Support for the external AMD flash device on Adder boards
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004, 2006, 2008 eCosCentric Limited
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   bartv
+// Date:        2004-11-25
+//
+//####DESCRIPTIONEND####
+//=============================================================================
+
+// There is a single AMD AM29LV320D device. DevId 22F6, 4MB, 63*64K,
+// 8*8K.
+
+#include <pkgconf/system.h>
+#ifdef CYGPKG_IO_FLASH
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+#include <cyg/io/am29xxxxx_dev.h>
+
+static const CYG_FLASH_FUNS(hal_adder_flash_amd_funs,
+                            &cyg_am29xxxxx_init_cfi_16,
+                            &cyg_flash_devfn_query_nop,
+                            &cyg_am29xxxxx_erase_16,
+                            &cyg_am29xxxxx_program_16,
+                            (int (*)(struct cyg_flash_dev*, const cyg_flashaddr_t, void*, size_t))0,
+                            &cyg_flash_devfn_lock_nop,
+                            &cyg_flash_devfn_unlock_nop);
+
+static cyg_am29xxxxx_dev hal_adder_flash_priv = {
+    .devid      = 0x22F6,
+    .block_info = {
+        { 0, 0 },
+        { 0, 0 },
+        { 0, 0 },
+        { 0, 0 }
+    }
+};
+
+CYG_FLASH_DRIVER(hal_adder_flash,
+                 &hal_adder_flash_amd_funs,
+                 0,
+                 0xFE000000,
+                 0xFE3FFFFF,
+                 4,
+                 hal_adder_flash_priv.block_info,
+                 &hal_adder_flash_priv
+);
+#endif  // CYGPKG_IO_FLASH
+
+// EOF adder_flash.c
Index: packages/io/common/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/common/current/ChangeLog,v
retrieving revision 1.30
diff -u -5 -p -r1.30 ChangeLog
--- packages/io/common/current/ChangeLog	8 Aug 2008 10:55:45 -0000	1.30
+++ packages/io/common/current/ChangeLog	18 Nov 2008 01:26:56 -0000
@@ -5,10 +5,15 @@
 2007-08-13  Alexey Shusharin <mrfinch@mail.ru>
 
 	* include/config_keys.h: Added key set setting CAN callback
 	configuration.
 	
+2007-05-10  Jonathan Larmour  <jifl@eCosCentric.com>
+
+	* include/config_keys.h (CYG_IO_GET_CONFIG_FLASH_DEVADDR):
+	Add this new key.
+
 2006-09-21  Jonathan Larmour  <jifl@eCosCentric.com>
 
 	* include/config_keys.h: Merge from eCosCentric repository.
 	ChangeLogs incorporated in correct location below.
 
Index: packages/io/common/current/include/config_keys.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/common/current/include/config_keys.h,v
retrieving revision 1.16
diff -u -5 -p -r1.16 config_keys.h
--- packages/io/common/current/include/config_keys.h	8 Aug 2008 10:55:45 -0000	1.16
+++ packages/io/common/current/include/config_keys.h	18 Nov 2008 01:26:56 -0000
@@ -119,11 +119,13 @@
 #define CYG_IO_GET_CONFIG_FLASH_LOCK             0x602
 #define CYG_IO_GET_CONFIG_FLASH_UNLOCK           0x603
 #define CYG_IO_GET_CONFIG_FLASH_VERIFY           0x604
 #define CYG_IO_GET_CONFIG_FLASH_DEVSIZE          0x605
 #define CYG_IO_GET_CONFIG_FLASH_BLOCKSIZE        0x606
+#define CYG_IO_GET_CONFIG_FLASH_DEVADDR          0x607
 
+// Note the following is now deprecated. See generic flash package for the replacement.
 #define CYG_IO_SET_CONFIG_FLASH_FIS_NAME         0x680
 
 // ======== 0x700 DISK =======================================================
 // Get/Set configuration 'key' values for DISK I/O 
 
Index: packages/redboot/current/src/fconfig.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/src/fconfig.c,v
retrieving revision 1.14
diff -u -5 -p -r1.14 fconfig.c
--- packages/redboot/current/src/fconfig.c	11 Nov 2008 04:32:10 -0000	1.14
+++ packages/redboot/current/src/fconfig.c	18 Nov 2008 01:26:58 -0000
@@ -75,11 +75,11 @@ externC void read_eeprom(void *buf, int 
 externC bool cyg_plf_redboot_esa_validate(unsigned char *val);
 #endif
 
 #ifdef CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH
 externC int do_flash_init(void);
-externC int flash_read(void *flash_base, void *ram_base, int len, void **err_address);
+#include <cyg/io/flash.h>
 #endif
 
 // Round a quantity up
 #define _rup(n,s) ((((n)+(s-1))/s)*s)
 
@@ -89,23 +89,24 @@ externC int flash_read(void *flash_base,
 // normal "configuration" data items.
 struct _config *config, *backup_config;
 
 // Local data used by these routines
 #ifdef CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH
-extern void *flash_start, *flash_end;
-extern int flash_block_size, flash_num_blocks;
+extern cyg_flashaddr_t flash_start, flash_end;
+extern size_t flash_block_size;
+extern cyg_uint32 flash_num_blocks;
 extern int __flash_init;
 #ifdef CYGOPT_REDBOOT_FIS
 extern void *fis_work_block;
-extern void *fis_addr;
+extern cyg_flashaddr_t fis_addr;
 extern int fisdir_size;  // Size of FIS directory.
 #endif
 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG_READONLY_FALLBACK
 static struct _config  *readonly_config;
 #endif
-void *cfg_base;   // Location in Flash of config data
-int   cfg_size;   // Length of config data - rounded to Flash block size
+cyg_flashaddr_t cfg_base;    // Location in Flash of config data
+size_t  cfg_size;            // Length of config data - rounded to Flash block size
 #endif // FLASH MEDIA
 
 // Prototypes for local functions
 static char *flash_lookup_config(char *key);
 
@@ -773,17 +774,13 @@ flash_crc(struct _config *conf)
 // Write the in-memory copy of the configuration data to the flash device.
 //
 void
 flash_write_config(bool prompt)
 {
-#if defined(CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH) && !defined(CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG)
-# ifdef CYG_FLASH_ERR_OK // crude temporary hack to see if we're being used with flashv2
-    cyg_flashaddr_t err_addr;
-# else
-    void *err_addr;
-# endif
+#if defined(CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH)
 #if !defined(CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG)
+    cyg_flashaddr_t err_addr;
     int stat;
 #endif
 #endif
 
     config->len = sizeof(struct _config);
@@ -796,25 +793,27 @@ flash_write_config(bool prompt)
         fis_read_directory();
         fis_update_directory();
 #else 
 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
         // Insure [quietly] that the config page is unlocked before trying to update
-        flash_unlock((void *)cfg_base, cfg_size, (void **)&err_addr);
+        cyg_flash_unlock(cfg_base, cfg_size, &err_addr);
 #endif
-        if ((stat = flash_erase(cfg_base, cfg_size, (void **)&err_addr)) != 0) {
-            diag_printf("   initialization failed at %p: %s\n", err_addr, flash_errmsg(stat));
+        if ((stat = cyg_flash_erase(cfg_base, cfg_size, &err_addr)) != 0) {
+            diag_printf("   initialization failed at %p: %s\n", (void*)err_addr, 
+                        cyg_flash_errmsg(stat));
         } else {
             conf_endian_fixup(config);
-            if ((stat = FLASH_PROGRAM(cfg_base, config, sizeof(struct _config), (void **)&err_addr)) != 0) {
+            if ((stat = cyg_flash_program(cfg_base, (void *)config, sizeof(struct _config), 
+                                      &err_addr)) != 0) {
                 diag_printf("Error writing config data at %p: %s\n", 
-                            err_addr, flash_errmsg(stat));
+                            (void*)err_addr, cyg_flash_errmsg(stat));
             }
             conf_endian_fixup(config);
         }
 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
         // Insure [quietly] that the config data is locked after the update
-        flash_lock((void *)cfg_base, cfg_size, (void **)&err_addr);
+        cyg_flash_lock(cfg_base, cfg_size, &err_addr);
 #endif
 #endif // CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG
 #else  // CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH
         write_eeprom(config, sizeof(struct _config));  // into 'config'
 #endif
@@ -1125,11 +1124,11 @@ static void
 load_flash_config(void)
 {
     bool use_boot_script;
     unsigned char *cfg_temp = (unsigned char *)workspace_end;
 #ifdef CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH
-    void *err_addr;
+    cyg_flashaddr_t err_addr;
 #endif
 
     config_ok = false;
     script = NULL;
     cfg_temp -= sizeof(struct _config);  // Space for primary config data
@@ -1149,25 +1148,25 @@ load_flash_config(void)
                                   CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_SIZE)) {
         // Too bad this can't be checked at compile/build time
         diag_printf("Sorry, FLASH config exceeds available space in FIS directory\n");
         return;
     }
-    cfg_base = (void *)(((CYG_ADDRESS)fis_addr + fisdir_size) - cfg_size);
+    cfg_base = (((CYG_ADDRESS)fis_addr + fisdir_size) - cfg_size);
     fisdir_size -= cfg_size;
 #else
     cfg_size = (flash_block_size > sizeof(struct _config)) ? 
         sizeof(struct _config) : 
         _rup(sizeof(struct _config), flash_block_size);
     if (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK < 0) {
-        cfg_base = (void *)((CYG_ADDRESS)flash_end + 1 -
+        cfg_base = ((CYG_ADDRESS)flash_end + 1 -
            _rup(_rup((-CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*flash_block_size), cfg_size), flash_block_size));
     } else {
-        cfg_base = (void *)((CYG_ADDRESS)flash_start + 
+        cfg_base = ((CYG_ADDRESS)flash_start + 
            _rup(_rup((CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*flash_block_size), cfg_size), flash_block_size));
     }
 #endif
-    FLASH_READ(cfg_base, config, sizeof(struct _config), &err_addr);
+    cyg_flash_read(cfg_base, (void *)config, sizeof(struct _config), &err_addr);
     conf_endian_fixup(config);
 #else
     read_eeprom(config, sizeof(struct _config));  // into 'config'
 #endif
 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG_READONLY_FALLBACK
@@ -1179,10 +1178,11 @@ load_flash_config(void)
         diag_printf("Use 'fconfig -i' to [re]initialize database\n");
         config_init();
         return;
     }
     config_ok = true;
+    
     flash_get_config("boot_script", &use_boot_script, CONFIG_BOOL);
     if (use_boot_script) {
         flash_get_config("boot_script_data", &script, CONFIG_SCRIPT);
         flash_get_config("boot_script_timeout", &script_timeout, CONFIG_INT);
     }
Index: packages/redboot/current/src/flash.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/src/flash.c,v
retrieving revision 1.84
diff -u -5 -p -r1.84 flash.c
--- packages/redboot/current/src/flash.c	28 Aug 2007 10:59:52 -0000	1.84
+++ packages/redboot/current/src/flash.c	18 Nov 2008 01:26:58 -0000
@@ -6,10 +6,11 @@
 //
 //==========================================================================
 //####ECOSGPLCOPYRIGHTBEGIN####
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004, 2005, 2006, 2007, 2008 eCosCentric Limited
 // Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
 // Copyright (C) 2003, 2004 Gary Thomas
 //
 // eCos is free software; you can redistribute it and/or modify it under
 // the terms of the GNU General Public License as published by the Free
@@ -31,13 +32,10 @@
 // License. However the source code for this file must still be made available
 // in accordance with section (3) of the GNU General Public License.
 //
 // This exception does not invalidate any other reasons why a work based on
 // this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
 // -------------------------------------------
 //####ECOSGPLCOPYRIGHTEND####
 //==========================================================================
 //#####DESCRIPTIONBEGIN####
 //
@@ -162,23 +160,24 @@ RedBoot_nested_cmd("fis", 
             do_fis,
             __FIS_cmds_TAB__, &__FIS_cmds_TAB_END__
     );
 
 // Local data used by these routines
-void *flash_start, *flash_end;
-int flash_block_size, flash_num_blocks;
+cyg_flashaddr_t flash_start, flash_end;
+size_t flash_block_size;
+cyg_uint32 flash_num_blocks;
 #ifdef CYGOPT_REDBOOT_FIS
 void *fis_work_block;
-void *fis_addr;
+cyg_flashaddr_t fis_addr;
 #ifdef CYGOPT_REDBOOT_REDUNDANT_FIS
 void *redundant_fis_addr;
 #endif
 int fisdir_size;  // Size of FIS directory.
 #endif
 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
-extern void *cfg_base;   // Location in Flash of config data
-extern int   cfg_size;   // Length of config data - rounded to Flash block size
+extern cyg_flashaddr_t cfg_base;   // Location in Flash of config data
+extern size_t cfg_size;            // Length of config data - rounded to Flash block size
 extern struct _config *config;
 #endif
 
 static void
 fis_usage(char *why)
@@ -188,12 +187,41 @@ fis_usage(char *why)
 }
 
 static void        
 _show_invalid_flash_address(CYG_ADDRESS flash_addr, int stat)
 {
-    diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat));
-    diag_printf("   valid range is %p-%p\n", (void *)flash_start, (void *)flash_end);
+    cyg_uint32 i=0;
+    cyg_flash_info_t info;
+    int ret;
+    
+    diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, 
+                cyg_flash_errmsg(stat));
+    do {
+      ret = cyg_flash_get_info(i, &info);
+      if (ret == CYG_FLASH_ERR_OK) {
+          diag_printf("   valid range is %p - %p\n", (void*)info.start, (void*)info.end);
+      }
+      i++;
+    } while (ret != CYG_FLASH_ERR_INVALID);
+}
+
+// Avoid overwriting the current executable. This is not a complete
+// implementation, there may be code outside the text region, but it
+// is generally good enough. If either the start of the text region or
+// the end of the text region is within the specified range then at
+// least some of the code is in the area of flash about to be erased
+// or programmed.
+static cyg_bool
+check_code_overlaps(cyg_flashaddr_t start, cyg_flashaddr_t end)
+{
+  extern char _stext[], _etext[];
+  
+  return ((((unsigned long)&_stext >= (unsigned long)start) &&
+           ((unsigned long)&_stext < (unsigned long)end))
+          ||
+          (((unsigned long)&_etext >= (unsigned long)start) &&
+           ((unsigned long)&_etext < (unsigned long)end)));
 }
 
 #ifdef CYGOPT_REDBOOT_FIS
 
 // fis_endian_fixup() is used to swap endianess if required.
@@ -218,13 +246,13 @@ static inline void fis_endian_fixup(void
 }
 
 void
 fis_read_directory(void)
 {
-    void *err_addr;
+    cyg_flashaddr_t err_addr;
 
-    FLASH_READ(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr);
+    cyg_flash_read(fis_addr, fis_work_block, fisdir_size, &err_addr);
     fis_endian_fixup(fis_work_block);
 }
 
 struct fis_image_desc *
 fis_lookup(char *name, int *num)
@@ -234,11 +262,11 @@ fis_lookup(char *name, int *num)
 
     fis_read_directory();
 
     img = (struct fis_image_desc *)fis_work_block;
     for (i = 0;  i < fisdir_size/sizeof(*img);  i++, img++) {
-        if ((img->u.name[0] != (unsigned char)0xFF) &&
+        if ((img->u.name[0] != '\xFF') &&
             (strcasecmp(name, img->u.name) == 0)) {
             if (num) *num = i;
             return img;
         }
     }
@@ -256,12 +284,13 @@ int fis_start_update_directory(int autol
    int do_autolock=autolock;
 #endif
 #endif
 
    struct fis_image_desc* img=NULL;
-   void* err_addr=NULL;
-   void* tmp_fis_addr=NULL;
+   cyg_flashaddr_t err_addr=NULL;
+   cyg_flashaddr_t tmp_fis_addr=NULL;
+   int stat;
 
    /*exchange old and new valid fis tables*/
    tmp_fis_addr=fis_addr;
    fis_addr=redundant_fis_addr;
    redundant_fis_addr=tmp_fis_addr;
@@ -275,17 +304,24 @@ int fis_start_update_directory(int autol
    img->u.valid_info.version_count=img->u.valid_info.version_count+1;
 
    //ready to go....
 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
    if (do_autolock)
-      flash_unlock((void *)fis_addr, fisdir_size, (void **)&err_addr);
+      cyg_flash_unlock(fis_addr, fisdir_size, &err_addr);
 #endif
 
-   flash_erase(fis_addr, fisdir_size, (void **)&err_addr);
+   if ((stat = cyg_flash_erase(fis_addr, fisdir_size, &err_addr)) != 0) {
+       diag_printf("Error erasing FIS directory at %p: %s\n", err_addr, cyg_flash_errmsg(stat));
+       return 1;
+   }
    //now magic is 0xffffffff
    fis_endian_fixup(fis_work_block);
-   flash_program(fis_addr, fis_work_block, flash_block_size, (void **)&err_addr);
+   if ((stat = cyg_flash_program(fis_addr, fis_work_block, flash_block_size, &err_addr)) != 0) {
+       diag_printf("Error writing FIS directory at %p: %s\n",
+                   err_addr, cyg_flash_errmsg(stat));
+       return 1;
+   }
    fis_endian_fixup(fis_work_block);
    //now magic is 0xff1234ff, valid is IN_PROGRESS, version_count is the old one +1
 
 #else
    /* nothing to do here without redundant fis */
@@ -295,11 +331,12 @@ int fis_start_update_directory(int autol
 }
 
 int
 fis_update_directory(int autolock, int error)
 {
-   void* err_addr=0;
+   cyg_flashaddr_t err_addr;
+   int stat;
 
 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
    // Ensure [quietly] that the directory is unlocked before trying to update and locked again afterwards
    int do_autolock=1;
@@ -332,45 +369,48 @@ fis_update_directory(int autolock, int e
       void* tmp_fis_addr=(void *)((CYG_ADDRESS)fis_addr+CYG_REDBOOT_RFIS_VALID_MAGIC_LENGTH);
 
       img->u.valid_info.valid_flag[0]=CYG_REDBOOT_RFIS_VALID;
       img->u.valid_info.valid_flag[1]=CYG_REDBOOT_RFIS_VALID;
 
-      flash_program(tmp_fis_addr, img->u.valid_info.valid_flag, sizeof(img->u.valid_info.valid_flag), (void **)&err_addr);
+      if ((stat = cyg_flash_program(tmp_fis_addr, img->u.valid_info.valid_flag,
+                                    sizeof(img->u.valid_info.valid_flag), &err_addr)) != 0) {
+          diag_printf("Error writing FIS directory at %p: %s\n", 
+                      err_addr, cyg_flash_errmsg(stat));
+      }
    }
 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
    if (do_autolock)
       flash_lock((void *)fis_addr, fisdir_size, (void **)&err_addr);
 #endif
 
 #else // CYGOPT_REDBOOT_REDUNDANT_FIS
     int blk_size = fisdir_size;
-    int stat;
 
     fis_endian_fixup(fis_work_block);
 #ifdef CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG
     memcpy((char *)fis_work_block+fisdir_size, config, cfg_size);
     conf_endian_fixup((char *)fis_work_block+fisdir_size);
     blk_size += cfg_size;
 #endif
 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
     if (do_autolock)
-        flash_unlock((void *)fis_addr, blk_size, (void **)&err_addr);
+        cyg_flash_unlock(fis_addr, blk_size, &err_addr);
 #endif
 
-    if ((stat = flash_erase(fis_addr, blk_size, (void **)&err_addr)) != 0) {
-        diag_printf("Error erasing FIS directory at %p: %s\n", err_addr, flash_errmsg(stat));
+    if ((stat = cyg_flash_erase(fis_addr, blk_size, &err_addr)) != 0) {
+        diag_printf("Error erasing FIS directory at %p: %s\n", (void*)err_addr, cyg_flash_errmsg(stat));
     } else {
-        if ((stat = FLASH_PROGRAM(fis_addr, fis_work_block,
-                                  blk_size, (void **)&err_addr)) != 0) {
+        if ((stat = cyg_flash_program(fis_addr, fis_work_block, blk_size,
+                                      &err_addr)) != 0) {
             diag_printf("Error writing FIS directory at %p: %s\n", 
-                        err_addr, flash_errmsg(stat));
+                        (void*)err_addr, cyg_flash_errmsg(stat));
         }
     }
     fis_endian_fixup(fis_work_block);
 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
     if (do_autolock)
-       flash_lock((void *)fis_addr, blk_size, (void **)&err_addr);
+        cyg_flash_lock(fis_addr, blk_size, &err_addr);
 #endif
 
 #endif // CYGOPT_REDBOOT_REDUNDANT_FIS
 
     return 0;
@@ -426,31 +466,31 @@ fis_erase_redundant_directory(void)
     void *err_addr;
 
 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
     // Ensure [quietly] that the directory is unlocked before trying
     // to update
-    flash_unlock((void *)redundant_fis_addr, fisdir_size,
-                 (void **)&err_addr);
+    cyg_flash_unlock(redundant_fis_addr, fisdir_size,
+                     &err_addr);
 #endif
-    if ((stat = flash_erase(redundant_fis_addr, fisdir_size,
-                            (void **)&err_addr)) != 0) {
+    if ((stat = cyg_flash_erase(redundant_fis_addr, fisdir_size,
+                                &err_addr)) != 0) {
          diag_printf("Error erasing FIS directory at %p: %s\n",
-                     err_addr, flash_errmsg(stat));
+                     err_addr, cyg_flash_errmsg(stat));
     }
 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
     // Ensure [quietly] that the directory is locked after the update
-    flash_lock((void *)redundant_fis_addr, fisdir_size, (void **)&err_addr);
+    cyg_flash_lock(redundant_fis_addr, fisdir_size, &err_addr);
 #endif
 }
 #endif
 
 static void
 fis_init(int argc, char *argv[])
 {
     int stat;
     struct fis_image_desc *img;
-    void *err_addr;
+    cyg_flashaddr_t err_addr;
     bool full_init = false;
     struct option_info opts[1];
     CYG_ADDRESS redboot_flash_start;
     unsigned long redboot_image_size;
 
@@ -470,11 +510,11 @@ fis_init(int argc, char *argv[])
 #define MIN_REDBOOT_IMAGE_SIZE CYGBLD_REDBOOT_MIN_IMAGE_SIZE
     redboot_image_size = flash_block_size > MIN_REDBOOT_IMAGE_SIZE ? 
                          flash_block_size : MIN_REDBOOT_IMAGE_SIZE;
 
     img = (struct fis_image_desc *)fis_work_block;
-    memset(img, 0xFF, fisdir_size);  // Start with erased data
+    memset(img, '\xFF', fisdir_size);  // Start with erased data
 
 #ifdef CYGOPT_REDBOOT_REDUNDANT_FIS
     //create the valid flag entry
     memset(img, 0, sizeof(struct fis_image_desc));
     strcpy(img->u.valid_info.magic_name, CYG_REDBOOT_RFIS_VALID_MAGIC);
@@ -489,19 +529,21 @@ fis_init(int argc, char *argv[])
     memset(img, 0, sizeof(*img));
     strcpy(img->u.name, "(reserved)");
     img->flash_base = (CYG_ADDRESS)flash_start;
     img->mem_base = (CYG_ADDRESS)flash_start;
     img->size = CYGNUM_REDBOOT_FLASH_RESERVED_BASE;
+    img->data_length = img->size;
     img++;
 #endif
     redboot_flash_start = (CYG_ADDRESS)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET;
 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT
     memset(img, 0, sizeof(*img));
     strcpy(img->u.name, "RedBoot");
     img->flash_base = redboot_flash_start;
     img->mem_base = redboot_flash_start;
     img->size = redboot_image_size;
+    img->data_length = img->size;
     img++;
     redboot_flash_start += redboot_image_size;
 #endif
 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_POST
 #ifdef CYGNUM_REDBOOT_FIS_REDBOOT_POST_OFFSET
@@ -511,38 +553,42 @@ fis_init(int argc, char *argv[])
     memset(img, 0, sizeof(*img));
     strcpy(img->u.name, "RedBoot[post]");
     img->flash_base = redboot_flash_start;
     img->mem_base = redboot_flash_start;
     img->size = redboot_image_size;
+    img->data_length = img->size;
     img++;
     redboot_flash_start += redboot_image_size;
 #endif
 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_BACKUP
     // And a backup image
     memset(img, 0, sizeof(*img));
     strcpy(img->u.name, "RedBoot[backup]");
     img->flash_base = redboot_flash_start;
     img->mem_base = redboot_flash_start;
     img->size = redboot_image_size;
+    img->data_length = img->size;
     img++;
     redboot_flash_start += redboot_image_size;
 #endif
 #if defined(CYGSEM_REDBOOT_FLASH_CONFIG) && defined(CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH)
     // And a descriptor for the configuration data
     memset(img, 0, sizeof(*img));
     strcpy(img->u.name, "RedBoot config");
     img->flash_base = (CYG_ADDRESS)cfg_base;
     img->mem_base = (CYG_ADDRESS)cfg_base;
     img->size = cfg_size;
+    img->data_length = img->size;
     img++;
 #endif
     // And a descriptor for the descriptor table itself
     memset(img, 0, sizeof(*img));
     strcpy(img->u.name, "FIS directory");
     img->flash_base = (CYG_ADDRESS)fis_addr;
     img->mem_base = (CYG_ADDRESS)fis_addr;
     img->size = fisdir_size;
+    img->data_length = img->size;
     img++;
 
     //create the entry for the redundant fis table
 #ifdef CYGOPT_REDBOOT_REDUNDANT_FIS
     memset(img, 0, sizeof(*img));
@@ -601,14 +647,14 @@ fis_init(int argc, char *argv[])
 #if (CYGBLD_REDBOOT_FLASH_BOOT_OFFSET > CYGNUM_REDBOOT_FLASH_RESERVED_BASE)
         erase_start = (CYG_ADDRESS)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE;
         erase_size =  (CYG_ADDRESS)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET;
         if ( erase_size > erase_start ) {
             erase_size -= erase_start;
-            if ((stat = flash_erase((void *)erase_start, erase_size,
-                                    (void **)&err_addr)) != 0) {
+            if ((stat = cyg_flash_erase((void *)erase_start, erase_size,
+                                        &err_addr)) != 0) {
                 diag_printf("   initialization failed at %p: %s\n",
-                            err_addr, flash_errmsg(stat));
+                            err_addr, cyg_flash_errmsg(stat));
             }
         }
 #endif
         // second deal with the larger part in the main:
         erase_start = redboot_flash_start; // high water of created images
@@ -620,44 +666,40 @@ fis_init(int argc, char *argv[])
         if (fis_addr > cfg_base) {
           erase_size = (CYG_ADDRESS)cfg_base - erase_start; // the gap between HWM and config data
         } else {
           erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between HWM and fis data
         }
-        if ((stat = flash_erase((void *)erase_start, erase_size,
-                                (void **)&err_addr)) != 0) {
+        if ((stat = cyg_flash_erase(erase_start, erase_size,&err_addr)) != 0) {
           diag_printf("   initialization failed %p: %s\n",
-                 err_addr, flash_errmsg(stat));
+                 err_addr, cyg_flash_errmsg(stat));
         }
         erase_start += (erase_size + flash_block_size);
         if (fis_addr > cfg_base) {
           erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between config and fis data
         } else {
           erase_size = (CYG_ADDRESS)cfg_base - erase_start; // the gap between fis and config data
         }
-        if ((stat = flash_erase((void *)erase_start, erase_size,
-                                (void **)&err_addr)) != 0) {
+        if ((stat = cyg_flash_erase(erase_start, erase_size,&err_addr)) != 0) {
           diag_printf("   initialization failed %p: %s\n",
-                 err_addr, flash_errmsg(stat));
+                 err_addr, cyg_flash_errmsg(stat));
         }
         erase_start += (erase_size + flash_block_size);
 #else  // !CYGSEM_REDBOOT_FLASH_CONFIG        
         erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between HWM and fis data
-        if ((stat = flash_erase((void *)erase_start, erase_size,
-                                (void **)&err_addr)) != 0) {
+        if ((stat = cyg_flash_erase(erase_start, erase_size,&err_addr)) != 0) {
           diag_printf("   initialization failed %p: %s\n",
-                 err_addr, flash_errmsg(stat));
+                      (void*)err_addr, cyg_flash_errmsg(stat));
         }
         erase_start += (erase_size + flash_block_size);          
 #endif
-        // Lastly, anything at the end, if there is any
-        if ( erase_start < (((CYG_ADDRESS)flash_end)+1) ) {
-            erase_size = ((CYG_ADDRESS)flash_end - erase_start) + 1;
-            if ((stat = flash_erase((void *)erase_start, erase_size,
-                                    (void **)&err_addr)) != 0) {
-                diag_printf("   initialization failed at %p: %s\n",
-                            err_addr, flash_errmsg(stat));
-            }
+        // Lastly, anything at the end
+        erase_size = ((CYG_ADDRESS)flash_end - erase_start) + 1;
+        if ((erase_size > 0) &&
+            ((stat = cyg_flash_erase(erase_start, erase_size,
+                                     &err_addr))) != 0) {
+            diag_printf("   initialization failed at %p: %s\n",
+                        (void*)err_addr, cyg_flash_errmsg(stat));
         }
 #ifndef CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS
     // In this case, 'fis free' works by scanning for erased blocks.  Since the
     // "-f" option was not supplied, there may be areas which are not used but
     // don't appear to be free since they are not erased - thus the warning
@@ -716,11 +758,11 @@ fis_list(int argc, char *argv[])
     do {
         image_found = false;
         lowest_addr = 0xFFFFFFFF;
         img = (struct fis_image_desc *) fis_work_block;
         for (i = 0;  i < fisdir_size/sizeof(*img);  i++, img++) {
-            if (img->u.name[0] != (unsigned char)0xFF) {
+            if (img->u.name[0] != '\xFF') {
                 if ((img->flash_base >= last_addr) && (img->flash_base < lowest_addr)) {
                     lowest_addr = img->flash_base;
                     image_found = true;
                     image_indx = i;
                 }
@@ -742,64 +784,106 @@ fis_list(int argc, char *argv[])
         }
         last_addr = lowest_addr + 1;
     } while (image_found == true);
 }
 
+#ifdef CYGNUM_REDBOOT_FLASH_RESERVED_DEVICES
+static CYG_ADDRESS flash_reserved_devices[] = { CYGNUM_REDBOOT_FLASH_RESERVED_DEVICES, 0xFFFFFFFF };
+
+static cyg_bool flash_reserved( CYG_ADDRESS start )
+{
+    int i;
+    for( i = 0; flash_reserved_devices[i] != 0xFFFFFFFF; i++ )
+        if( start == flash_reserved_devices[i] )
+            return true;
+    return false;
+}
+#else
+#define flash_reserved(__start) false
+#endif
+
 #ifdef CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS
 struct free_chunk {
     CYG_ADDRESS start, end;
 };
 
 static int
 find_free(struct free_chunk *chunks)
 {
-    CYG_ADDRESS *fis_ptr, *fis_end;
+    cyg_flash_info_t info;
     struct fis_image_desc *img;
-    int i, idx;
-    int num_chunks = 1;
+    int i=0, idx;
+    int num_chunks = 0;
+    int ret;
+    
+    do {
+        // get info for each flash device
+        ret = cyg_flash_get_info(i, &info);
 
-    // Do not search the area reserved for pre-RedBoot systems:
-    fis_ptr = (CYG_ADDRESS *)((CYG_ADDRESS)flash_start + 
-                              CYGNUM_REDBOOT_FLASH_RESERVED_BASE);
-    fis_end = (CYG_ADDRESS *)flash_end;
-    chunks[num_chunks-1].start = (CYG_ADDRESS)fis_ptr;
-    chunks[num_chunks-1].end = (CYG_ADDRESS)fis_end;
+        if (ret == CYG_FLASH_ERR_OK && !flash_reserved( info.start )) {
+            
+#ifdef CYGNUM_REDBOOT_FLASH_BASE
+            if ( CYGNUM_REDBOOT_FLASH_BASE == info.start )
+#else
+            if (i == 0 )
+#endif
+            {
+                // Do not search the area reserved for pre-RedBoot systems:
+                chunks[num_chunks].start = (info.start + 
+                                            CYGNUM_REDBOOT_FLASH_RESERVED_BASE);
+                chunks[num_chunks].end = info.end;
+                num_chunks++;
+            } else {   // Contiguous flash? If so collapse the chunks together.
+                if (chunks[num_chunks-1].end == (info.start -1)) {
+                    chunks[num_chunks-1].end = info.end;
+                } else {
+                    chunks[num_chunks].start = info.start;
+                    chunks[num_chunks].end = info.end;
+                    num_chunks++;
+                }
+            }
+        }
+        i++;
+    } while (ret != CYG_FLASH_ERR_INVALID);
+    
     fis_read_directory();
     img = (struct fis_image_desc *) fis_work_block;
     for (i = 0;  i < fisdir_size/sizeof(*img);  i++, img++) {
-        if (img->u.name[0] != (unsigned char)0xFF) {
+        if (img->u.name[0] != '\xFF') {
             // Figure out which chunk this is in and split it
             for (idx = 0;  idx < num_chunks;  idx++) {
                 if ((img->flash_base >= chunks[idx].start) && 
                     (img->flash_base <= chunks[idx].end)) {
                     if (img->flash_base == chunks[idx].start) {
                         chunks[idx].start += img->size;
                         if (chunks[idx].start >= chunks[idx].end) {
                             // This free chunk has collapsed
-                            while (idx < (num_chunks-1)) {
+                            num_chunks--;
+                            while (idx < num_chunks) {
                                 chunks[idx] = chunks[idx+1];
                                 idx++;
                             }
-                            num_chunks--;
                         }
-                    } else if ((img->flash_base+img->size) == chunks[idx].end) {
-                        chunks[idx].end = img->flash_base;
+                    } else if ((img->flash_base+img->size-1) >= chunks[idx].end) {
+                        chunks[idx].end = img->flash_base - 1;
                     } else {
                         // Split chunk into two parts
-                        if ((img->flash_base+img->size) < (CYG_ADDRESS)fis_end) {
-                            int j;
-                            // make room for new chunk
-                            for (j = num_chunks; j > (idx+1); j--)
-                                chunks[j] = chunks[j-1];
-                            chunks[idx+1].start = img->flash_base + img->size;
-                            chunks[idx+1].end = chunks[idx].end;
-                            if (++num_chunks == CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS) {
-                                diag_printf("Warning: too many free chunks\n");
-                                return num_chunks;
-                            }
+                        int idxtmp;
+                        
+                        // shift chunks along one so we insert the new one
+                        for (idxtmp=num_chunks; idxtmp > (idx+1); idxtmp--)
+                        {
+                            chunks[idxtmp] = chunks[idxtmp-1];
+                        }
+                        
+                        chunks[idx+1].start = img->flash_base + img->size;
+                        chunks[idx+1].end = chunks[idx].end;
+                        chunks[idx].end = img->flash_base - 1;
+                        if (++num_chunks == CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS) {
+                          diag_printf("Warning: too many free chunks\n");
+                          return num_chunks;
                         }
-                        chunks[idx].end = img->flash_base;
                     }
                     break;
                 }
             }
         }
@@ -809,46 +893,112 @@ find_free(struct free_chunk *chunks)
 #endif // CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS
 
 static void
 fis_free(int argc, char *argv[])
 {
-#ifndef CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS
-    unsigned long *fis_ptr, *fis_end, flash_data;
-    unsigned long *area_start;
-    void *err_addr;
+#if !defined(CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS)
+    cyg_uint32 flash_data;
+    cyg_flashaddr_t area_start;
+    cyg_flashaddr_t err_addr;
+    cyg_uint32 flash_dev_no;
+    int flash_err;
+    cyg_flash_info_t flash_info;
+    cyg_uint32 curr_block, curr_block_info;
+    cyg_flashaddr_t curr_flash_addr, next_flash_addr;
 
-    // Do not search the area reserved for pre-RedBoot systems:
-    fis_ptr = (unsigned long *)((CYG_ADDRESS)flash_start + 
-                                CYGNUM_REDBOOT_FLASH_RESERVED_BASE);
-    fis_end = (unsigned long *)(CYG_ADDRESS)flash_end;
-    area_start = fis_ptr;
-    while (fis_ptr < fis_end) {
-        flash_read(fis_ptr, &flash_data, sizeof(unsigned long), (void **)&err_addr);
-        if (flash_data != (unsigned long)0xFFFFFFFF) {
-            if (area_start != fis_ptr) {
-                // Assume that this is something
-                diag_printf("  0x%08lX .. 0x%08lX\n",
-                            (CYG_ADDRESS)area_start, (CYG_ADDRESS)fis_ptr);
-            }
-            // Find next blank block
-            area_start = fis_ptr;
-            while (area_start < fis_end) {
-                flash_read(area_start, &flash_data, sizeof(unsigned long), (void **)&err_addr);
-                if (flash_data == (unsigned long)0xFFFFFFFF) {
-                    break;
+    // For each flash device
+    for (flash_dev_no=0;; flash_dev_no++)
+    {
+        flash_err = cyg_flash_get_info( flash_dev_no, &flash_info );
+        if ( CYG_FLASH_ERR_OK != flash_err )  // assume all done
+            break;
+
+        if( flash_reserved( flash_info.start ) ) // Ignore reserved devices
+            continue;
+        
+        // Once more, from the top...
+        curr_flash_addr = area_start = flash_info.start;
+
+        // We must not search the area reserved for pre-RedBoot systems,
+        // but this is only the case for the first flash device, or
+        // the one corresponding to CYGNUM_REDBOOT_FLASH_BASE.
+        // FIXME: this is insufficiently generic by design - can only
+        // reserve on one flash.
+#ifdef CYGNUM_REDBOOT_FLASH_BASE
+        if ( CYGNUM_REDBOOT_FLASH_BASE == area_start )
+#else
+        if ( 0 == flash_dev_no )
+#endif
+        {
+            //cyg_flashaddr_t asold = area_start;
+            area_start += CYGNUM_REDBOOT_FLASH_RESERVED_BASE;
+            //diag_printf("area_start was %08x now %08x\n", asold, area_start );
+        }
+        // For each region of blocks
+        for ( curr_block_info = 0;
+              curr_block_info < flash_info.num_block_infos;
+              curr_block_info++ )
+        {
+            // For each individual block
+            for ( curr_block = 0;
+                  curr_block < flash_info.block_info[curr_block_info].blocks;
+                  curr_flash_addr = next_flash_addr, curr_block++ )
+            {
+                cyg_ucount32 i;
+                cyg_bool is_blank = true; // until proved otherwise
+                size_t amount_to_check;
+
+                // determine this now to avoid recalculating it later in this block, so we know the
+                // end of this block
+                next_flash_addr = curr_flash_addr + flash_info.block_info[curr_block_info].block_size;
+
+                // If area_start got adjusted further up, skip until we reach it
+                if ( curr_flash_addr < area_start )
+                    continue;
+                
+                //diag_printf("block region %d, block %d, flashaddr %08x\n",curr_block_info,curr_block,curr_flash_addr);
+                
+                // check 32 bytes at most. Reading it all will take too long on many devices.
+                // Perhaps this should be a config option.
+                amount_to_check = 32; 
+                if ( amount_to_check > flash_info.block_info[curr_block_info].block_size ) // paranoia
+                    amount_to_check = flash_info.block_info[curr_block_info].block_size;
+
+                for ( i=0; i<amount_to_check; i += sizeof(cyg_uint32) )
+                {
+                    flash_err = cyg_flash_read(curr_flash_addr+i, &flash_data, sizeof(cyg_uint32), &err_addr);
+                    if ( (CYG_FLASH_ERR_OK != flash_err) || (flash_data != 0xffffffff) )
+                    {
+                        is_blank = false;
+                        break; // no point continuing
+                    }
+                } // for
+                
+                if (!is_blank)
+                {
+                    /* If not blank, output the preceding region if any */
+                    if ( curr_flash_addr != area_start )
+                    {
+                        diag_printf("  0x%08lX .. 0x%08lX\n",
+                                    area_start,
+                                    next_flash_addr-1 );
+                    }
+                    area_start = next_flash_addr;
                 }
-                area_start += flash_block_size / sizeof(CYG_ADDRESS);
-            }
-            fis_ptr = area_start;
-        } else {
-            fis_ptr += flash_block_size / sizeof(CYG_ADDRESS);
+            } // for block
+        } // for block region
+
+        /* If the blank region extended to the very end of the device, we need to do one
+         * final check at the end of the device.
+         */
+        if ( curr_flash_addr != area_start )
+        {
+            diag_printf("  0x%08lX .. 0x%08lX\n",
+                        area_start,
+                        next_flash_addr-1 );
         }
-    }
-    if (area_start != fis_ptr) {
-        diag_printf("  0x%08lX .. 0x%08lX\n", 
-                    (CYG_ADDRESS)area_start, (CYG_ADDRESS)fis_ptr);
-    }
+    } // for flash device
 #else
     struct free_chunk chunks[CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS];
     int idx, num_chunks;
 
     num_chunks = find_free(chunks);
@@ -863,85 +1013,151 @@ fis_free(int argc, char *argv[])
 // Find the first unused area of flash which is long enough
 static bool
 fis_find_free(CYG_ADDRESS *addr, unsigned long length)
 {
 #ifndef CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS
-    unsigned long *fis_ptr, *fis_end, flash_data;
-    unsigned long *area_start;
-    void *err_addr;
+    cyg_uint32 flash_data;
+    cyg_flashaddr_t area_start;
+    cyg_flashaddr_t err_addr;
+    cyg_uint32 flash_dev_no;
+    int flash_err;
+    cyg_flash_info_t flash_info;
+    cyg_uint32 curr_block, curr_block_info;
+    cyg_flashaddr_t curr_flash_addr, next_flash_addr;
 
-    // Do not search the area reserved for pre-RedBoot systems:
-    fis_ptr = (unsigned long *)((CYG_ADDRESS)flash_start + 
-                                CYGNUM_REDBOOT_FLASH_RESERVED_BASE);
-    fis_end = (unsigned long *)(CYG_ADDRESS)flash_end;
-    area_start = fis_ptr;
-    while (fis_ptr < fis_end) {
-        flash_read(fis_ptr, &flash_data, sizeof(unsigned long), (void **)&err_addr);
-        if (flash_data != (unsigned long)0xFFFFFFFF) {
-            if (area_start != fis_ptr) {
-                // Assume that this is something
-                if ((fis_ptr-area_start) >= (length/sizeof(unsigned))) {
-                    *addr = (CYG_ADDRESS)area_start;
-                    return true;
-                }
-            }
-            // Find next blank block
-            area_start = fis_ptr;
-            while (area_start < fis_end) {
-                flash_read(area_start, &flash_data, sizeof(unsigned long), (void **)&err_addr);
-                if (flash_data == (unsigned long)0xFFFFFFFF) {
-                    break;
+    // For each flash device
+    for (flash_dev_no=0;; flash_dev_no++)
+    {
+        flash_err = cyg_flash_get_info( flash_dev_no, &flash_info );
+        if ( CYG_FLASH_ERR_OK != flash_err )  // assume all done
+            break;
+
+        if( flash_reserved( flash_info.start ) ) // Ignore reserved devices
+            continue;
+        
+        // Once more, from the top...
+        curr_flash_addr = area_start = flash_info.start;
+
+        // We must not search the area reserved for pre-RedBoot systems,
+        // but this is only the case for the first flash device, or
+        // the one corresponding to CYGNUM_REDBOOT_FLASH_BASE.
+        // FIXME: this is insufficiently generic by design - can only
+        // reserve on one flash.
+#ifdef CYGNUM_REDBOOT_FLASH_BASE
+        if ( CYGNUM_REDBOOT_FLASH_BASE == area_start )
+#else
+        if ( 0 == flash_dev_no )
+#endif
+        {
+            //cyg_flashaddr_t asold = area_start;
+            area_start += CYGNUM_REDBOOT_FLASH_RESERVED_BASE;
+            //diag_printf("area_start was %08x now %08x\n", asold, area_start );
+        }
+        // For each region of blocks
+        for ( curr_block_info = 0;
+              curr_block_info < flash_info.num_block_infos;
+              curr_block_info++ )
+        {
+            // For each individual block
+            for ( curr_block = 0;
+                  curr_block < flash_info.block_info[curr_block_info].blocks;
+                  curr_flash_addr = next_flash_addr, curr_block++ )
+            {
+                cyg_ucount32 i;
+                cyg_bool is_blank = true; // until proved otherwise
+                size_t amount_to_check;
+
+                // determine this now to avoid recalculating it later in this block, so we know the
+                // end of this block
+                next_flash_addr = curr_flash_addr + flash_info.block_info[curr_block_info].block_size;
+
+                // If area_start got adjusted further up, skip until we reach it
+                if ( curr_flash_addr < area_start )
+                    continue;
+                
+                //diag_printf("block region %d, block %d, flashaddr %08x\n",curr_block_info,curr_block,curr_flash_addr);
+                
+                // check 32 bytes at most. Reading it all will take too long on many devices.
+                // Perhaps this should be a config option.
+                amount_to_check = 32; 
+                if ( amount_to_check > flash_info.block_info[curr_block_info].block_size ) // paranoia
+                    amount_to_check = flash_info.block_info[curr_block_info].block_size;
+
+                for ( i=0; i<amount_to_check; i += sizeof(cyg_uint32) )
+                {
+                    flash_err = cyg_flash_read(curr_flash_addr+i, &flash_data, sizeof(cyg_uint32), &err_addr);
+                    if ( (CYG_FLASH_ERR_OK != flash_err) || (flash_data != 0xffffffff) )
+                    {
+                        is_blank = false;
+                        break; // no point continuing
+                    }
+                } // for
+                
+                if (!is_blank)
+                {
+                    /* If not blank, output the preceding region if any */
+                    if ( curr_flash_addr != area_start )
+                    {
+                        if ( length <= (next_flash_addr - area_start) )
+                        {
+                            *addr = (CYG_ADDRESS)area_start;
+                            return true;
+                        }    
+                    }
+                    area_start = next_flash_addr;
                 }
-                area_start += flash_block_size / sizeof(CYG_ADDRESS);
-            }
-            fis_ptr = area_start;
-        } else {
-            fis_ptr += flash_block_size / sizeof(CYG_ADDRESS);
-        }
-    }
-    if (area_start != fis_ptr) {
-        if ((fis_ptr-area_start) >= (length/sizeof(unsigned))) {
-            *addr = (CYG_ADDRESS)area_start;
-            return true;
+            } // for block
+        } // for block region
+
+        /* If the blank region extended to the very end of the device, we need to do one
+         * final check at the end of the device.
+         */
+        if ( curr_flash_addr != area_start )
+        {
+            if ( length <= (next_flash_addr - area_start) )
+            {
+                *addr = (CYG_ADDRESS)area_start;
+                return true;
+            }    
         }
-    }
-    return false;
+    } // for flash device
 #else
     struct free_chunk chunks[CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS];
     int idx, num_chunks;
 
     num_chunks = find_free(chunks);
     for (idx = 0;  idx < num_chunks;  idx++) {
-        if ((chunks[idx].end - chunks[idx].start) >= length) {
+        if ((chunks[idx].end - chunks[idx].start + 1) >= length) {
             *addr = (CYG_ADDRESS)chunks[idx].start;
             return true;
         }
     }
-    return false;
 #endif
+    return false;
 }
 
 static void
 fis_create(int argc, char *argv[])
 {
     int i, stat;
     unsigned long length, img_size;
-    CYG_ADDRESS mem_addr, exec_addr, flash_addr, entry_addr;
+    CYG_ADDRESS mem_addr, exec_addr, flash_addr, entry_addr, flash_offset;
     char *name;
     bool mem_addr_set = false;
     bool exec_addr_set = false;
     bool entry_addr_set = false;
     bool flash_addr_set = false;
     bool length_set = false;
     bool img_size_set = false;
     bool no_copy = false;
-    void *err_addr;
+    cyg_flashaddr_t err_addr;
     struct fis_image_desc *img = NULL;
     bool defaults_assumed;
     struct option_info opts[7];
     bool prog_ok = true;
-
+    size_t block_size;
+    
     init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 
               (void *)&mem_addr, (bool *)&mem_addr_set, "memory base address");
     init_opts(&opts[1], 'r', true, OPTION_ARG_TYPE_NUM, 
               (void *)&exec_addr, (bool *)&exec_addr_set, "ram base address");
     init_opts(&opts[2], 'e', true, OPTION_ARG_TYPE_NUM, 
@@ -972,18 +1188,20 @@ fis_create(int argc, char *argv[])
                 length = img->size;
                 defaults_assumed = true;
             }
         }
     }
-    if (!mem_addr_set && (load_address >= (CYG_ADDRESS)ram_start) &&
+    if ((!mem_addr_set || mem_addr == load_address) && !no_copy && (load_address >= (CYG_ADDRESS)ram_start) &&
 	(load_address_end) < (CYG_ADDRESS)ram_end) {
 	mem_addr = load_address;
 	mem_addr_set = true;
         defaults_assumed = true;
         // Get entry address from loader, unless overridden
-        if (!entry_addr_set)
+        if (!entry_addr_set) {
             entry_addr = entry_address;
+            entry_addr_set = true;
+        }
 	if (!length_set) {
 	    length = load_address_end - load_address;
 	    length_set = true;
 	} else if (defaults_assumed && !img_size_set) {
 	    /* We got length from the FIS table, so the size of the
@@ -1004,56 +1222,69 @@ fis_create(int argc, char *argv[])
             flash_addr = img->flash_base;
             defaults_assumed = true;
         }
     }
 
-    if ((!no_copy && !mem_addr_set) || (no_copy && !flash_addr_set) ||
+    if ((!no_copy && !mem_addr_set) ||
         !length_set || !name) {
         fis_usage("required parameter missing");
         return;
     }
     if (!img_size_set) {
         img_size = length;
     }
-    // 'length' is size of FLASH image, 'img_size' is actual data size
-    // Round up length to FLASH block size
-#ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken
-    length = ((length + flash_block_size - 1) / flash_block_size) * flash_block_size;
     if (length < img_size) {
         diag_printf("Invalid FLASH image size/length combination\n");
         return;
     }
-#endif
+
+    if (strlen(name) >= sizeof(img->u.name)) {
+        diag_printf("Name is too long, must be less than %d chars\n", (int)sizeof(img->u.name));
+        return;
+    }
+
     if (flash_addr_set &&
         ((stat = flash_verify_addr((void *)flash_addr)) ||
          (stat = flash_verify_addr((void *)(flash_addr+length-1))))) {
         _show_invalid_flash_address(flash_addr, stat);
         return;
     }
-    if (flash_addr_set && ((flash_addr & (flash_block_size-1)) != 0)) {
-        diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr);
-        diag_printf("   must be 0x%x aligned\n", flash_block_size);
-        return;
-    }
-    if (strlen(name) >= sizeof(img->u.name)) {
-        diag_printf("Name is too long, must be less than %d chars\n", (int)sizeof(img->u.name));
-        return;
-    }
     if (!no_copy) {
         if ((mem_addr < (CYG_ADDRESS)ram_start) ||
             ((mem_addr+img_size) >= (CYG_ADDRESS)ram_end)) {
             diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr);
             diag_printf("   valid range is %p-%p\n", (void *)ram_start, (void *)ram_end);
         }
-        if (!flash_addr_set && !fis_find_free(&flash_addr, length)) {
-            diag_printf("Can't locate %lx(%ld) bytes free in FLASH\n", length, length);
-            return;
-        }
     }
+    if (!flash_addr_set && !fis_find_free(&flash_addr, length)) {
+        diag_printf("Can't locate %lx(%ld) bytes free in FLASH\n", length, length);
+        return;
+    }
+    flash_addr_set = true;
+
+    block_size = cyg_flash_block_size(flash_addr + length);
+    length = ((length + block_size - 1) / block_size) * block_size;
+    if (length < img_size) {
+        diag_printf("Invalid FLASH image size/length combination\n");
+        return;
+    }
+    if ((stat = cyg_flash_verify_addr(flash_addr)) ||
+        (stat = cyg_flash_verify_addr((flash_addr+length-1)))) {
+        _show_invalid_flash_address(flash_addr, stat);
+        return;
+    }
+    block_size = cyg_flash_block_size(flash_addr);
+    flash_offset = (flash_addr-flash_start)/block_size;
+    if( flash_start + (flash_offset * block_size) != flash_addr ) {
+        diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr);
+        diag_printf("   must be 0x%x aligned\n", (unsigned int)flash_block_size);
+        return;
+    }
+    
     // First, see if the image by this name has agreable properties
     if (img) {
-        if (flash_addr_set && (img->flash_base != flash_addr)) {
+        if (img->flash_base != flash_addr) {
             diag_printf("Image found, but flash address (%p)\n"
                         "             is incorrect (present image location %p)\n",
                         (void*)flash_addr, (void*)img->flash_base);
             
             return;
@@ -1077,17 +1308,18 @@ fis_create(int argc, char *argv[])
             }
         }
     } else {
 #ifdef CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS
         // Make sure that any FLASH address specified directly is truly free
-        if (flash_addr_set && !no_copy) {
+        if (!no_copy) {
             struct free_chunk chunks[CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS];
             int idx, num_chunks;
             bool is_free = false;
 
             num_chunks = find_free(chunks);
             for (idx = 0;  idx < num_chunks;  idx++) {
+                //diag_printf("addr %08x, length %d chunk start %08x, end %08x\n",flash_addr, length, chunks[idx].start, chunks[idx].end);
                 if ((flash_addr >= chunks[idx].start) && 
                     ((flash_addr+length-1) <= chunks[idx].end)) {
                     is_free = true;
                 }
             }
@@ -1095,42 +1327,62 @@ fis_create(int argc, char *argv[])
                 diag_printf("Invalid FLASH address - not free!\n");
                 return;
             }
         }
 #endif
-        // If not image by that name, try and find an empty slot
+        // If no image by that name, try and find an empty slot
         img = (struct fis_image_desc *)fis_work_block;
         for (i = 0;  i < fisdir_size/sizeof(*img);  i++, img++) {
-            if (img->u.name[0] == (unsigned char)0xFF) {
+            if (img->u.name[0] == '\xFF') {
                 break;
             }
         }
 	if (i >= fisdir_size/sizeof(*img)) {
 	    diag_printf("Can't find an empty slot in FIS directory!\n");
 	    return;
 	}
     }
     if (!no_copy) {
         // Safety check - make sure the address range is not within the code we're running
-        if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+img_size-1))) {
+        if (check_code_overlaps(flash_addr, (flash_addr+img_size-1))) {
             diag_printf("Can't program this region - contains code in use!\n");
             return;
         }
+#ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING            
+        if (prog_ok) {
+            // Unlock area to be programmed
+            if ((stat = cyg_flash_unlock((cyg_flashaddr_t)flash_addr, length, &err_addr)) != 0) {
+                diag_printf("Can't unlock region at %p: %s\n", (void*)err_addr, flash_errmsg(stat));
+                prog_ok = false;
+            }
+        }
+#endif
         if (prog_ok) {
             // Erase area to be programmed
-            if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) {
-                diag_printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat));
+            if ((stat = cyg_flash_erase(flash_addr, length, &err_addr)) != 0) {
+                diag_printf("Can't erase region at %p: %s\n", (void*)err_addr, cyg_flash_errmsg(stat));
                 prog_ok = false;
             }
         }
         if (prog_ok) {
             // Now program it
-            if ((stat = FLASH_PROGRAM((void *)flash_addr, (void *)mem_addr, img_size, (void **)&err_addr)) != 0) {
-                diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat));
+            if ((stat = cyg_flash_program(flash_addr, (void *)mem_addr, img_size, 
+                                          &err_addr)) != 0) {
+                diag_printf("Can't program region at %p: %s\n", (void*)err_addr, 
+                            cyg_flash_errmsg(stat));
+                prog_ok = false;
+            }
+        }
+#ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING            
+        if (prog_ok) {
+            // Lock area programmed
+            if ((stat = cyg_flash_lock((cyg_flashaddr_t)flash_addr, length, &err_addr)) != 0) {
+                diag_printf("Can't lock region at %p: %s\n", (void*)err_addr, flash_errmsg(stat));
                 prog_ok = false;
             }
         }
+#endif
     }
     if (prog_ok) {
         // Update directory
         memset(img, 0, sizeof(*img));
         strcpy(img->u.name, name);
@@ -1156,11 +1408,11 @@ extern void arm_fis_delete(char *);
 static void
 fis_delete(int argc, char *argv[])
 {
     char *name;
     int num_reserved, i, stat;
-    void *err_addr;
+    cyg_flashaddr_t err_addr;
     struct fis_image_desc *img;
 
     if (!scan_opts(argc, argv, 2, 0, 0, (void *)&name, OPTION_ARG_TYPE_STR, "image name"))
     {
         fis_usage("invalid arguments");
@@ -1204,14 +1456,14 @@ fis_delete(int argc, char *argv[])
     } else {
         diag_printf("No image '%s' found\n", name);
         return;
     }
     // Erase Data blocks (free space)
-    if ((stat = flash_erase((void *)img->flash_base, img->size, (void **)&err_addr)) != 0) {
-        diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat));
+    if ((stat = cyg_flash_erase(img->flash_base, img->size, &err_addr)) != 0) {
+        diag_printf("Error erasing at %p: %s\n", (void*)err_addr, cyg_flash_errmsg(stat));
     } else {
-        img->u.name[0] = (unsigned char)0xFF;    
+        img->u.name[0] = '\xFF';    
         fis_start_update_directory(0);
         fis_update_directory(0, 0);
     }
 }
 
@@ -1229,11 +1481,11 @@ fis_load(int argc, char *argv[])
 #endif
     int num_options;
 #if defined(CYGPRI_REDBOOT_ZLIB_FLASH) ||  defined(CYGSEM_REDBOOT_FIS_CRC_CHECK)
     bool decompress = false;
 #endif
-    void *err_addr;
+    cyg_flashaddr_t err_addr;
 
     init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 
               (void *)&mem_addr, (bool *)&mem_addr_set, "memory [load] base address");
     init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, 
               (void *)&show_cksum, (bool *)0, "display checksum");
@@ -1297,11 +1549,12 @@ fis_load(int argc, char *argv[])
         // Reload fis directory
         fis_read_directory();
     } else // dangling block
 #endif
     {
-        flash_read((void *)img->flash_base, (void *)mem_addr, img->data_length, (void **)&err_addr);
+        cyg_flash_read(img->flash_base, (void *)mem_addr, img->data_length, 
+                       &err_addr);
 
         // Set load address/top
         load_address = mem_addr;
         load_address_end = mem_addr + img->data_length;
     }
@@ -1327,18 +1580,19 @@ fis_load(int argc, char *argv[])
 static void
 fis_write(int argc, char *argv[])
 {
     int stat;
     unsigned long length;
-    CYG_ADDRESS mem_addr, flash_addr;
+    CYG_ADDRESS mem_addr, flash_addr, flash_offset;
     bool mem_addr_set = false;
     bool flash_addr_set = false;
     bool length_set = false;
-    void *err_addr;
+    cyg_flashaddr_t err_addr;
     struct option_info opts[3];
     bool prog_ok;
-
+    size_t block_size;
+    
     init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 
               (void *)&mem_addr, (bool *)&mem_addr_set, "memory base address");
     init_opts(&opts[1], 'f', true, OPTION_ARG_TYPE_NUM, 
               (void *)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address");
     init_opts(&opts[2], 'l', true, OPTION_ARG_TYPE_NUM, 
@@ -1353,31 +1607,32 @@ fis_write(int argc, char *argv[])
         fis_usage("required parameter missing");
         return;
     }
 
     // Round up length to FLASH block size
-#ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken
-    length = ((length + flash_block_size - 1) / flash_block_size) * flash_block_size;
-#endif
-    if (flash_addr_set &&
-        ((stat = flash_verify_addr((void *)flash_addr)) ||
-         (stat = flash_verify_addr((void *)(flash_addr+length-1))))) {
+    block_size = cyg_flash_block_size(flash_addr + length);
+    length = ((length + block_size - 1) / block_size) * block_size;
+    if ((stat = cyg_flash_verify_addr(flash_addr)) ||
+         (stat = cyg_flash_verify_addr((flash_addr+length-1)))) {
         _show_invalid_flash_address(flash_addr, stat);
         return;
     }
-    if (flash_addr_set && flash_addr & (flash_block_size-1)) {
+
+    block_size = cyg_flash_block_size(flash_addr);
+    flash_offset = (flash_addr-flash_start)/block_size;
+    if( flash_start + (flash_offset * block_size) != flash_addr ) {
         diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr);
-        diag_printf("   must be 0x%x aligned\n", flash_block_size);
+        diag_printf("   must be 0x%x aligned\n", (unsigned int)block_size);
         return;
     }
     if ((mem_addr < (CYG_ADDRESS)ram_start) ||
         ((mem_addr+length) >= (CYG_ADDRESS)ram_end)) {
         diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr);
         diag_printf("   valid range is %p-%p\n", (void *)ram_start, (void *)ram_end);
     }
     // Safety check - make sure the address range is not within the code we're running
-    if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+length-1))) {
+    if (check_code_overlaps(flash_addr, (flash_addr+length-1))) {
         diag_printf("Can't program this region - contains code in use!\n");
         return;
     }
     if (!verify_action("* CAUTION * about to program FLASH\n            at %p..%p from %p", 
                        (void *)flash_addr, (void *)(flash_addr+length-1),
@@ -1385,34 +1640,39 @@ fis_write(int argc, char *argv[])
         return;  // The guy gave up
     }
     prog_ok = true;
     if (prog_ok) {
         // Erase area to be programmed
-        if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) {
-            diag_printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat));
+        if ((stat = cyg_flash_erase(flash_addr, length, &err_addr)) != 0) {
+            diag_printf("Can't erase region at %p: %s\n", (void*)err_addr, 
+                        cyg_flash_errmsg(stat));
             prog_ok = false;
         }
     }
     if (prog_ok) {
         // Now program it
-        if ((stat = FLASH_PROGRAM((void *)flash_addr, (void *)mem_addr, length, (void **)&err_addr)) != 0) {
-            diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat));
+        if ((stat = cyg_flash_program(flash_addr, (void *)mem_addr, length, 
+                                      &err_addr)) != 0) {
+            diag_printf("Can't program region at %p: %s\n", (void*)err_addr, 
+                        cyg_flash_errmsg(stat));
             prog_ok = false;
         }
     }
 }
 
 static void
 fis_erase(int argc, char *argv[])
 {
     int stat;
     unsigned long length;
-    CYG_ADDRESS flash_addr;
+    CYG_ADDRESS flash_addr, flash_offset;
     bool flash_addr_set = false;
     bool length_set = false;
-    void *err_addr;
+    cyg_flashaddr_t err_addr;
     struct option_info opts[2];
+    size_t block_size;
+    
 
     init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, 
               (void *)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address");
     init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, 
               (void *)&length, (bool *)&length_set, "length");
@@ -1425,27 +1685,29 @@ fis_erase(int argc, char *argv[])
     if (!flash_addr_set || !length_set) {
         fis_usage("missing argument");
         return;
     }
     if (flash_addr_set &&
-        ((stat = flash_verify_addr((void *)flash_addr)) ||
-         (stat = flash_verify_addr((void *)(flash_addr+length-1))))) {
+        ((stat = cyg_flash_verify_addr(flash_addr)) ||
+         (stat = cyg_flash_verify_addr((flash_addr+length-1))))) {
         _show_invalid_flash_address(flash_addr, stat);
         return;
     }
-    if (flash_addr_set && flash_addr & (flash_block_size-1)) {
+    block_size = cyg_flash_block_size(flash_addr);
+    flash_offset = (flash_addr-flash_start)/block_size;
+    if( flash_addr_set && (flash_start + (flash_offset * block_size) != flash_addr) ) {
         diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr);
-        diag_printf("   must be 0x%x aligned\n", flash_block_size);
+        diag_printf("   must be 0x%x aligned\n", (unsigned int)flash_block_size);
         return;
     }
     // Safety check - make sure the address range is not within the code we're running
-    if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+length-1))) {
+    if (check_code_overlaps(flash_addr, (flash_addr+length-1))) {
         diag_printf("Can't erase this region - contains code in use!\n");
         return;
     }
-    if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) {
-        diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat));
+    if ((stat = cyg_flash_erase(flash_addr, length, &err_addr)) != 0) {
+        diag_printf("Error erasing at %p: %s\n", (void*)err_addr, cyg_flash_errmsg(stat));
     }
 }
 
 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
 
@@ -1456,11 +1718,11 @@ fis_lock(int argc, char *argv[])
     int stat;
     unsigned long length;
     CYG_ADDRESS flash_addr;
     bool flash_addr_set = false;
     bool length_set = false;
-    void *err_addr;
+    cyg_flashaddr_t err_addr;
     struct option_info opts[2];
 
     init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, 
               (void *)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address");
     init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, 
@@ -1486,17 +1748,17 @@ fis_lock(int argc, char *argv[])
       if (!flash_addr_set || !length_set) {
         fis_usage("missing argument");
         return;
     }
     if (flash_addr_set &&
-        ((stat = flash_verify_addr((void *)flash_addr)) ||
-         (stat = flash_verify_addr((void *)(flash_addr+length-1))))) {
+        ((stat = cyg_flash_verify_addr(flash_addr)) ||
+         (stat = cyg_flash_verify_addr((flash_addr+length-1))))) {
         _show_invalid_flash_address(flash_addr, stat);
         return;
     }
-    if ((stat = flash_lock((void *)flash_addr, length, (void **)&err_addr)) != 0) {
-        diag_printf("Error locking at %p: %s\n", err_addr, flash_errmsg(stat));
+    if ((stat = cyg_flash_lock(flash_addr, length, &err_addr)) != 0) {
+        diag_printf("Error locking at %p: %s\n", (void*)err_addr, cyg_flash_errmsg(stat));
     }
 }
 
 static void
 fis_unlock(int argc, char *argv[])
@@ -1505,11 +1767,11 @@ fis_unlock(int argc, char *argv[])
     int stat;
     unsigned long length;
     CYG_ADDRESS flash_addr;
     bool flash_addr_set = false;
     bool length_set = false;
-    void *err_addr;
+    cyg_flashaddr_t err_addr;
     struct option_info opts[2];
 
     init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, 
               (void *)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address");
     init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, 
@@ -1534,45 +1796,62 @@ fis_unlock(int argc, char *argv[])
       if (!flash_addr_set || !length_set) {
         fis_usage("missing argument");
         return;
     }
     if (flash_addr_set &&
-        ((stat = flash_verify_addr((void *)flash_addr)) ||
-         (stat = flash_verify_addr((void *)(flash_addr+length-1))))) {
+        ((stat = cyg_flash_verify_addr(flash_addr)) ||
+         (stat = cyg_flash_verify_addr((flash_addr+length-1))))) {
         _show_invalid_flash_address(flash_addr, stat);
         return;
     }
 
-    if ((stat = flash_unlock((void *)flash_addr, length, (void **)&err_addr)) != 0) {
-        diag_printf("Error unlocking at %p: %s\n", err_addr, flash_errmsg(stat));
+    if ((stat = cyg_flash_unlock(flash_addr, length, &err_addr)) != 0) {
+        diag_printf("Error unlocking at %p: %s\n", (void*)err_addr, cyg_flash_errmsg(stat));
     }
 }
 #endif
 
 // This is set non-zero if the FLASH subsystem has successfully been initialized
-int __flash_init = 0;
+int __flash_init;
 
 void
 _flash_info(void)
-{
+{   
+    cyg_uint32 i=0,j;
+    cyg_flash_info_t info;
+    int ret;
+    
     if (!__flash_init) return;
-    diag_printf("FLASH: %p - 0x%x, %d blocks of %p bytes each.\n", 
-           flash_start, (CYG_ADDRWORD)flash_end + 1, flash_num_blocks, (void *)flash_block_size);
+
+    do {
+      ret = cyg_flash_get_info(i, &info);
+      if (ret == CYG_FLASH_ERR_OK) {
+          diag_printf("FLASH: %p-%p", (void*)info.start, (void*)info.end);
+        for (j=0;j < info.num_block_infos; j++) {
+          diag_printf(", %d x 0x%x blocks",
+                      info.block_info[j].blocks,
+                      (unsigned int)info.block_info[j].block_size);
+        }
+        diag_printf("\n");
+      }
+      i++;
+    } while (ret != CYG_FLASH_ERR_INVALID);
 }
 
 /* Returns -1 on failure, 0 on success, 1 if it was successfull
  but a failed fis update was detected  */
 int
 do_flash_init(void)
 {
-    int stat;
+    int stat, i;
+    cyg_flash_info_t info;
 
 #ifdef CYGOPT_REDBOOT_REDUNDANT_FIS
     struct fis_image_desc img0;
     struct fis_image_desc img1;
     int fis_update_was_interrupted=0;
-    void *err_addr;
+    cyg_flashaddr_t err_addr;
 
     //check the size of fis_valid_info
     CYG_ASSERT((sizeof(struct fis_valid_info)<=sizeof(img0.u.name)), "fis_valid_info size mismatch");
     //try to check the alignment of version_count
     CYG_ASSERT((((unsigned long)&img0.u.valid_info.version_count - (unsigned long)&img0) % sizeof(unsigned long) == 0), "alignment problem");
@@ -1580,18 +1859,43 @@ do_flash_init(void)
 
 
 
     if (!__flash_init) {
         __flash_init = 1;
-        if ((stat = flash_init(diag_printf)) != 0) {
-            diag_printf("FLASH: driver init failed: %s\n", flash_errmsg(stat));
+        
+        if ((stat = cyg_flash_init(diag_printf)) != 0) {
+            diag_printf("FLASH: driver init failed: %s\n", cyg_flash_errmsg(stat));
             return -1;
         }
-        flash_get_limits((void *)0, (void **)&flash_start, (void **)&flash_end);
-        // Keep 'end' address as last valid location, to avoid wrap around problems
-        flash_end = (void *)((CYG_ADDRESS)flash_end - 1);
-        flash_get_block_info(&flash_block_size, &flash_num_blocks);
+
+#ifdef CYGNUM_REDBOOT_FLASH_BASE
+        stat = cyg_flash_get_info_addr(CYGNUM_REDBOOT_FLASH_BASE, &info);
+#else
+        stat = cyg_flash_get_info(0, &info);
+#endif
+        if (stat != CYG_FLASH_ERR_OK) {
+             diag_printf("FLASH: driver init failed: %s\n", 
+                         cyg_flash_errmsg(stat));
+             return false;
+        }
+        flash_start = info.start;
+        flash_end = info.end;
+
+        // No bootblock support yet, so we merge any bootblocks we might
+        // find into full size blocks
+        for (i=0; i < info.num_block_infos; i++) {
+          if (info.block_info[i].block_size > flash_block_size) {
+            flash_block_size = info.block_info[i].block_size;
+          }
+        }
+        flash_num_blocks = 0;
+        for (i=0; i < info.num_block_infos; i++) {
+          flash_num_blocks += (info.block_info[i].block_size *
+                               info.block_info[i].blocks) /
+            flash_block_size;
+        }
+        
 #ifdef CYGOPT_REDBOOT_FIS
         fisdir_size = CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_COUNT * CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_SIZE;
         fisdir_size = ((fisdir_size + flash_block_size - 1) / flash_block_size) * flash_block_size;
 # if defined(CYGPRI_REDBOOT_ZLIB_FLASH) && defined(CYGOPT_REDBOOT_FIS_ZLIB_COMMON_BUFFER)
 	fis_work_block = fis_zlib_common_buffer;
@@ -1601,16 +1905,17 @@ do_flash_init(void)
 	}
 # else
         workspace_end = (unsigned char *)(workspace_end-fisdir_size);
         fis_work_block = workspace_end;
 # endif
+
         if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) {
-            fis_addr = (void *)((CYG_ADDRESS)flash_end + 1 +
-                                (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*flash_block_size));
+            fis_addr = ((CYG_ADDRESS)flash_end + 1 +
+                        (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*flash_block_size));
         } else {
-            fis_addr = (void *)((CYG_ADDRESS)flash_start + 
-                                (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*flash_block_size));
+            fis_addr = ((CYG_ADDRESS)flash_start + 
+                        (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*flash_block_size));
         }
         
         if (((CYG_ADDRESS)fis_addr + fisdir_size - 1) > (CYG_ADDRESS)flash_end) {
             diag_printf("FIS directory doesn't fit\n");
             return -1;
@@ -1627,12 +1932,12 @@ do_flash_init(void)
 
         if (((CYG_ADDRESS)redundant_fis_addr + fisdir_size - 1) > (CYG_ADDRESS)flash_end) {
             diag_printf("Redundant FIS directory doesn't fit\n");
             return -1;
         }
-        FLASH_READ(fis_addr, &img0, sizeof(img0), (void **)&err_addr);
-        FLASH_READ(redundant_fis_addr, &img1, sizeof(img1), (void **)&err_addr);
+        cyg_flash_read(fis_addr, &img0, sizeof(img0), &err_addr);
+        cyg_flash_read(redundant_fis_addr, &img1, sizeof(img1), &err_addr);
 
         if (strncmp(img0.u.valid_info.magic_name, CYG_REDBOOT_RFIS_VALID_MAGIC, CYG_REDBOOT_RFIS_VALID_MAGIC_LENGTH)!=0)
         {
            memset(&img0, 0, sizeof(img0));
         }

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