* [flashv2 merge] RedBoot
@ 2008-11-18 1:00 Jonathan Larmour
2008-11-18 1:32 ` Jonathan Larmour
0 siblings, 1 reply; 2+ messages in thread
From: Jonathan Larmour @ 2008-11-18 1:00 UTC (permalink / raw)
To: eCos Patches List
[-- Attachment #1: Type: text/plain, Size: 316 bytes --]
With many eCosCentric updates. Attached.
--
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
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: flashv2.redboot.diff --]
[-- Type: text/x-patch; name="flashv2.redboot.diff", Size: 18204 bytes --]
Index: packages/redboot/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/ChangeLog,v
retrieving revision 1.259
diff -u -5 -p -r1.259 ChangeLog
--- packages/redboot/current/ChangeLog 11 Nov 2008 17:08:17 -0000 1.259
+++ packages/redboot/current/ChangeLog 18 Nov 2008 00:58:17 -0000
@@ -1,5 +1,25 @@
+2008-11-16 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/redboot.cdl, src/flash.c, src/fconfig.c:
+ Flash-related eCosCentric changes to these files (including a
+ merge of the flashv2 work) have been merged. Changes have been
+ directly interleaved below on the correct dates.
+
+2008-11-14 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (fis_lock): Revert patch of 2005-10-05 which disabled
+ locking entirely if FIS was disabled. Was better fixed by patch of
+ 2006-02-17.
+ (fis_list): Revert patch of 2007-04-03 to avoid skipping entries
+ at 0x0. Replaced by anoncvs patch of 2007-06-02 for consistency.
+
+2008-09-11 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/flash.c (fis_create, fis_write, fis_erase): Change alignment
+ test to cope with flash blocks that are not a power of 2 in size.
+
2008-06-18 Bart Veer <bartv@ecoscentric.com>
* src/fconfig.c, src/flash.c, src/io.c, src/load.c, src/main.c,
src/xyzModem.c, include/redboot.h: more signed vs. unsigned char
issues.
@@ -20,10 +40,15 @@
* src/io.c: Ditto.
* src/xyzModem.c: Ditto.
* src/load.c: Ditto.
* src/flash.c: Ditto.
+2007-11-21 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (fis_create): Allow length to be inferred if same
+ mem address given as prior load address.
+
2007-08-28 Gary Thomas <gary@mlbassoc.com>
* src/flash.c (do_flash_init): Memory allocation was slightly
incorrect - 'workspace_end' should always be used to find
the end of available memory.
@@ -56,15 +81,32 @@
* src/fs/fileio.c: Temporary kludge to treat flash correctly if either
flash v1 or flash v2 used with this file.
(do_mount): silence warning. Include accidentally omitted printf arg.
(do_list): silence warning.
+2007-04-03 Bart Veer <bartv@ecoscentric.com>
+
+ * src/flash.c (fis_list): don't skip entries at location 0x0
+
2007-01-22 Peter Korsgaard <peter.korsgaard@barco.com>
* src/load.c (do_load): Reset entry address before load so
go/exec commands will fail after an incomplete upload.
+2006-12-18 John Dallaway <jld@ecoscentric.com>
+
+ * src/flash.c, src/fconfig.c: Eliminate some compiler warnings.
+
+2006-12-06 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (find_free): When eliminating collapsed free chunks,
+ don't decrement num_chunks as a side effect every loop!
+
+2006-12-04 Bart Veer <bartv@ecoscentric.com>
+
+ * src/flash.c, src/main.c: eliminate some compiler warnings.
+
2006-11-28 David Fernandez <dfernandez@cct.co.uk>
* cdl/redboot.cdl: Modified to change the option
CYGDAT_REDBOOT_DEFAULT_NETWORK_DEVICE to make it independent of
CYGSEM_REDBOOT_FLASH_CONFIG, changes in net_io.c will allow to
@@ -82,10 +124,20 @@
2006-11-19 Andrew Lunn <lunn@laptop.lunn.ch>
* src/load.c: Only call valid_address() if
CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS is enabled.
+2006-11-01 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (fis_create): Ensure flash_addr is always inferred
+ to come from unused space if not set.
+
+2006-10-19 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (fis_create): If not copying, no reason to insist
+ on a flash address being set.
+
2006-09-06 Andrew Lunn <andrew.lunn@ascom.ch>
* cdl/redboot.cdl: Fix description of CYGSEM_REDBOOT_DISK_IDE.
Error pointed out by Wang Cui
@@ -96,10 +148,23 @@
2006-07-21 David Ho <davidkwho@gmail.com>
* src/flash.c (fis_start_update_directory): Fix build error when
redundant FIS selected and locking is not enabled/supported.
+2006-06-16 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/flash.c (flash_reserved): Value for the macro used when this
+ feature is disabled should be false not true.
+
+2006-06-09 Nick Garnett <nickg@ecoscentric.com>
+
+ * cdl/redboot.cdl:
+ * src/flash.c (flash_reserved): Added config option,
+ CYGNUM_REDBOOT_FLASH_RESERVED_DEVICES, and code to check for a
+ list of reserved flash devices that should not be used for FIS
+ file allocation.
+
2006-05-24 Gary Thomas <gary@mlbassoc.com>
* src/net/net_io.c (do_ip_addr): Bail out if no networking.
2006-05-23 Gary Thomas <gary@mlbassoc.com>
@@ -127,10 +192,28 @@
2006-03-27 Gary Thomas <gary@mlbassoc.com>
* src/net/tcp.c (__tcp_write_block): Fix calculation of actual
total number of bytes sent (from Wolfgang Koebler)
+2006-03-21 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (find_free): Fix typo in last change.
+
+2006-03-16 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (find_free): Fix indentation.
+ Trivial optimisation when free chunk collapsed.
+ When splitting chunks, be sure to insert not overwrite - there may be
+ a subsequent free chunk.
+ Even if out of free chunks when splitting, be sure to mark end of this
+ chunk as used, to avoid it inappropriately being reported as free.
+
+2006-03-10 Bart Veer <bartv@ecoscentric.com>
+
+ * src/flash.c (find_free): fix boundary condition when an fis img
+ is right at the end of memory.
+
2006-02-25 Oliver Munz <munz@speag.ch>
Andrew Lunn <andrew.lunn@ascom.ch>
* src/xyzModem.c (xyzModem_stream_open): Fix compiler warnings.
* src/flash_load.c (NEW): Implements access to flash
@@ -151,18 +234,62 @@
* src/flash.c (fis_lock & fis_unlock): Allow compilation without
FIS being enabled.
* src/flash.c (fis_update_directory): When reading/writing flash
use the full size of the fis directory, not just one block.
+2006-01-26 John Dallaway <jld@ecoscentric.com>
+
+ * src/flash.c (_flash_info): Tidy presentation of flash block info.
+
+2006-01-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (fis_init): Default data_length = FIS partition
+ size for special partitions.
+
+2005-12-22 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (find_free): adjust base only for appropriate device.
+ (fis_free): Fix up case for !CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS
+ to correctly scan for blank regions.
+ Remove obsolete version of same.
+ (fis_find_free): Adapt fis_free changes for this.
+
+2005-12-12 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (fis_free): Rewrite to improve support
+ for multiple flash devices. Still not really right - needs
+ wider changes.
+ (fis_find_free): Better support multiple flash devices.
+ Far from perfect yet though. Minor improvement on what
+ was there before though.
+
2005-11-23 Peter Korsgaard <peter.korsgaard@barco.com>
* src/gunzip.c (do_gunzip): Fixed diag_printf format string warnings.
2005-10-17 Gary Thomas <gary@mlbassoc.com>
* src/iomem.c (do_iopeek): Correct number of options.
+2005-10-05 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/flash.c: Changes to various ifdefs to allow FCONFIG to be
+ used independently of FIS. It was always intended that this be
+ possible, but over time it suffered a little bitrot.
+
+2005-09-30 Nick Garnett <nickg@ecoscentric.com>
+
+ * cdl/redboot.cdl: Move CYGNUM_REDBOOT_FLASH_BASE out of
+ CYGPKG_REDBOOT_FLASH component so that it can be used from RBL
+ when CYGPKG_REDBOOT_FLASH is disabled.
+
+2005-09-26 Bart Veer <bartv@ecoscentric.com>
+
+ * src/flash.c: put flag into .bss rather than .data, avoids
+ problems if soft reset involves branching to the entry point and
+ .data does not get reinitialized.
+
2005-09-13 Jonathan Larmour <jifl@eCosCentric.com>
* src/parse.c (redboot_exec): Conditionalise use of
__mem_fault_handler to only be when stubs are included.
(error_handler): Ditto for this function.
@@ -309,25 +436,39 @@
* src/alias.c (lookup_alias): Fix compiler warnings about formats
* src/cksum.c (do_cksum): Ditto
* src/dump.c (do_dump): Ditto
-2005-04-07 Peter Korsgaard <jacmet@sunsite.dk>
-
- * cdl/redboot.cdl, doc/redboot_cmds.sgml, src/gunzip.c: Added
- gunzip command to uncompress GZIP compressed data.
-
2005-04-11 Peter Korsgaard <jacmet@sunsite.dk>
* src/flash.c (find_free): Correctly split chunks in two when
not final chunk.
+2005-04-07 Peter Korsgaard <jacmet@sunsite.dk>
+
+ * cdl/redboot.cdl, doc/redboot_cmds.sgml, src/gunzip.c: Added
+ gunzip command to uncompress GZIP compressed data.
+
2005-03-07 Alexander Neundorf <alexander.neundorf@jenoptik.com>
* src/net/arp.c: use correct sizeof(rt->enet_addr) in
__arp_lookup()
+2005-02-17  Bart Veer  <bartv@ecoscentric.com>
+
+ * src/flash.c (fis_create): if -r is not specified, set the ram
+ base address in the fis directory to the current load address.
+ This assumes the data is currently in the right place, as should
+ be the case after e.g. loading an elf executable.
+
+2005-02-11 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (find_free): Correct fis free calculations to account
+ for chunk regions ending 1 byte before fis fis regions.
+ (fis_find_free): Allow for difference of end from start being one
+ less than size of region.
+
2005-01-26 Nick Garnett <nickg@ecoscentric.com>
* src/fs/fileio.c (do_mkdir, do_deldir, do_del, do_write): Added
some extra argument checking to these functions.
@@ -380,10 +521,60 @@
commands.
* src/fs/fileio.c (do_write): Added O_TRUNC to the open call to
ensure that the file is resized to fit the new data.
+2004-11-24 Bart Veer <bartv@ecoscentric.com>
+
+ * Merge from flash V2 branch
+
+ 2004-11-21 Bart Veer <bartv@ecoscentric.com>
+
+ * src/flash.c (check_code_overlaps): cyg_flash_code_overlaps() has
+ been removed, so use a RedBoot-specific function instead
+
+ 2004-11-20 Bart Veer <bartv@ecoscentric.com>
+
+ * src/flash.c (do_flash_init): info.end already holds the last
+ flash byte, no need to adjust.
+
+ 2004-10-07 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/flash.c (do_flash_init): Fix compiler warning about an
+ unused variable.
+
+ 2004-10-06 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/flash.c (do_flash_init): We need info independent of
+ CYGNUM_REDBOOT_FLASH_BASE being set or not.
+
+ 2004-09-14 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/redboot.cdl: Change CYGNUM_REDBOOT_FLASH_BASE to a booldata
+ so we don't always look at address 0 for the flash!
+
+ 2004-08-21 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/flash.c (do_flash_init): cyg_flash_get_limits has been removed.
+ Reimplement this functionality using other calls.
+
+ 2004-08-13 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/redboot.cdl: Fixed the type of CYGNUM_REDBOOT_FLASH_BASE
+ * src/flash.c (fis_[un]lock): Fix compiler warnings
+
+ 2004-08-06 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/flash.c (do_flash_init): Removed the MIPS br0ken condition
+ which i wrongly added. My problem was actually a / 0. This roundup
+ is needed otherwise the workspace goes off the end of the RAM.
+
+ 2004-08-05 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/flash.c:
+ * src/fconfig.c: Make use of the new flash API.
+
2004-11-24 Nick Garnett <nickg@ecoscentric.com>
* src/fs/fileio.c: Significantly reorganized to present an
interface similar to the fis commands. Added a variety of command
to manipulate files and directories in a filesystem.
@@ -402,10 +593,15 @@
* src/net/net_io.c: Changed init priority to RedBoot_INIT_NET.
* include/redboot.h: Added some extra initialization
priorities. Added prototypes for redboot_exec() and err_printf().
+2004-11-11 Bart Veer <bartv@ecoscentric.com>
+
+ * src/flash.c (find_free): allow for flash blocks larger than the
+ RedBoot MIN_IMAGE_SIZE
+
2004-11-09 Ian Campbell <icampbell@arcom.com>
* cdl/redboot.cdl, doc/redboot_cmds.sgml, src/iomem.c: Add support
for iopeek and iopoke commands to allow access to the I/O regions.
@@ -416,10 +612,18 @@
* src/flash.c (find_free, fis_free, fis_find_free): Don't ignore
an extra CYGBLD_REDBOOT_MIN_IMAGE_SIZE amount from the start.
This fixes the case where nothing uses the start of flash.
+2004-11-05 John Dallaway <jld@ecoscentric.com>
+
+ * src/flash.c (fis_create): Eliminate MIPS compiler workaround
+ which causes problems with multiple use of flash blocks and appears
+ to be unnecessary with GCC 3.2.1.
+
+ * src/flash.c (fis_write): Eliminate MIPS compiler workaround.
+
2004-11-04 Peter Korsgaard <jacmet@sunsite.dk>
* src/fconfig.c (flash_write_config): Removed compiler warning
when building redboot with combined FIS and config.
@@ -524,10 +728,15 @@
* src/flash.c (find_free): fix endless loop when removing a
collapsed chunk from chunk table. Found by Laurent Gonzalez
(fis_load): Fixed a compiler warning.
+2004-06-11 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/flash.c (fis_create): Made unlock/lock operations dependent
+ on CYGHWR_IO_FLASH_BLOCK_LOCKING.
+
2004-05-31 Jani Monoses <jani@iv.ro>
* src/main.c:
* include/redboot.h: Get rid of unused workspace_size.
@@ -539,10 +748,17 @@
2004-05-21 Ian Campbell <icampbell@arcom.com>
* src/main.c: Make it build without CYGSEM_REDBOOT_FLASH_ALIASES.
+2004-05-07 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/flash.c (fis_create): Added unlock and lock operations
+ around programming of flash region. Some flash parts power up with
+ all locks on, so we have to unlock, and we might as well play safe
+ and keep everything locked.
+
2004-05-05 Gary Thomas <gary@mlbassoc.com>
* src/flash.c (fis_load): CRC check on load was broken (the CDL
option changed names)
@@ -3918,10 +4134,11 @@
//===========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003, 2004, 2005, 2006, 2007, 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.
//
@@ -3941,11 +4158,8 @@
// 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####
//===========================================================================
Index: packages/redboot/current/cdl/redboot.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/cdl/redboot.cdl,v
retrieving revision 1.80
diff -u -5 -p -r1.80 redboot.cdl
--- packages/redboot/current/cdl/redboot.cdl 11 Nov 2008 04:32:10 -0000 1.80
+++ packages/redboot/current/cdl/redboot.cdl 18 Nov 2008 00:58:17 -0000
@@ -6,10 +6,11 @@
#
# ====================================================================
#####ECOSGPLCOPYRIGHTBEGIN####
## -------------------------------------------
## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2005, 2006, 2008 eCosCentric Limited
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
## Copyright (C) 2002, 2003, 2004, 2005 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
@@ -674,10 +675,20 @@ cdl_package CYGPKG_REDBOOT {
for a safer environment, but this check may not be valid
on all platforms, thus the ability to disable it.
** Disable this only with great care **"
}
+ cdl_option CYGNUM_REDBOOT_FLASH_BASE {
+ display "Base address of flash device redboot should use"
+ flavor booldata
+ description "
+ This option controls how redboot finds the flash
+ device. Setting this option to an address will
+ cause redboot to use that address as the base of the
+ flash device."
+ }
+
cdl_component CYGPKG_REDBOOT_FLASH {
display "Allow RedBoot to support FLASH programming"
flavor bool
default_value 1
active_if CYGHWR_IO_FLASH_DEVICE
@@ -893,10 +904,22 @@ cdl_package CYGPKG_REDBOOT {
FLASH where RedBoot will never interfere; it is
expected that this area contains
(non-RedBoot-based) POST code or some other boot
monitor that executes before RedBoot."
}
+
+ cdl_option CYGNUM_REDBOOT_FLASH_RESERVED_DEVICES {
+ display "List of Flash devices that are reserved"
+ flavor booldata
+ default_value 0
+ description "This option lists the base addresses of any Flash
+ devices that should not be managed by the flash
+ image system. In particular, this means that these
+ devices will not be considered when looking for free
+ space in which to create new files. It should consist
+ of a comma-separated list of (virtual) addresses."
+ }
}
cdl_option CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL {
display "Keep all RedBoot FLASH data blocks locked."
flavor bool
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [flashv2 merge] RedBoot
2008-11-18 1:00 [flashv2 merge] RedBoot Jonathan Larmour
@ 2008-11-18 1:32 ` Jonathan Larmour
0 siblings, 0 replies; 2+ messages in thread
From: Jonathan Larmour @ 2008-11-18 1:32 UTC (permalink / raw)
To: eCos Patches List
[-- Attachment #1: Type: text/plain, Size: 395 bytes --]
Jonathan Larmour wrote:
> With many eCosCentric updates. Attached.
Let's try again.... forgive me, it's late :).
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
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: flashv2.redboot.diff --]
[-- Type: text/x-patch; name="flashv2.redboot.diff", Size: 88775 bytes --]
Index: packages/redboot/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/ChangeLog,v
retrieving revision 1.259
retrieving revision 1.260
diff -u -5 -p -r1.259 -r1.260
--- packages/redboot/current/ChangeLog 11 Nov 2008 17:08:17 -0000 1.259
+++ packages/redboot/current/ChangeLog 18 Nov 2008 01:02:43 -0000 1.260
@@ -1,5 +1,25 @@
+2008-11-16 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/redboot.cdl, src/flash.c, src/fconfig.c:
+ Flash-related eCosCentric changes to these files (including a
+ merge of the flashv2 work) have been merged. Changes have been
+ directly interleaved below on the correct dates.
+
+2008-11-14 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (fis_lock): Revert patch of 2005-10-05 which disabled
+ locking entirely if FIS was disabled. Was better fixed by patch of
+ 2006-02-17.
+ (fis_list): Revert patch of 2007-04-03 to avoid skipping entries
+ at 0x0. Replaced by anoncvs patch of 2007-06-02 for consistency.
+
+2008-09-11 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/flash.c (fis_create, fis_write, fis_erase): Change alignment
+ test to cope with flash blocks that are not a power of 2 in size.
+
2008-06-18 Bart Veer <bartv@ecoscentric.com>
* src/fconfig.c, src/flash.c, src/io.c, src/load.c, src/main.c,
src/xyzModem.c, include/redboot.h: more signed vs. unsigned char
issues.
@@ -20,10 +40,15 @@
* src/io.c: Ditto.
* src/xyzModem.c: Ditto.
* src/load.c: Ditto.
* src/flash.c: Ditto.
+2007-11-21 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (fis_create): Allow length to be inferred if same
+ mem address given as prior load address.
+
2007-08-28 Gary Thomas <gary@mlbassoc.com>
* src/flash.c (do_flash_init): Memory allocation was slightly
incorrect - 'workspace_end' should always be used to find
the end of available memory.
@@ -56,15 +81,32 @@
* src/fs/fileio.c: Temporary kludge to treat flash correctly if either
flash v1 or flash v2 used with this file.
(do_mount): silence warning. Include accidentally omitted printf arg.
(do_list): silence warning.
+2007-04-03 Bart Veer <bartv@ecoscentric.com>
+
+ * src/flash.c (fis_list): don't skip entries at location 0x0
+
2007-01-22 Peter Korsgaard <peter.korsgaard@barco.com>
* src/load.c (do_load): Reset entry address before load so
go/exec commands will fail after an incomplete upload.
+2006-12-18 John Dallaway <jld@ecoscentric.com>
+
+ * src/flash.c, src/fconfig.c: Eliminate some compiler warnings.
+
+2006-12-06 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (find_free): When eliminating collapsed free chunks,
+ don't decrement num_chunks as a side effect every loop!
+
+2006-12-04 Bart Veer <bartv@ecoscentric.com>
+
+ * src/flash.c, src/main.c: eliminate some compiler warnings.
+
2006-11-28 David Fernandez <dfernandez@cct.co.uk>
* cdl/redboot.cdl: Modified to change the option
CYGDAT_REDBOOT_DEFAULT_NETWORK_DEVICE to make it independent of
CYGSEM_REDBOOT_FLASH_CONFIG, changes in net_io.c will allow to
@@ -82,10 +124,20 @@
2006-11-19 Andrew Lunn <lunn@laptop.lunn.ch>
* src/load.c: Only call valid_address() if
CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS is enabled.
+2006-11-01 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (fis_create): Ensure flash_addr is always inferred
+ to come from unused space if not set.
+
+2006-10-19 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (fis_create): If not copying, no reason to insist
+ on a flash address being set.
+
2006-09-06 Andrew Lunn <andrew.lunn@ascom.ch>
* cdl/redboot.cdl: Fix description of CYGSEM_REDBOOT_DISK_IDE.
Error pointed out by Wang Cui
@@ -96,10 +148,23 @@
2006-07-21 David Ho <davidkwho@gmail.com>
* src/flash.c (fis_start_update_directory): Fix build error when
redundant FIS selected and locking is not enabled/supported.
+2006-06-16 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/flash.c (flash_reserved): Value for the macro used when this
+ feature is disabled should be false not true.
+
+2006-06-09 Nick Garnett <nickg@ecoscentric.com>
+
+ * cdl/redboot.cdl:
+ * src/flash.c (flash_reserved): Added config option,
+ CYGNUM_REDBOOT_FLASH_RESERVED_DEVICES, and code to check for a
+ list of reserved flash devices that should not be used for FIS
+ file allocation.
+
2006-05-24 Gary Thomas <gary@mlbassoc.com>
* src/net/net_io.c (do_ip_addr): Bail out if no networking.
2006-05-23 Gary Thomas <gary@mlbassoc.com>
@@ -127,10 +192,28 @@
2006-03-27 Gary Thomas <gary@mlbassoc.com>
* src/net/tcp.c (__tcp_write_block): Fix calculation of actual
total number of bytes sent (from Wolfgang Koebler)
+2006-03-21 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (find_free): Fix typo in last change.
+
+2006-03-16 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (find_free): Fix indentation.
+ Trivial optimisation when free chunk collapsed.
+ When splitting chunks, be sure to insert not overwrite - there may be
+ a subsequent free chunk.
+ Even if out of free chunks when splitting, be sure to mark end of this
+ chunk as used, to avoid it inappropriately being reported as free.
+
+2006-03-10 Bart Veer <bartv@ecoscentric.com>
+
+ * src/flash.c (find_free): fix boundary condition when an fis img
+ is right at the end of memory.
+
2006-02-25 Oliver Munz <munz@speag.ch>
Andrew Lunn <andrew.lunn@ascom.ch>
* src/xyzModem.c (xyzModem_stream_open): Fix compiler warnings.
* src/flash_load.c (NEW): Implements access to flash
@@ -151,18 +234,62 @@
* src/flash.c (fis_lock & fis_unlock): Allow compilation without
FIS being enabled.
* src/flash.c (fis_update_directory): When reading/writing flash
use the full size of the fis directory, not just one block.
+2006-01-26 John Dallaway <jld@ecoscentric.com>
+
+ * src/flash.c (_flash_info): Tidy presentation of flash block info.
+
+2006-01-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (fis_init): Default data_length = FIS partition
+ size for special partitions.
+
+2005-12-22 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (find_free): adjust base only for appropriate device.
+ (fis_free): Fix up case for !CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS
+ to correctly scan for blank regions.
+ Remove obsolete version of same.
+ (fis_find_free): Adapt fis_free changes for this.
+
+2005-12-12 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (fis_free): Rewrite to improve support
+ for multiple flash devices. Still not really right - needs
+ wider changes.
+ (fis_find_free): Better support multiple flash devices.
+ Far from perfect yet though. Minor improvement on what
+ was there before though.
+
2005-11-23 Peter Korsgaard <peter.korsgaard@barco.com>
* src/gunzip.c (do_gunzip): Fixed diag_printf format string warnings.
2005-10-17 Gary Thomas <gary@mlbassoc.com>
* src/iomem.c (do_iopeek): Correct number of options.
+2005-10-05 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/flash.c: Changes to various ifdefs to allow FCONFIG to be
+ used independently of FIS. It was always intended that this be
+ possible, but over time it suffered a little bitrot.
+
+2005-09-30 Nick Garnett <nickg@ecoscentric.com>
+
+ * cdl/redboot.cdl: Move CYGNUM_REDBOOT_FLASH_BASE out of
+ CYGPKG_REDBOOT_FLASH component so that it can be used from RBL
+ when CYGPKG_REDBOOT_FLASH is disabled.
+
+2005-09-26 Bart Veer <bartv@ecoscentric.com>
+
+ * src/flash.c: put flag into .bss rather than .data, avoids
+ problems if soft reset involves branching to the entry point and
+ .data does not get reinitialized.
+
2005-09-13 Jonathan Larmour <jifl@eCosCentric.com>
* src/parse.c (redboot_exec): Conditionalise use of
__mem_fault_handler to only be when stubs are included.
(error_handler): Ditto for this function.
@@ -309,25 +436,39 @@
* src/alias.c (lookup_alias): Fix compiler warnings about formats
* src/cksum.c (do_cksum): Ditto
* src/dump.c (do_dump): Ditto
-2005-04-07 Peter Korsgaard <jacmet@sunsite.dk>
-
- * cdl/redboot.cdl, doc/redboot_cmds.sgml, src/gunzip.c: Added
- gunzip command to uncompress GZIP compressed data.
-
2005-04-11 Peter Korsgaard <jacmet@sunsite.dk>
* src/flash.c (find_free): Correctly split chunks in two when
not final chunk.
+2005-04-07 Peter Korsgaard <jacmet@sunsite.dk>
+
+ * cdl/redboot.cdl, doc/redboot_cmds.sgml, src/gunzip.c: Added
+ gunzip command to uncompress GZIP compressed data.
+
2005-03-07 Alexander Neundorf <alexander.neundorf@jenoptik.com>
* src/net/arp.c: use correct sizeof(rt->enet_addr) in
__arp_lookup()
+2005-02-17  Bart Veer  <bartv@ecoscentric.com>
+
+ * src/flash.c (fis_create): if -r is not specified, set the ram
+ base address in the fis directory to the current load address.
+ This assumes the data is currently in the right place, as should
+ be the case after e.g. loading an elf executable.
+
+2005-02-11 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash.c (find_free): Correct fis free calculations to account
+ for chunk regions ending 1 byte before fis fis regions.
+ (fis_find_free): Allow for difference of end from start being one
+ less than size of region.
+
2005-01-26 Nick Garnett <nickg@ecoscentric.com>
* src/fs/fileio.c (do_mkdir, do_deldir, do_del, do_write): Added
some extra argument checking to these functions.
@@ -380,10 +521,60 @@
commands.
* src/fs/fileio.c (do_write): Added O_TRUNC to the open call to
ensure that the file is resized to fit the new data.
+2004-11-24 Bart Veer <bartv@ecoscentric.com>
+
+ * Merge from flash V2 branch
+
+ 2004-11-21 Bart Veer <bartv@ecoscentric.com>
+
+ * src/flash.c (check_code_overlaps): cyg_flash_code_overlaps() has
+ been removed, so use a RedBoot-specific function instead
+
+ 2004-11-20 Bart Veer <bartv@ecoscentric.com>
+
+ * src/flash.c (do_flash_init): info.end already holds the last
+ flash byte, no need to adjust.
+
+ 2004-10-07 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/flash.c (do_flash_init): Fix compiler warning about an
+ unused variable.
+
+ 2004-10-06 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/flash.c (do_flash_init): We need info independent of
+ CYGNUM_REDBOOT_FLASH_BASE being set or not.
+
+ 2004-09-14 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/redboot.cdl: Change CYGNUM_REDBOOT_FLASH_BASE to a booldata
+ so we don't always look at address 0 for the flash!
+
+ 2004-08-21 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/flash.c (do_flash_init): cyg_flash_get_limits has been removed.
+ Reimplement this functionality using other calls.
+
+ 2004-08-13 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/redboot.cdl: Fixed the type of CYGNUM_REDBOOT_FLASH_BASE
+ * src/flash.c (fis_[un]lock): Fix compiler warnings
+
+ 2004-08-06 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/flash.c (do_flash_init): Removed the MIPS br0ken condition
+ which i wrongly added. My problem was actually a / 0. This roundup
+ is needed otherwise the workspace goes off the end of the RAM.
+
+ 2004-08-05 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/flash.c:
+ * src/fconfig.c: Make use of the new flash API.
+
2004-11-24 Nick Garnett <nickg@ecoscentric.com>
* src/fs/fileio.c: Significantly reorganized to present an
interface similar to the fis commands. Added a variety of command
to manipulate files and directories in a filesystem.
@@ -402,10 +593,15 @@
* src/net/net_io.c: Changed init priority to RedBoot_INIT_NET.
* include/redboot.h: Added some extra initialization
priorities. Added prototypes for redboot_exec() and err_printf().
+2004-11-11 Bart Veer <bartv@ecoscentric.com>
+
+ * src/flash.c (find_free): allow for flash blocks larger than the
+ RedBoot MIN_IMAGE_SIZE
+
2004-11-09 Ian Campbell <icampbell@arcom.com>
* cdl/redboot.cdl, doc/redboot_cmds.sgml, src/iomem.c: Add support
for iopeek and iopoke commands to allow access to the I/O regions.
@@ -416,10 +612,18 @@
* src/flash.c (find_free, fis_free, fis_find_free): Don't ignore
an extra CYGBLD_REDBOOT_MIN_IMAGE_SIZE amount from the start.
This fixes the case where nothing uses the start of flash.
+2004-11-05 John Dallaway <jld@ecoscentric.com>
+
+ * src/flash.c (fis_create): Eliminate MIPS compiler workaround
+ which causes problems with multiple use of flash blocks and appears
+ to be unnecessary with GCC 3.2.1.
+
+ * src/flash.c (fis_write): Eliminate MIPS compiler workaround.
+
2004-11-04 Peter Korsgaard <jacmet@sunsite.dk>
* src/fconfig.c (flash_write_config): Removed compiler warning
when building redboot with combined FIS and config.
@@ -524,10 +728,15 @@
* src/flash.c (find_free): fix endless loop when removing a
collapsed chunk from chunk table. Found by Laurent Gonzalez
(fis_load): Fixed a compiler warning.
+2004-06-11 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/flash.c (fis_create): Made unlock/lock operations dependent
+ on CYGHWR_IO_FLASH_BLOCK_LOCKING.
+
2004-05-31 Jani Monoses <jani@iv.ro>
* src/main.c:
* include/redboot.h: Get rid of unused workspace_size.
@@ -539,10 +748,17 @@
2004-05-21 Ian Campbell <icampbell@arcom.com>
* src/main.c: Make it build without CYGSEM_REDBOOT_FLASH_ALIASES.
+2004-05-07 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/flash.c (fis_create): Added unlock and lock operations
+ around programming of flash region. Some flash parts power up with
+ all locks on, so we have to unlock, and we might as well play safe
+ and keep everything locked.
+
2004-05-05 Gary Thomas <gary@mlbassoc.com>
* src/flash.c (fis_load): CRC check on load was broken (the CDL
option changed names)
@@ -3918,10 +4134,11 @@
//===========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003, 2004, 2005, 2006, 2007, 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.
//
@@ -3941,11 +4158,8 @@
// 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####
//===========================================================================
Index: packages/redboot/current/cdl/redboot.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/cdl/redboot.cdl,v
retrieving revision 1.80
retrieving revision 1.81
diff -u -5 -p -r1.80 -r1.81
--- packages/redboot/current/cdl/redboot.cdl 11 Nov 2008 04:32:10 -0000 1.80
+++ packages/redboot/current/cdl/redboot.cdl 18 Nov 2008 01:02:44 -0000 1.81
@@ -6,10 +6,11 @@
#
# ====================================================================
#####ECOSGPLCOPYRIGHTBEGIN####
## -------------------------------------------
## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2005, 2006, 2008 eCosCentric Limited
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
## Copyright (C) 2002, 2003, 2004, 2005 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
@@ -674,10 +675,20 @@ cdl_package CYGPKG_REDBOOT {
for a safer environment, but this check may not be valid
on all platforms, thus the ability to disable it.
** Disable this only with great care **"
}
+ cdl_option CYGNUM_REDBOOT_FLASH_BASE {
+ display "Base address of flash device redboot should use"
+ flavor booldata
+ description "
+ This option controls how redboot finds the flash
+ device. Setting this option to an address will
+ cause redboot to use that address as the base of the
+ flash device."
+ }
+
cdl_component CYGPKG_REDBOOT_FLASH {
display "Allow RedBoot to support FLASH programming"
flavor bool
default_value 1
active_if CYGHWR_IO_FLASH_DEVICE
@@ -893,10 +904,22 @@ cdl_package CYGPKG_REDBOOT {
FLASH where RedBoot will never interfere; it is
expected that this area contains
(non-RedBoot-based) POST code or some other boot
monitor that executes before RedBoot."
}
+
+ cdl_option CYGNUM_REDBOOT_FLASH_RESERVED_DEVICES {
+ display "List of Flash devices that are reserved"
+ flavor booldata
+ default_value 0
+ description "This option lists the base addresses of any Flash
+ devices that should not be managed by the flash
+ image system. In particular, this means that these
+ devices will not be considered when looking for free
+ space in which to create new files. It should consist
+ of a comma-separated list of (virtual) addresses."
+ }
}
cdl_option CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL {
display "Keep all RedBoot FLASH data blocks locked."
flavor bool
Index: packages/redboot/current/src/fconfig.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/src/fconfig.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -5 -p -r1.14 -r1.15
--- 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:28:12 -0000 1.15
@@ -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
retrieving revision 1.85
diff -u -5 -p -r1.84 -r1.85
--- 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:28:12 -0000 1.85
@@ -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));
}
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2008-11-18 1:32 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-11-18 1:00 [flashv2 merge] RedBoot Jonathan Larmour
2008-11-18 1:32 ` Jonathan Larmour
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).