[ECOS] Supporting Paged Flash in eCos/RedBoot
Ian Campbell
icampbell@arcom.com
Fri Feb 21 14:08:00 GMT 2003
Hi,
Attached is a rough first draft of a patch to implement an improved
flash interface -- It's a first pass and I certainly wouldn't expect you
to apply it as is...
The main bulk of the patch modifies the API of cyg/io/flash.h such that
each function takes a struct flash_info * as it's first parameter and
all addresses are described as unsigned long offsets rather than literal
addresses. I have added flash_read as well. It also modifies the redboot
flash support to use the new API as well as the strataflash driver.
I have tested the modified strata flash driver, and fis and fconfig seem
to work OK, either separatly or using the combined fis and config CDL
option. I haven't got the readonly fallback working as yet. The strata
flash changes also make use of FLASH_READ and FLASH_WRITE macros, but
these are just an interim solution to support paged flash and are mostly
orthogonal to the issue of improving the flash API.
Older drivers which do not define the CYGHWR_IO_FLASH_DEVICE_V2 symbol
should still work just fine. I was able to compile RedBoot for one of
our other boards which has linear AMD flash and another which uses the
intel/28fxxxx driver but I haven't had a chance to actually run either
yet.
There's quite a few rough edges, but I hope you can see the general path
I am taking. Eventually I would like to add a Flash device table (like
the net device table) and add a flash_open("string") command to get the
flash_info pointer.
So, comments?
Ian.
--
Ian Campbell
Design Engineer
Arcom Control Systems Ltd, Direct: +44 (0)1223 403465
Clifton Road, Phone: +44 (0)1223 411 200
Cambridge CB1 7EA E-Mail: icampbell@arcom.com
United Kingdom Web: http://www.arcom.com
________________________________________________________________________
This email has been scanned for all viruses by the MessageLabs SkyScan
service. For more information on a proactive anti-virus service working
around the clock, around the globe, visit http://www.messagelabs.com
________________________________________________________________________
-------------- next part --------------
Index: devs/flash/intel/strata/current/cdl/flash_strata.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/intel/strata/current/cdl/flash_strata.cdl,v
retrieving revision 1.5
diff -u -b -B -w -p -u -r1.5 flash_strata.cdl
--- devs/flash/intel/strata/current/cdl/flash_strata.cdl 23 May 2002 23:01:02 -0000 1.5
+++ devs/flash/intel/strata/current/cdl/flash_strata.cdl 21 Feb 2003 13:33:53 -0000
@@ -55,6 +55,7 @@ cdl_package CYGPKG_DEVS_FLASH_STRATA {
parent CYGPKG_IO_FLASH
active_if CYGPKG_IO_FLASH
+ implements CYGHWR_IO_FLASH_DEVICE_V2
implements CYGHWR_IO_FLASH_DEVICE
# implements CYGHWR_IO_FLASH_DEVICE_NOT_IN_RAM
Index: devs/flash/intel/strata/current/src/flash_erase_block.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/intel/strata/current/src/flash_erase_block.c,v
retrieving revision 1.4
diff -u -b -B -w -p -u -r1.4 flash_erase_block.c
--- devs/flash/intel/strata/current/src/flash_erase_block.c 23 May 2002 23:01:02 -0000 1.4
+++ devs/flash/intel/strata/current/src/flash_erase_block.c 21 Feb 2003 13:33:53 -0000
@@ -56,19 +56,19 @@
#include <cyg/hal/hal_arch.h>
#include <cyg/hal/hal_cache.h>
+#include <cyg/io/flash.h>
+
//
// CAUTION! This code must be copied to RAM before execution. Therefore,
// it must not contain any code which might be position dependent!
//
-
-int flash_erase_block(volatile flash_t *block, unsigned int block_size)
+int flash_erase_block(struct flash_info *flash_info, unsigned long block, unsigned int block_size)
{
- volatile flash_t *ROM;
flash_t stat = 0;
int timeout = 50000;
int cache_on;
int len, block_len, erase_block_size;
- volatile flash_t *eb;
+ unsigned long eb = block;
HAL_DCACHE_IS_ENABLED(cache_on);
if (cache_on) {
@@ -77,8 +77,6 @@ int flash_erase_block(volatile flash_t *
}
// Get base address and map addresses to virtual addresses
- ROM = FLASH_P2V(CYGNUM_FLASH_BASE_MASK & (unsigned int)block);
- eb = block = FLASH_P2V(block);
block_len = block_size;
#ifdef CYGOPT_FLASH_IS_BOOTBLOCK
@@ -95,29 +93,34 @@ int flash_erase_block(volatile flash_t *
#endif
// Clear any error conditions
- ROM[0] = FLASH_Clear_Status;
+ //HAL_FLASH_WRITE(0, FLASH_Clear_Status);
+ HAL_FLASH_WRITE(0, FLASH_Reset);
// Erase block
while (block_len > 0) {
- ROM[0] = FLASH_Block_Erase;
- *eb = FLASH_Confirm;
+ HAL_FLASH_WRITE(eb, FLASH_Block_Erase);
+ HAL_FLASH_WRITE(eb, FLASH_Confirm);
timeout = 5000000;
- while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ HAL_FLASH_READ(0, stat);
+ while((stat & FLASH_Status_Ready) != FLASH_Status_Ready) {
if (--timeout == 0) break;
+ HAL_FLASH_READ(0, stat);
}
block_len -= erase_block_size;
- eb = FLASH_P2V((unsigned int)eb + erase_block_size);
+ eb = eb + erase_block_size;
}
// Restore ROM to "normal" mode
- ROM[0] = FLASH_Reset;
+ HAL_FLASH_WRITE(0, FLASH_Reset);
// If an error was reported, see if the block erased anyway
if (stat & FLASH_ErrorMask ) {
len = block_size;
while (len > 0) {
- if (*block++ != FLASH_BlankValue ) break;
- len -= sizeof(*block);
+ flash_t t;
+ HAL_FLASH_READ(len, t);
+ if (t != FLASH_BlankValue ) break;
+ len -= sizeof(t);
}
if (len == 0) stat = 0;
}
Index: devs/flash/intel/strata/current/src/flash_lock_block.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/intel/strata/current/src/flash_lock_block.c,v
retrieving revision 1.3
diff -u -b -B -w -p -u -r1.3 flash_lock_block.c
--- devs/flash/intel/strata/current/src/flash_lock_block.c 23 May 2002 23:01:02 -0000 1.3
+++ devs/flash/intel/strata/current/src/flash_lock_block.c 21 Feb 2003 13:33:53 -0000
@@ -54,23 +54,20 @@
#include <cyg/hal/hal_cache.h>
+#include <cyg/io/flash.h>
+
//
// CAUTION! This code must be copied to RAM before execution. Therefore,
// it must not contain any code which might be position dependent!
//
int
-flash_lock_block(volatile flash_t *block)
+flash_lock_block(struct flash_info *flash_info, unsigned long block)
{
- volatile flash_t *ROM;
flash_t stat;
int timeout = 5000000;
int cache_on;
- // Get base address and map addresses to virtual addresses
- ROM = FLASH_P2V(CYGNUM_FLASH_BASE_MASK & (unsigned int)block);
- block = FLASH_P2V(block);
-
HAL_DCACHE_IS_ENABLED(cache_on);
if (cache_on) {
HAL_DCACHE_SYNC();
@@ -78,17 +75,18 @@ flash_lock_block(volatile flash_t *block
}
// Clear any error conditions
- ROM[0] = FLASH_Clear_Status;
+ HAL_FLASH_WRITE(0, FLASH_Clear_Status);
// Set lock bit
- block[0] = FLASH_Set_Lock;
- block[0] = FLASH_Set_Lock_Confirm; // Confirmation
- while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ HAL_FLASH_WRITE(block, FLASH_Set_Lock);
+ HAL_FLASH_WRITE(block, FLASH_Set_Lock_Confirm); // Confirmation
+ HAL_FLASH_READ(0, stat);
+ while((stat & FLASH_Status_Ready) != FLASH_Status_Ready) {
if (--timeout == 0) break;
}
// Restore ROM to "normal" mode
- ROM[0] = FLASH_Reset;
+ HAL_FLASH_WRITE(0, FLASH_Reset);
if (cache_on) {
HAL_DCACHE_ENABLE();
Index: devs/flash/intel/strata/current/src/flash_program_buf.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/intel/strata/current/src/flash_program_buf.c,v
retrieving revision 1.6
diff -u -b -B -w -p -u -r1.6 flash_program_buf.c
--- devs/flash/intel/strata/current/src/flash_program_buf.c 23 May 2002 23:01:02 -0000 1.6
+++ devs/flash/intel/strata/current/src/flash_program_buf.c 21 Feb 2003 13:33:53 -0000
@@ -53,6 +53,9 @@
#include "strata.h"
#include <pkgconf/hal.h>
+
+#include <cyg/io/flash.h>
+
#include <cyg/hal/hal_arch.h>
#include <cyg/hal/hal_cache.h>
@@ -62,17 +65,17 @@
//
int
-flash_program_buf(volatile flash_t *addr, flash_t *data, int len,
+flash_program_buf(struct flash_info *flash_info,
+ unsigned long offset, flash_t *data, int len,
unsigned long block_mask, int buffer_size)
{
- volatile flash_t *ROM;
- volatile flash_t *BA;
flash_t stat = 0;
int timeout = 50000;
int cache_on;
#ifdef FLASH_Write_Buffer
int i, wc;
#endif
+ unsigned long BA;
HAL_DCACHE_IS_ENABLED(cache_on);
if (cache_on) {
@@ -80,13 +83,11 @@ flash_program_buf(volatile flash_t *addr
HAL_DCACHE_DISABLE();
}
- // Get base address and map addresses to virtual addresses
- ROM = FLASH_P2V( CYGNUM_FLASH_BASE_MASK & (unsigned int)addr );
- BA = FLASH_P2V( block_mask & (unsigned int)addr );
- addr = FLASH_P2V(addr);
+ // Get base address
+ BA = block_mask & offset;
// Clear any error conditions
- ROM[0] = FLASH_Clear_Status;
+ HAL_FLASH_WRITE(0, FLASH_Clear_Status);
#ifdef FLASH_Write_Buffer
// Write any big chunks first
@@ -96,30 +97,36 @@ flash_program_buf(volatile flash_t *addr
len -= wc;
// convert 'wc' in bytes to 'wc' in 'flash_t'
wc = wc / sizeof(flash_t); // Word count
- *BA = FLASH_Write_Buffer;
+
+ HAL_FLASH_WRITE(BA, FLASH_Write_Buffer);
timeout = 5000000;
- while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ HAL_FLASH_READ(0, stat);
+ while((stat & FLASH_Status_Ready) != FLASH_Status_Ready) {
if (--timeout == 0) {
goto bad;
}
- *BA = FLASH_Write_Buffer;
+ HAL_FLASH_WRITE(BA, FLASH_Write_Buffer);
+ HAL_FLASH_READ(0, stat);
}
- *BA = FLASHWORD(wc-1); // Count is 0..N-1
+ HAL_FLASH_WRITE(BA, FLASHWORD(wc-1)); // Count is 0..N-1
for (i = 0; i < wc; i++) {
#ifdef CYGHWR_FLASH_WRITE_ELEM
- CYGHWR_FLASH_WRITE_ELEM(addr+i, data+i);
+ CYGHWR_FLASH_WRITE_ELEM(offset+i, data+i));
#else
- *(addr+i) = *(data+i);
+ HAL_FLASH_WRITE(offset + i*sizeof(flash_t), *(data+i));
#endif
}
- *BA = FLASH_Confirm;
+ HAL_FLASH_WRITE(BA, FLASH_Confirm);
- ROM[0] = FLASH_Read_Status;
+ HAL_FLASH_WRITE(00, FLASH_Read_Status);
timeout = 5000000;
- while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+
+ HAL_FLASH_READ(0, stat);
+ while((stat & FLASH_Status_Ready) != FLASH_Status_Ready) {
if (--timeout == 0) {
goto bad;
}
+ HAL_FLASH_READ(0, stat);
}
// Jump out if there was an error
if (stat & FLASH_ErrorMask) {
@@ -125,35 +132,46 @@ flash_program_buf(volatile flash_t *addr
if (stat & FLASH_ErrorMask) {
goto bad;
}
+
// And verify the data - also increments the pointers.
- *BA = FLASH_Reset;
+ HAL_FLASH_WRITE(BA, FLASH_Reset);
for (i = 0; i < wc; i++) {
- if ( *addr++ != *data++ ) {
+ flash_t verf;
+ HAL_FLASH_READ(offset, verf);
+ if ( verf != *data ) {
stat = FLASH_ErrorNotVerified;
goto bad;
}
+ offset += sizeof(flash_t);
+ data++;
}
}
#endif
while (len > 0) {
- ROM[0] = FLASH_Program;
+ flash_t verf;
+
+ HAL_FLASH_WRITE(0, FLASH_Program);
#ifdef CYGHWR_FLASH_WRITE_ELEM
CYGHWR_FLASH_WRITE_ELEM(addr, data);
#else
- *addr = *data;
+ HAL_FLASH_WRITE(offset, (*data));
#endif
timeout = 5000000;
- while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ HAL_FLASH_READ(0, stat);
+ while((stat & FLASH_Status_Ready) != FLASH_Status_Ready) {
if (--timeout == 0) {
goto bad;
}
+ HAL_FLASH_READ(0, stat);
}
if (stat & FLASH_ErrorMask) {
break;
}
- ROM[0] = FLASH_Reset;
- if (*addr++ != *data++) {
+ HAL_FLASH_WRITE(0, FLASH_Reset);
+ HAL_FLASH_READ(offset, verf);
+ offset += sizeof(flash_t);
+ if (verf != *data++) {
stat = FLASH_ErrorNotVerified;
break;
}
@@ -162,7 +180,7 @@ flash_program_buf(volatile flash_t *addr
// Restore ROM to "normal" mode
bad:
- ROM[0] = FLASH_Reset;
+ HAL_FLASH_WRITE(0, FLASH_Reset);
if (cache_on) {
HAL_DCACHE_ENABLE();
Index: devs/flash/intel/strata/current/src/flash_query.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/intel/strata/current/src/flash_query.c,v
retrieving revision 1.4
diff -u -b -B -w -p -u -r1.4 flash_query.c
--- devs/flash/intel/strata/current/src/flash_query.c 23 May 2002 23:01:02 -0000 1.4
+++ devs/flash/intel/strata/current/src/flash_query.c 21 Feb 2003 13:33:53 -0000
@@ -57,19 +57,21 @@
#include <cyg/hal/hal_cache.h>
#include CYGHWR_MEMORY_LAYOUT_H
+#include <cyg/io/flash.h>
+
//
// CAUTION! This code must be copied to RAM before execution. Therefore,
// it must not contain any code which might be position dependent!
-//
+// i.e. don't call diag_printf.
#define CNT 20*1000*10 // Approx 20ms
int
-flash_query(unsigned char *data)
+flash_query(struct flash_info *flash_info, unsigned char *data)
{
- volatile flash_t *ROM;
- int i, cnt;
+ int i, cnt, offset;
int cache_on;
+ flash_t tmp;
HAL_DCACHE_IS_ENABLED(cache_on);
if (cache_on) {
@@ -78,36 +80,38 @@ flash_query(unsigned char *data)
}
// Get base address and map addresses to virtual addresses
- ROM = FLASH_P2V( CYGNUM_FLASH_BASE );
#ifdef CYGOPT_FLASH_IS_BOOTBLOCK
// BootBlock flash does not support full Read_Query - we have do a
// table oriented thing above, after getting just two bytes of results:
- ROM[0] = FLASH_Read_ID;
+ HAL_FLASH_WRITE(0, FLASH_Read_ID);
i = 2;
#else
// StrataFlash supports the full Read_Query op:
- ROM[0] = FLASH_Read_Query;
+ HAL_FLASH_WRITE(0, FLASH_Read_Query);
i = sizeof(struct FLASH_query);
#endif // Not CYGOPT_FLASH_IS_BOOTBLOCK
for (cnt = CNT; cnt > 0; cnt--) ;
+ offset = 0;
for ( /* i */; i > 0; i-- ) {
// It is very deliberate that data is chars NOT flash_t:
// The info comes out in bytes regardless of device.
- *data++ = (unsigned char) (*ROM++);
+ HAL_FLASH_READ(offset, tmp);
+ *data++ = (unsigned char)tmp;
+ offset += sizeof(flash_t) / sizeof (unsigned char);
#ifndef CYGOPT_FLASH_IS_BOOTBLOCK
# if 8 == CYGNUM_FLASH_WIDTH
// strata flash with 'byte-enable' contains the configuration data
// at even addresses
- ++ROM;
+ ++offset;
# endif
#endif
}
- ROM[0] = FLASH_Reset;
+ HAL_FLASH_WRITE(0, FLASH_Reset);
if (cache_on) {
HAL_DCACHE_ENABLE();
}
- return 0;
+ return;
}
Index: devs/flash/intel/strata/current/src/flash_unlock_block.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/intel/strata/current/src/flash_unlock_block.c,v
retrieving revision 1.4
diff -u -b -B -w -p -u -r1.4 flash_unlock_block.c
--- devs/flash/intel/strata/current/src/flash_unlock_block.c 12 Aug 2002 12:20:50 -0000 1.4
+++ devs/flash/intel/strata/current/src/flash_unlock_block.c 21 Feb 2003 13:33:53 -0000
@@ -52,6 +52,8 @@
#include "strata.h"
+#include <cyg/io/flash.h>
+
#include <cyg/hal/hal_cache.h>
//
@@ -70,15 +72,14 @@
#define MAX_FLASH_BLOCKS 128
int
-flash_unlock_block(volatile flash_t *block, int block_size, int blocks)
+flash_unlock_block(struct flash_info *flash_info, unsigned long block, unsigned long block_size, int blocks)
{
- volatile flash_t *ROM;
flash_t stat;
int timeout = 5000000;
int cache_on;
#ifndef CYGOPT_FLASH_IS_SYNCHRONOUS
int i;
- volatile flash_t *bp, *bpv;
+ unsigned long bp;
unsigned char is_locked[MAX_FLASH_BLOCKS];
#endif
@@ -88,65 +89,72 @@ flash_unlock_block(volatile flash_t *blo
HAL_DCACHE_DISABLE();
}
- // Get base address and map addresses to virtual addresses
- ROM = FLASH_P2V( CYGNUM_FLASH_BASE_MASK & (unsigned int)block );
- block = FLASH_P2V(block);
-
// Clear any error conditions
- ROM[0] = FLASH_Clear_Status;
+ HAL_FLASH_WRITE(0, FLASH_Clear_Status);
#ifdef CYGOPT_FLASH_IS_SYNCHRONOUS
// Clear lock bit
- block[0] = FLASH_Clear_Locks;
- block[0] = FLASH_Clear_Locks_Confirm; // Confirmation
- while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ HAL_FLASH_WRITE(block, FLASH_Clear_Locks);
+ HAL_FLASH_WRITE(block, FLASH_Clear_Locks_Confirm); // Confirmation
+ HAL_FLASH_READ(0, stat);
+ while((stat & FLASH_Status_Ready) != FLASH_Status_Ready) {
if (--timeout == 0) break;
+ HAL_FLASH_READ(0, stat);
}
#else
// Get current block lock state. This needs to access each block on
// the device so currently locked blocks can be re-locked.
- bp = ROM;
- for (i = 0; i < blocks; i++) {
- bpv = FLASH_P2V( bp );
- *bpv = FLASH_Read_Query;
- if (bpv == block) {
- is_locked[i] = 0;
- } else {
+ bp = 0;
+ for (i = 0; i < ( blocks / CYGNUM_FLASH_BANKS ); i++) {
+ HAL_FLASH_WRITE(bp, FLASH_Read_Query);
+#warning NOT SURE THIS IS CORRECT -- IJC
+ HAL_FLASH_READ(bp+4, is_locked[i]);
+#if 0
#if 8 == CYGNUM_FLASH_WIDTH
- is_locked[i] = bpv[4];
+ HAL_FLASH_READ(bp+4, is_locked[i]);
#else
- is_locked[i] = bpv[2];
+ HAL_FLASH_READ(bp+2, is_locked[i]);
+#endif
# endif
+ if (bp == block) {
+ is_locked[i] = 0;
}
- bp += block_size / sizeof(*bp);
+ bp += block_size;
}
// Clears all lock bits
- ROM[0] = FLASH_Clear_Locks;
- ROM[0] = FLASH_Clear_Locks_Confirm; // Confirmation
+ HAL_FLASH_WRITE(0, FLASH_Clear_Locks);
+ HAL_FLASH_WRITE(0, FLASH_Clear_Locks_Confirm); // Confirmation
timeout = 5000000;
- while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ HAL_FLASH_READ(0, stat);
+ while((stat & FLASH_Status_Ready) != FLASH_Status_Ready) {
if (--timeout == 0) break;
+ HAL_FLASH_READ(0, stat);
}
+#if 0
// Restore the lock state
- bp = ROM;
- for (i = 0; i < blocks; i++) {
- bpv = FLASH_P2V( bp );
+ bp = 0;
+ for (i = 0; i < ( blocks / CYGNUM_FLASH_BANKS ); i++) {
if (is_locked[i]) {
- *bpv = FLASH_Set_Lock;
- *bpv = FLASH_Set_Lock_Confirm; // Confirmation
+ diag_printf("Locking: %p\n", bp);
+ HAL_FLASH_WRITE(bp, FLASH_Set_Lock);
+ HAL_FLASH_WRITE(bp, FLASH_Set_Lock_Confirm); // Confirmation
timeout = 5000000;
- while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ HAL_FLASH_READ(0, stat);
+ while((stat & FLASH_Status_Ready) != FLASH_Status_Ready) {
if (--timeout == 0) break;
+ HAL_FLASH_READ(0, stat);
}
}
- bp += block_size / sizeof(*bp);
+ bp += block_size;
}
+#endif
+
#endif // CYGOPT_FLASH_IS_SYNCHRONOUS
// Restore ROM to "normal" mode
- ROM[0] = FLASH_Reset;
+ HAL_FLASH_WRITE(0, FLASH_Reset);
if (cache_on) {
HAL_DCACHE_ENABLE();
Index: devs/flash/intel/strata/current/src/strata.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/intel/strata/current/src/strata.c,v
retrieving revision 1.7
diff -u -b -B -w -p -u -r1.7 strata.c
--- devs/flash/intel/strata/current/src/strata.c 23 May 2002 23:01:02 -0000 1.7
+++ devs/flash/intel/strata/current/src/strata.c 21 Feb 2003 13:33:53 -0000
@@ -67,31 +67,53 @@ extern void diag_dump_buf(void *buf, CYG
extern int strncmp(const char *s1, const char *s2, size_t len);
extern void *memcpy( void *, const void *, size_t );
+#ifndef CYGHWR_IO_FLASH_DEVICE_NOT_IN_RAM
+// Use this function to make function pointers anonymous - forcing the
+// compiler to use jumps instead of branches when calling driver
+// services.
+static void* __anonymizer(void* p)
+{
+ return p;
+}
+#endif
+
int
-flash_hwr_init(void)
+flash_hwr_init(struct flash_info *flash_info)
{
struct FLASH_query data, *qp;
- extern char flash_query[], flash_query_end[];
- typedef int code_fun(unsigned char *);
- code_fun *_flash_query;
- int code_len, stat, num_regions, region_size, buffer_size;
+ flash_query_func _flash_query;
+ int stat, num_regions, region_size, buffer_size;
int icache_on, dcache_on;
HAL_DCACHE_IS_ENABLED(dcache_on);
HAL_ICACHE_IS_ENABLED(icache_on);
// Copy 'program' code to RAM for execution
- code_len = (unsigned long)&flash_query_end - (unsigned long)&flash_query;
- _flash_query = (code_fun *)flash_info.work_space;
+
+#ifdef CYGHWR_IO_FLASH_DEVICE_NOT_IN_RAM
+ {
+ extern char flash_query[], flash_query_end[];
+ CYG_ADDRESS code_len;
+
+ // Copy 'query' code to RAM for execution
+ code_len = (CYG_ADDRESS)&flash_query_end - (CYG_ADDRESS)&flash_query;
+ _flash_query = (flash_query_func)flash_info->work_space;
memcpy(_flash_query, &flash_query, code_len);
+ }
+#else
+ {
+ externC flash_query_func flash_query;
+ _flash_query = (flash_query_func) __anonymizer(&flash_query);
+ }
+#endif
+
if (dcache_on) {
HAL_DCACHE_SYNC(); // Should guarantee this code will run
}
if (icache_on) {
HAL_ICACHE_DISABLE(); // is also required to avoid old contents
}
-
- stat = (*_flash_query)((unsigned char *)&data);
+ stat = (*_flash_query)(flash_info, (unsigned char *)&data);
if (icache_on) {
HAL_ICACHE_ENABLE();
}
@@ -138,30 +160,34 @@ flash_hwr_init(void)
}
#endif // Not CYGOPT_FLASH_IS_BOOTBLOCK
- flash_info.block_size = region_size*CYGNUM_FLASH_DEVICES;
- flash_info.buffer_size = buffer_size;
- flash_info.blocks = num_regions;
- flash_info.start = (void *)CYGNUM_FLASH_BASE;
- flash_info.end = (void *)(CYGNUM_FLASH_BASE +
- (num_regions*region_size*CYGNUM_FLASH_DEVICES));
-#ifdef CYGNUM_FLASH_BASE_MASK
+ flash_info->block_size = region_size*CYGNUM_FLASH_DEVICES;
+ flash_info->buffer_size = buffer_size;
+ flash_info->blocks = num_regions*CYGNUM_FLASH_BANKS;
+#if 0 // IJC
+ flash_info->start = (void *)CYGNUM_FLASH_BASE;
+ flash_info->end = (void *)(CYGNUM_FLASH_BASE +
+ (num_regions*region_size*CYGNUM_FLASH_DEVICES*CYGNUM_FLASH_BANKS));
+#endif
+ flash_info->size = (num_regions*region_size*CYGNUM_FLASH_DEVICES*CYGNUM_FLASH_BANKS);
+
+#ifdef CYGNUM_FLASH_BASE_MASK_DISABLE // IJC -- what does this do?
// Then this gives us a maximum size for the (visible) device.
// This is to cope with oversize devices fitted, with some high
// address lines ignored.
- if ( ((unsigned int)flash_info.start & CYGNUM_FLASH_BASE_MASK) !=
- (((unsigned int)flash_info.end - 1) & CYGNUM_FLASH_BASE_MASK ) ) {
+ if ( ((unsigned int)flash_info->start & CYGNUM_FLASH_BASE_MASK) !=
+ (((unsigned int)flash_info->end - 1) & CYGNUM_FLASH_BASE_MASK ) ) {
// then the size of the device appears to span >1 device-worth!
unsigned int x;
x = (~(CYGNUM_FLASH_BASE_MASK)) + 1; // expected device size
- x += (unsigned int)flash_info.start;
- if ( x < (unsigned int)flash_info.end ) { // 2nd sanity check
- (*flash_info.pf)("\nFLASH: Oversized device! End addr %p changed to %p\n",
- flash_info.end, (void *)x );
- flash_info.end = (void *)x;
+ x += (unsigned int)flash_info->start;
+ if ( x < (unsigned int)flash_info->end ) { // 2nd sanity check
+ (*flash_info->pf)("\nFLASH: Oversized device! End addr %p changed to %p\n",
+ flash_info->end, (void *)x );
+ flash_info->end = (void *)x;
// Also adjust the block count else unlock crashes!
- x = ((cyg_uint8 *)flash_info.end - (cyg_uint8 *)flash_info.start)
- / flash_info.block_size;
- flash_info.blocks = x;
+ x = ((cyg_uint8 *)flash_info->end - (cyg_uint8 *)flash_info->start)
+ / flash_info->block_size;
+ flash_info->blocks = x;
}
}
#endif // CYGNUM_FLASH_BASE_MASK
@@ -171,18 +196,28 @@ flash_hwr_init(void)
#ifdef CYGOPT_FLASH_IS_BOOTBLOCK
flash_type_unknown:
#endif
- (*flash_info.pf)("Can't identify FLASH, sorry, man %x, dev %x, id [%4s] stat %x\n",
+ (*flash_info->pf)("Can't identify FLASH, sorry, man %x, dev %x, id [%4s] stat %x\n",
qp->manuf_code, qp->device_code, qp->id, stat );
diag_dump_buf(qp, sizeof(data));
return FLASH_ERR_HWR;
}
+int flash_hwr_read(struct flash_info *flash_info, void *ram_base, unsigned long flash_base, unsigned long len, unsigned long *err_addr)
+{
+ int i;
+ flash_t *data = (flash_t *)ram_base;
+ for ( i = 0 ; i < len ; i += sizeof(flash_t) ) {
+ HAL_FLASH_READ(flash_base+i, *data++);
+ }
+ return FLASH_ERR_OK;
+}
+
// Map a hardware status to a package error
int
-flash_hwr_map_error(int err)
+flash_hwr_map_error(struct flash_info *flash_info, int err)
{
if (err & FLASH_ErrorMask) {
- (*flash_info.pf)("Err = %x\n", err);
+ (*flash_info->pf)("Err = %x\n", err);
if (err & FLASH_ErrorProgram)
return FLASH_ERR_PROGRAM;
else if (err & FLASH_ErrorErase)
@@ -196,7 +231,7 @@ flash_hwr_map_error(int err)
// See if a range of FLASH addresses overlaps currently running code
bool
-flash_code_overlaps(void *start, void *end)
+flash_code_overlaps(struct flash_info *flash_info, unsigned long start, unsigned long end)
{
extern char _stext[], _etext[];
Index: devs/flash/intel/strata/current/src/strata.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/intel/strata/current/src/strata.h,v
retrieving revision 1.4
diff -u -b -B -w -p -u -r1.4 strata.h
--- devs/flash/intel/strata/current/src/strata.h 12 Aug 2002 12:20:50 -0000 1.4
+++ devs/flash/intel/strata/current/src/strata.h 21 Feb 2003 13:33:53 -0000
@@ -83,6 +83,9 @@
// CYGNUM_FLASH_BLANK 1 if blank is allones, 0 if 0
// CYGNUM_FLASH_BASE base address
// CYGNUM_FLASH_BASE_MASK a mask to get base address from any
+// CYGNUM_FLASH_BANKS number of devices up the databus
+// CYGNUM_FLASH_BANK_MASK a mask to get base address of the
+// bank containing an address
//
// for example, a 32-bit memory could be made from 1x32bit, 2x16bit or
// 4x8bit devices; usually 16bit ones are chosen in practice, so we would
@@ -91,7 +94,11 @@
// Some CPUs can handle a single 16bit device as 32bit memory "by magic".
// In that case, CYGNUM_FLASH_DEVICES = 1 and CYGNUM_FLASH_WIDTH = 16, and
// the device is managed using only 16bit bus operations.
-
+//
+// If you had two consecutive 32bit devices of size 32Mb to give a total of 64Mb
+// at memory address 0 then you would define CYGNUM_FLASH_BANKS as 2 and
+// CYGNUM_FLASH_BANK_MASK as 0xFE000000u to give the base of the bank and
+// CYGNUM_FLASH_BASE_MASK as 0xFC000000
// ------------------------------------------------------------------------
//
@@ -107,6 +114,24 @@
#define FLASH_P2V( _a_ ) ((volatile flash_t *)((unsigned int)(_a_)))
#endif
+// -------------------------------------------------------------------------
+//
+// If the board has not defined multiple banks then assume only one bank
+// exists
+//
+#ifndef CYGNUM_FLASH_BANKS
+#define CYGNUM_FLASH_BANKS (1)
+#endif
+
+#ifndef CYGNUM_FLASH_BANK_MASK
+#define CYGNUM_FLASH_BANK_MASK CYGNUM_FLASH_BASE_MASK
+#endif
+
+#if CYGNUM_FLASH_BANKS > 1 && defined(CYGOPT_FLASH_IS_BOOTBLOCK)
+#error "Can't handle multiple flash banks with bootblock flash"
+#endif
+
+
// ------------------------------------------------------------------------
//
// This generic code is intended to deal with all shapes and orientations
@@ -141,7 +166,7 @@ typedef unsigned long flash_t;
# elif 8 == CYGNUM_FLASH_DEVICES
// 8 devices to make 64-bit - intermediate requires explicit widening
# define FLASHWORD32( k ) ((flash_t)((k)+((k)<<8)+((k)<<16)+((k)<<24)))
-# define FLASHWORD( k ) (FLASHWORD32( k ) + (FLASHWORD32( k ) << 32));
+# define FLASHWORD( k ) (FLASHWORD32( k ) + (FLASHWORD32( k ) << 32))
typedef unsigned long long flash_t;
# else
# error How many 8-bit flash devices?
@@ -156,10 +181,10 @@ typedef unsigned short flash_t;
// 2 devices to make 32-bit
# define FLASHWORD( k ) ((k)+((k)<<16))
typedef unsigned long flash_t;
-# elif 2 == CYGNUM_FLASH_DEVICES
+# elif 4 == CYGNUM_FLASH_DEVICES
// 4 devices to make 64-bit - intermediate requires explicit widening
# define FLASHWORD32( k ) ((flash_t)((k)+((k)<<16)))
-# define FLASHWORD( k ) (FLASHWORD32( k ) + (FLASHWORD32( k ) << 32));
+# define FLASHWORD( k ) (FLASHWORD32( k ) + (FLASHWORD32( k ) << 32))
typedef unsigned long long flash_t;
# else
# error How many 16-bit flash devices?
@@ -173,7 +198,7 @@ typedef unsigned long flash_t;
# elif 2 == CYGNUM_FLASH_DEVICES
// 2 devices to make 64-bit - intermediate requires explicit widening
# define FLASHWORD32( k ) ((flash_t)(k))
-# define FLASHWORD( k ) (FLASHWORD32( k ) + (FLASHWORD32( k ) << 32));
+# define FLASHWORD( k ) (FLASHWORD32( k ) + (FLASHWORD32( k ) << 32))
typedef unsigned long long flash_t;
# else
# error How many 32-bit flash devices?
@@ -249,6 +274,23 @@ struct FLASH_query {
unsigned char num_regions[2];
unsigned char region_size[2];
};
+
+// ------------------------------------------------------------------------
+
+#ifndef HAL_FLASH_READ
+#define HAL_FLASH_READ(__OFFSET__, __VALUE__) \
+CYG_MACRO_START \
+__VALUE__ = *(volatile flash_t *)(cyg_uint8*)FLASH_P2V(CYGNUM_FLASH_BASE)+(__OFFSET__));\
+CYG_MACRO_END
+#endif
+
+#ifndef HAL_FLASH_WRITE
+#define HAL_FLASH_WRITE(__OFFSET__, __VALUE__) \
+CYG_MACRO_START \
+*(volatile flash_t *)((cyg_uint8*)FLASH_P2V(CYGNUM_FLASH_BASE)+(__OFFSET__)) = (__VALUE__); \
+CYG_MACRO_END
+#endif
+
#endif // CYGONCE_DEVS_FLASH_INTEL_STRATA_FLASH_H
// ------------------------------------------------------------------------
Index: io/flash/current/cdl/io_flash.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/flash/current/cdl/io_flash.cdl,v
retrieving revision 1.11
diff -u -b -B -w -p -u -r1.11 io_flash.cdl
--- io/flash/current/cdl/io_flash.cdl 23 May 2002 23:06:14 -0000 1.11
+++ io/flash/current/cdl/io_flash.cdl 21 Feb 2003 13:33:57 -0000
@@ -88,6 +88,14 @@ cdl_package CYGPKG_IO_FLASH {
for the current platform."
}
+ cdl_interface CYGHWR_IO_FLASH_DEVICE_V2 {
+ display "Hardware FLASH device drivers"
+ flavor bool
+ description "
+ This option enables the hardware device drivers
+ V2 interface for the current platform."
+ }
+
cdl_interface CYGHWR_IO_FLASH_DEVICE_NOT_IN_RAM {
display "Hardware FLASH device drivers are not in RAM"
flavor booldata
Index: io/flash/current/include/flash.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/flash/current/include/flash.h,v
retrieving revision 1.15
diff -u -b -B -w -p -u -r1.15 flash.h
--- io/flash/current/include/flash.h 23 May 2002 23:06:14 -0000 1.15
+++ io/flash/current/include/flash.h 21 Feb 2003 13:33:57 -0000
@@ -59,20 +59,46 @@
typedef int _printf(const char *fmt, ...);
#define FLASH_MIN_WORKSPACE CYGNUM_FLASH_WORKSPACE_SIZE // Space used by FLASH code
+struct flash_info;
-externC int flash_init(void *work_space, int work_space_length, _printf *pf);
-externC int flash_erase(void *base, int len, void **err_address);
-externC int flash_program(void *flash_base, void *ram_base, int len, void **err_address);
+#ifdef CYGHWR_IO_FLASH_DEVICE_V2
+typedef int (*flash_query_func) (struct flash_info *, void *);
+typedef int (*flash_erase_func) (struct flash_info *, unsigned long, unsigned int);
+typedef int (*flash_program_func) (struct flash_info *, unsigned long, void *, int, unsigned long, int);
+typedef int (*flash_lock_func) (struct flash_info *, unsigned long);
+typedef int (*flash_unlock_func) (struct flash_info *, unsigned long, int, int);
+#else // FLASH DEVICE V1
+typedef int (*flash_query_func) (void *);
+typedef int (*flash_erase_func) (volatile void *, unsigned int);
+typedef int (*flash_program_func) (volatile void *, void *, int, unsigned long, int);
+typedef int (*flash_lock_func) (volatile void *);
+typedef int (*flash_unlock_func) (volatile void *, int, int);
+#endif
+
+externC int flash_init(struct flash_info *flash_info, void *work_space, int work_space_length, _printf *pf);
+externC int flash_erase(struct flash_info *flash_info, unsigned long base, unsigned long len, unsigned long *err_address);
+externC int flash_program(struct flash_info *flash_info, unsigned long flash_base, void *ram_base, unsigned long len, unsigned long *err_address);
+externC int flash_read(struct flash_info *flash_info, void *ram_base, unsigned long flash_base, unsigned long len, unsigned long *err_address);
+
+#ifdef CYGHWR_IO_FLASH_DEVICE_V2
+externC void flash_dev_query(struct flash_info *flash_info, void *data);
+#else
externC void flash_dev_query(void *data);
+#endif
+
#ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
-externC int flash_lock(void *base, int len, void **err_address);
-externC int flash_unlock(void *base, int len, void **err_address);
+externC int flash_lock(struct flash_info *flash_info, unsigned long base, unsigned long len, unsigned long *err_address);
+externC int flash_unlock(struct flash_info *flash_info, unsigned long base, unsigned long len, unsigned long *err_address);
#endif
-externC int flash_verify_addr(void *base);
-externC int flash_get_limits(void *base, void **start, void **end);
-externC int flash_get_block_info(int *block_size, int *blocks);
+externC int flash_verify_addr(struct flash_info *flash_info, unsigned long base);
+externC int flash_get_limit(struct flash_info *flash_info, unsigned long *size);
+externC int flash_get_block_info(struct flash_info *flash_info, unsigned long *block_size, int *blocks);
+#ifdef CYGHWR_IO_FLASH_DEVICE_V2
+externC bool flash_code_overlaps(struct flash_info *flash_info, unsigned long start, unsigned long end);
+#else
externC bool flash_code_overlaps(void *start, void *end);
-externC char *flash_errmsg(int err);
+#endif
+externC char *flash_errmsg(struct flash_info *flash_info, int err);
#define FLASH_ERR_OK 0x00 // No error - operation complete
#define FLASH_ERR_INVALID 0x01 // Invalid FLASH address
@@ -93,38 +119,55 @@ externC char *flash_errmsg(int err);
#ifdef CYGPKG_IO_FLASH_BLOCK_DEVICE
typedef struct {
CYG_ADDRESS offset;
- int len;
+ unsigned long len;
int flasherr;
- void **err_address;
+ unsigned long *err_address;
} cyg_io_flash_getconfig_erase_t;
typedef struct {
- int dev_size;
+ unsigned long dev_size;
} cyg_io_flash_getconfig_devsize_t;
typedef struct {
CYG_ADDRESS offset;
- int block_size;
+ unsigned long block_size;
} cyg_io_flash_getconfig_blocksize_t;
#endif
-#ifdef _FLASH_PRIVATE_
-
struct flash_info {
void *work_space;
int work_space_size;
+#ifdef CYGHWR_IO_FLASH_DEVICE_V2
+ unsigned long block_size; // Assuming fixed size "blocks"
+ int blocks; // Number of blocks
+ unsigned long buffer_size; // Size of write buffer (only defined for some devices)
+ unsigned long size; // Total size of device
+#else
int block_size; // Assuming fixed size "blocks"
int blocks; // Number of blocks
int buffer_size; // Size of write buffer (only defined for some devices)
- unsigned long block_mask;
void *start, *end; // Address range
+#endif
+ unsigned long block_mask; // Retrieve base of block from any offset
+
int init;
_printf *pf;
};
-externC struct flash_info flash_info;
+#ifdef _FLASH_PRIVATE_
+
+#ifdef CYGHWR_IO_FLASH_DEVICE_V2
+externC int flash_hwr_init(struct flash_info *flash_info);
+externC int flash_hwr_map_error(struct flash_info *flash_info, int err);
+externC int flash_hwr_read(struct flash_info *flash_info, void *ram_base,
+ unsigned long flash_base, unsigned long len,
+ unsigned long *err_addr);
+#else
externC int flash_hwr_init(void);
externC int flash_hwr_map_error(int err);
+#define FLASH_OFFSET_TO_ADDRESS(__BASE__, __OFFSET__) ((cyg_uint8*)(__BASE__) + (__OFFSET__))
+externC struct flash_info flash_info;
+#endif
//
// Some FLASH devices may require additional support, e.g. to turn on
Index: io/flash/current/src/flash.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/flash/current/src/flash.c,v
retrieving revision 1.20
diff -u -b -B -w -p -u -r1.20 flash.c
--- io/flash/current/src/flash.c 23 May 2002 23:06:16 -0000 1.20
+++ io/flash/current/src/flash.c 21 Feb 2003 13:33:57 -0000
@@ -58,6 +58,8 @@
#include <cyg/hal/hal_cache.h>
#include <string.h>
+#include <cyg/infra/diag.h>
+
#define _FLASH_PRIVATE_
#include <cyg/io/flash.h>
@@ -70,22 +72,25 @@
# undef CYGHWR_IO_FLASH_DEVICE_NOT_IN_RAM
#endif
-struct flash_info flash_info;
-
int
-flash_init(void *work_space, int work_space_size, _printf *pf)
+flash_init(struct flash_info *flash_info, void *work_space, int work_space_size, _printf *pf)
{
int err;
- if (flash_info.init) return FLASH_ERR_OK;
- flash_info.pf = pf; // Do this before calling into the driver
- flash_info.work_space = work_space;
- flash_info.work_space_size = work_space_size;
- if ((err = flash_hwr_init()) != FLASH_ERR_OK) {
+ if (flash_info->init) return FLASH_ERR_OK;
+ flash_info->pf = pf; // Do this before calling into the driver
+ flash_info->work_space = work_space;
+ flash_info->work_space_size = work_space_size;
+#ifdef CYGHWR_IO_FLASH_DEVICE_V2
+ err = flash_hwr_init(flash_info);
+#else
+ err = flash_hwr_init();
+#endif
+ if (err != FLASH_ERR_OK) {
return err;
}
- flash_info.block_mask = ~(flash_info.block_size-1);
- flash_info.init = 1;
+ flash_info->block_mask = ~(flash_info->block_size-1);
+ flash_info->init = 1;
return FLASH_ERR_OK;
}
@@ -102,11 +107,18 @@ static void* __anonymizer(void* p)
// FIXME: Want to change all drivers to use this function. But it may
// make sense to wait till device structure pointer arguments get
// added as well.
+#ifdef CYGHWR_IO_FLASH_DEVICE_V2
+void
+flash_dev_query(struct flash_info *_flash_info, void *data)
+#else
void
flash_dev_query(void* data)
+#endif
{
- typedef void code_fun(void*);
- code_fun *_flash_query;
+#if !defined(CYGHWR_IO_FLASH_DEVICE_V2) && defined(CYGHWR_IO_FLASH_DEVICE_NOT_IN_RAM)
+ struct flash_info *_flash_info = &flash_info;
+#endif
+ flash_query_func _flash_query;
int d_cache, i_cache;
#ifdef CYGHWR_IO_FLASH_DEVICE_NOT_IN_RAM
@@ -116,67 +128,82 @@ flash_dev_query(void* data)
// Query the device driver - copy 'query' code to RAM for execution
code_len = (CYG_ADDRESS)&flash_query_end - (CYG_ADDRESS)&flash_query;
- _flash_query = (code_fun *)flash_info.work_space;
+ _flash_query = (flash_query_func)_flash_info->work_space;
memcpy(_flash_query, &flash_query, code_len);
}
#else
{
- externC code_fun flash_query;
- _flash_query = (code_fun*) __anonymizer(&flash_query);
+ externC flash_query_func flash_query;
+ _flash_query = (flash_query_func) __anonymizer(&flash_query);
}
#endif
HAL_FLASH_CACHES_OFF(d_cache, i_cache);
+#ifdef CYGHWR_IO_FLASH_DEVICE_V2
+ (*_flash_query)(_flash_info, data);
+#else
(*_flash_query)(data);
+#endif
HAL_FLASH_CACHES_ON(d_cache, i_cache);
}
int
-flash_verify_addr(void *target)
+flash_verify_addr(struct flash_info *flash_info, unsigned long target)
{
- if (!flash_info.init) {
+ if (!flash_info->init) {
return FLASH_ERR_NOT_INIT;
}
- if (((CYG_ADDRESS)target >= (CYG_ADDRESS)flash_info.start) &&
- ((CYG_ADDRESS)target <= ( ((CYG_ADDRESS)flash_info.end) - 1) )) {
+#ifdef CYGHWR_IO_FLASH_DEVICE_V2
+ if (target <= ( (flash_info->size) - 1) ) {
+ return FLASH_ERR_OK;
+ } else {
+ return FLASH_ERR_INVALID;
+ }
+#else
+ if (((CYG_ADDRESS)target >= (CYG_ADDRESS)flash_info->start) &&
+ ((CYG_ADDRESS)target <= ( ((CYG_ADDRESS)flash_info->end) - 1) )) {
return FLASH_ERR_OK;
} else {
return FLASH_ERR_INVALID;
}
+
+#endif
}
int
-flash_get_limits(void *target, void **start, void **end)
+flash_get_limit(struct flash_info *flash_info, unsigned long *size)
{
- if (!flash_info.init) {
+ if (!flash_info->init) {
return FLASH_ERR_NOT_INIT;
}
- *start = flash_info.start;
- *end = flash_info.end;
+#ifdef CYGHWR_IO_FLASH_DEVICE_V2
+ *size = flash_info->size;
+#else
+ *size = (unsigned long)((cyg_uint8*)flash_info->end - (cyg_uint8*)flash_info->start);
+#endif
return FLASH_ERR_OK;
}
int
-flash_get_block_info(int *block_size, int *blocks)
+flash_get_block_info(struct flash_info *flash_info, unsigned long *block_size, int *blocks)
{
- if (!flash_info.init) {
+ if (!flash_info->init) {
return FLASH_ERR_NOT_INIT;
}
- *block_size = flash_info.block_size;
- *blocks = flash_info.blocks;
+ *block_size = flash_info->block_size;
+ *blocks = flash_info->blocks;
return FLASH_ERR_OK;
}
int
-flash_erase(void *addr, int len, void **err_addr)
+flash_erase(struct flash_info *flash_info, unsigned long addr, unsigned long len, unsigned long *err_addr)
{
- unsigned short *block, *end_addr;
+ unsigned long block, end_addr;
int stat = 0;
- typedef int code_fun(unsigned short *, unsigned int);
- code_fun *_flash_erase_block;
+ flash_erase_func _flash_erase_block;
int d_cache, i_cache;
- if (!flash_info.init) {
+ if (!flash_info->init) {
return FLASH_ERR_NOT_INIT;
}
@@ -192,53 +219,67 @@ flash_erase(void *addr, int len, void **
// Copy 'erase' code to RAM for execution
code_len = (CYG_ADDRESS)&flash_erase_block_end - (CYG_ADDRESS)&flash_erase_block;
- _flash_erase_block = (code_fun *)flash_info.work_space;
+ _flash_erase_block = (flash_erase_func)flash_info->work_space;
memcpy(_flash_erase_block, &flash_erase_block, code_len);
}
#else
{
- externC code_fun flash_erase_block;
- _flash_erase_block = (code_fun*) __anonymizer(&flash_erase_block);
+ externC flash_erase_func flash_erase_block;
+ _flash_erase_block = (flash_erase_func) __anonymizer(&flash_erase_block);
}
#endif
- block = (unsigned short *)((CYG_ADDRESS)addr & flash_info.block_mask);
- end_addr = (unsigned short *)((CYG_ADDRESS)addr+len);
+ block = (unsigned long)(addr & flash_info->block_mask);
+ end_addr = (unsigned long)(addr + len);
/* Check to see if end_addr overflowed */
if( (end_addr < block) && (len > 0) ){
- end_addr = (unsigned short *) ((CYG_ADDRESS) flash_info.end - 1);
+ flash_get_limit(flash_info, &end_addr);
+ --end_addr;
}
- (*flash_info.pf)("... Erase from %p-%p: ", (void*)block, (void*)end_addr);
+ (*flash_info->pf)("... Erase from %p-%p: ", (void*)block, (void*)end_addr);
HAL_FLASH_CACHES_OFF(d_cache, i_cache);
FLASH_Enable(block, end_addr);
while (block < end_addr) {
+#ifndef CYGSEM_IO_FLASH_ALWAYS_ERASE
// Supply the blocksize for a gross check for erase success
int i;
unsigned char *dp;
bool erased = true;
- unsigned short *tmp_block;
+ unsigned long tmp_block;
dp = (unsigned char *)block;
- for (i = 0; i < flash_info.block_size; i++) {
+ for (i = 0; i < flash_info->block_size; i++) {
if (*dp++ != (unsigned char)0xFF) {
erased = false;
break;
}
}
+#else
+ bool erased = false;
+ unsigned long tmp_block;
+#endif
if (!erased) {
- stat = (*_flash_erase_block)(block, flash_info.block_size);
+#ifdef CYGHWR_IO_FLASH_DEVICE_V2
+ stat = (*_flash_erase_block)(flash_info, block, flash_info->block_size);
+ stat = flash_hwr_map_error(flash_info, stat);
+#else
+ stat = (*_flash_erase_block)((volatile void*)FLASH_OFFSET_TO_ADDRESS(flash_info->start,block),
+ flash_info->block_size);
stat = flash_hwr_map_error(stat);
+#endif
}
if (stat) {
- *err_addr = (void *)block;
+ *err_addr = block;
break;
}
// Check to see if block will overflow
- tmp_block = block + flash_info.block_size / sizeof(*block);
+
+ //IJC tmp_block = block + flash_info->block_size / sizeof(*block);
+ tmp_block = block + flash_info->block_size;
if(tmp_block < block){
// If block address overflows, set block value to end on this loop
block = end_addr;
@@ -246,27 +287,26 @@ flash_erase(void *addr, int len, void **
else{
block = tmp_block;
}
- (*flash_info.pf)(".");
+ (*flash_info->pf)(".");
}
FLASH_Disable(block, end_addr);
HAL_FLASH_CACHES_ON(d_cache, i_cache);
- (*flash_info.pf)("\n");
+ (*flash_info->pf)("\n");
return (stat);
}
int
-flash_program(void *_addr, void *_data, int len, void **err_addr)
+flash_program(struct flash_info *flash_info, unsigned long _addr, void *_data, unsigned long len, unsigned long *err_addr)
{
int stat = 0;
int size;
- typedef int code_fun(void *, void *, int, unsigned long, int);
- code_fun *_flash_program_buf;
- unsigned char *addr = (unsigned char *)_addr;
+ flash_program_func _flash_program_buf;
+ unsigned long addr = _addr;
unsigned char *data = (unsigned char *)_data;
- CYG_ADDRESS tmp;
+ unsigned long tmp;
int d_cache, i_cache;
- if (!flash_info.init) {
+ if (!flash_info->init) {
return FLASH_ERR_NOT_INIT;
}
@@ -281,69 +321,85 @@ flash_program(void *_addr, void *_data,
extern char flash_program_buf[], flash_program_buf_end[];
// Copy 'program' code to RAM for execution
code_len = (CYG_ADDRESS)&flash_program_buf_end - (CYG_ADDRESS)&flash_program_buf;
- _flash_program_buf = (code_fun *)flash_info.work_space;
+ _flash_program_buf = (flash_program_func)flash_info->work_space;
memcpy(_flash_program_buf, &flash_program_buf, code_len);
}
#else
{
- externC code_fun flash_program_buf;
- _flash_program_buf = (code_fun*) __anonymizer(&flash_program_buf);
+ externC flash_program_func flash_program_buf;
+ _flash_program_buf = (flash_program_func) __anonymizer(&flash_program_buf);
}
#endif
- (*flash_info.pf)("... Program from %p-%p at %p: ", (void*)data,
+ (*flash_info->pf)("... Program from %p-%p at %p: ", (void*)data,
(void*)(((CYG_ADDRESS)data)+len), (void*)addr);
HAL_FLASH_CACHES_OFF(d_cache, i_cache);
FLASH_Enable((unsigned short*)addr, (unsigned short *)(addr+len));
while (len > 0) {
size = len;
- if (size > flash_info.block_size) size = flash_info.block_size;
+ if (size > flash_info->block_size) size = flash_info->block_size;
- tmp = (CYG_ADDRESS)addr & ~flash_info.block_mask;
+ tmp = addr & ~flash_info->block_mask;
if (tmp) {
- tmp = flash_info.block_size - tmp;
+ tmp = flash_info->block_size - tmp;
if (size>tmp) size = tmp;
}
- stat = (*_flash_program_buf)(addr, data, size,
- flash_info.block_mask, flash_info.buffer_size);
+#ifdef CYGHWR_IO_FLASH_DEVICE_V2
+ stat = (*_flash_program_buf)(flash_info, addr, data, size,
+ flash_info->block_mask, flash_info->buffer_size);
+ stat = flash_hwr_map_error(flash_info, stat);
+#else
+ stat = (*_flash_program_buf)((volatile void*)FLASH_OFFSET_TO_ADDRESS(flash_info->start,addr),
+ data, size, flash_info->block_mask, flash_info->buffer_size);
stat = flash_hwr_map_error(stat);
+#endif
+
#ifdef CYGSEM_IO_FLASH_VERIFY_PROGRAM
if (0 == stat) // Claims to be OK
if (memcmp(addr, data, size) != 0) {
stat = 0x0BAD;
- (*flash_info.pf)("V");
+ (*flash_info->pf)("V");
}
#endif
if (stat) {
- *err_addr = (void *)addr;
+ *err_addr = addr;
break;
}
- (*flash_info.pf)(".");
+ (*flash_info->pf)(".");
len -= size;
- addr += size/sizeof(*addr);
+ addr += size;
data += size/sizeof(*data);
}
FLASH_Disable((unsigned short*)addr, (unsigned short *)(addr+len));
HAL_FLASH_CACHES_ON(d_cache, i_cache);
- (*flash_info.pf)("\n");
+ (*flash_info->pf)("\n");
return (stat);
}
+int flash_read(struct flash_info *flash_info, void *ram_base, unsigned long flash_base, unsigned long len, unsigned long *err_addr)
+{
+#ifdef CYGHWR_IO_FLASH_DEVICE_V2
+ return flash_hwr_read(flash_info, ram_base, flash_base, len, err_addr);
+#else
+ memcpy(ram_base, FLASH_OFFSET_TO_ADDRESS(flash_info->start, flash_base), len);
+ return FLASH_ERR_OK;
+#endif
+}
+
#ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
int
-flash_lock(void *addr, int len, void **err_addr)
+flash_lock(struct flash_info *flash_info, unsigned long offset, unsigned long len, unsigned long *err_addr)
{
- unsigned short *block, *end_addr;
+ unsigned long block, end_offset;
int stat = 0;
- typedef int code_fun(unsigned short *);
- code_fun *_flash_lock_block;
+ flash_lock_func _flash_lock_block;
int d_cache, i_cache;
- if (!flash_info.init) {
+ if (!flash_info->init) {
return FLASH_ERR_NOT_INIT;
}
@@ -358,64 +414,69 @@ flash_lock(void *addr, int len, void **e
CYG_ADDRESS code_len;
// Copy 'lock' code to RAM for execution
code_len = (CYG_ADDRESS)&flash_lock_block_end - (CYG_ADDRESS)&flash_lock_block;
- _flash_lock_block = (code_fun *)flash_info.work_space;
+ _flash_lock_block = (flash_lock_func)flash_info->work_space;
memcpy(_flash_lock_block, &flash_lock_block, code_len);
}
#else
{
- externC code_fun flash_lock_block;
- _flash_lock_block = (code_fun*) __anonymizer(&flash_lock_block);
+ externC flash_lock_func flash_lock_block;
+ _flash_lock_block = (flash_lock_func) __anonymizer(&flash_lock_block);
}
#endif
- block = (unsigned short *)((CYG_ADDRESS)addr & flash_info.block_mask);
- end_addr = (unsigned short *)((CYG_ADDRESS)addr+len);
+ block = (offset & flash_info->block_mask);
+ end_offset = (offset + len);
/* Check to see if end_addr overflowed */
- if( (end_addr < block) && (len > 0) ){
- end_addr = (unsigned short *) ((CYG_ADDRESS) flash_info.end - 1);
+ if( (end_offset < block) && (len > 0) ){
+ end_offset = (flash_info->size - 1);
}
- (*flash_info.pf)("... Lock from %p-%p: ", block, end_addr);
+ (*flash_info->pf)("... Lock from %p-%p: ", (void*)block, (void*)end_offset);
HAL_FLASH_CACHES_OFF(d_cache, i_cache);
FLASH_Enable(block, end_addr);
- while (block < end_addr) {
- unsigned short *tmp_block;
- stat = (*_flash_lock_block)(block);
+ while (block < end_offset) {
+ unsigned long tmp_block;
+
+#ifdef CYGHWR_IO_FLASH_DEVICE_V2
+ stat = (*_flash_lock_block)(flash_info, block);
+ stat = flash_hwr_map_error(flash_info, stat);
+#else
+ stat = (*_flash_lock_block)((volatile void *) ((cyg_uint8 *)block + block));
stat = flash_hwr_map_error(stat);
+#endif
if (stat) {
- *err_addr = (void *)block;
+ *err_addr = block;
break;
}
// Check to see if block will overflow
- tmp_block = block + flash_info.block_size / sizeof(*block);
+ tmp_block = block + flash_info->block_size;
if(tmp_block < block){
// If block address overflows, set block value to end on this loop
- block = end_addr;
+ block = end_offset;
}
else{
block = tmp_block;
}
- (*flash_info.pf)(".");
+ (*flash_info->pf)(".");
}
FLASH_Disable(block, end_addr);
HAL_FLASH_CACHES_ON(d_cache, i_cache);
- (*flash_info.pf)("\n");
+ (*flash_info->pf)("\n");
return (stat);
}
int
-flash_unlock(void *addr, int len, void **err_addr)
+flash_unlock(struct flash_info *flash_info, unsigned long offset, unsigned long len, unsigned long *err_addr)
{
- unsigned short *block, *end_addr;
+ unsigned long block, end_offset;
int stat = 0;
- typedef int code_fun(unsigned short *, int, int);
- code_fun *_flash_unlock_block;
+ flash_unlock_func _flash_unlock_block;
int d_cache, i_cache;
- if (!flash_info.init) {
+ if (!flash_info->init) {
return FLASH_ERR_NOT_INIT;
}
@@ -430,56 +491,62 @@ flash_unlock(void *addr, int len, void *
CYG_ADDRESS code_len;
// Copy 'lock' code to RAM for execution
code_len = (CYG_ADDRESS)&flash_unlock_block_end - (CYG_ADDRESS)&flash_unlock_block;
- _flash_unlock_block = (code_fun *)flash_info.work_space;
+ _flash_unlock_block = (flash_unlock_func)flash_info->work_space;
memcpy(_flash_unlock_block, &flash_unlock_block, code_len);
}
#else
{
- externC code_fun flash_unlock_block;
- _flash_unlock_block = (code_fun*) __anonymizer(&flash_unlock_block);
+ externC flash_unlock_func flash_unlock_block;
+ _flash_unlock_block = (flash_unlock_func) __anonymizer(&flash_unlock_block);
}
#endif
- block = (unsigned short *)((CYG_ADDRESS)addr & flash_info.block_mask);
- end_addr = (unsigned short *)((CYG_ADDRESS)addr+len);
+ block = (offset & flash_info->block_mask);
+ end_offset = (offset+len);
- /* Check to see if end_addr overflowed */
- if( (end_addr < block) && (len > 0) ){
- end_addr = (unsigned short *) ((CYG_ADDRESS) flash_info.end - 1);
+ /* Check to see if end_offset overflowed */
+ if( (end_offset < block) && (len > 0) ){
+ end_offset = (flash_info->size - 1);
}
- (*flash_info.pf)("... Unlock from %p-%p: ", block, end_addr);
+ (*flash_info->pf)("... Unlock from %p-%p: ", (void*)block, (void*)end_offset);
HAL_FLASH_CACHES_OFF(d_cache, i_cache);
- FLASH_Enable(block, end_addr);
- while (block < end_addr) {
- unsigned short *tmp_block;
- stat = (*_flash_unlock_block)(block, flash_info.block_size, flash_info.blocks);
+ FLASH_Enable(block, end_offset);
+ while (block < end_offset) {
+ unsigned long tmp_block;
+#ifdef CYGHWR_IO_FLASH_DEVICE_V2
+ stat = (*_flash_unlock_block)(flash_info, block, flash_info->block_size, flash_info->blocks);
+ stat = flash_hwr_map_error(flash_info, stat);
+#else
+ stat = (*_flash_unlock_block)((volatile void *)FLASH_OFFSET_TO_ADDRESS(flash_info->start, block),
+ flash_info->block_size, flash_info->blocks);
stat = flash_hwr_map_error(stat);
+#endif
if (stat) {
- *err_addr = (void *)block;
+ *err_addr = block;
break;
}
- tmp_block = block + flash_info.block_size / sizeof(*block);
+ tmp_block = block + flash_info->block_size;
if(tmp_block < block){
// If block address overflows, set block value to end on this loop
- block = end_addr;
+ block = end_offset;
}
else{
block = tmp_block;
}
- (*flash_info.pf)(".");
+ (*flash_info->pf)(".");
}
- FLASH_Disable(block, end_addr);
+ FLASH_Disable(block, end_offset);
HAL_FLASH_CACHES_ON(d_cache, i_cache);
- (*flash_info.pf)("\n");
+ (*flash_info->pf)("\n");
return (stat);
}
#endif
char *
-flash_errmsg(int err)
+flash_errmsg(struct flash_info *flash_info, int err)
{
switch (err) {
case FLASH_ERR_OK:
Index: redboot/current/cdl/redboot.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/cdl/redboot.cdl,v
retrieving revision 1.44
diff -u -b -B -w -p -u -r1.44 redboot.cdl
--- redboot/current/cdl/redboot.cdl 14 Feb 2003 02:49:06 -0000 1.44
+++ redboot/current/cdl/redboot.cdl 21 Feb 2003 13:34:00 -0000
@@ -641,7 +648,8 @@ cdl_package CYGPKG_REDBOOT {
cdl_option CYGSEM_REDBOOT_FLASH_CONFIG_READONLY_FALLBACK {
display "Fallback to read-only FLASH configuration"
flavor bool
- default_value 1
+ #default_value 1
+ default_value 0
description "
This option will cause the configuration information to
revert to the readonly information stored in the FLASH.
Index: redboot/current/src/flash.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/src/flash.c,v
retrieving revision 1.42
diff -u -b -B -w -p -u -r1.42 flash.c
--- redboot/current/src/flash.c 24 Oct 2002 18:32:25 -0000 1.42
+++ redboot/current/src/flash.c 21 Feb 2003 13:34:00 -0000
@@ -68,7 +68,8 @@
#include <flash_config.h>
// Configuration data, saved in FLASH, used to set/update RedBoot
-// normal "configuration" data items.
+// normal "configuration" data items. *config and *backup_config
+// point to copies of the config data in RAM
static struct _config {
unsigned long len;
unsigned long key1;
@@ -77,6 +78,10 @@ static struct _config {
unsigned long cksum;
} *config, *backup_config;
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG_READONLY_FALLBACK
+#error READONLY_FALLBACK not currently supported
+/* readonly_config is kept in flash, but coped into RAM if needed
+ * it should more correctly be called 'fallback_config'
+ */
static struct _config *readonly_config;
#endif
#endif
@@ -177,16 +182,20 @@ RedBoot_nested_cmd("fis",
__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__
);
+// Global flash device handle
+struct flash_info flash_info;
+
// Local data used by these routines
-static void *flash_start, *flash_end;
-static int flash_block_size, flash_num_blocks;
+static unsigned long flash_size;
+static unsigned long flash_block_size;
+static int flash_num_blocks;
#ifdef CYGOPT_REDBOOT_FIS
static void *fis_work_block;
-static void *fis_addr;
+static unsigned long fis_offset;
static int fisdir_size; // Size of FIS directory.
#endif
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
-static void *cfg_base; // Location in Flash of config data
+static unsigned long cfg_base; // Location in Flash of config data
static int cfg_size; // Length of config data - rounded to Flash block size
// Prototypes for local functions
static unsigned char *flash_lookup_config(char *key);
@@ -200,10 +209,10 @@ fis_usage(char *why)
}
static void
-_show_invalid_flash_address(CYG_ADDRESS flash_addr, int stat)
+_show_invalid_flash_offset(unsigned long flash_offset, 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);
+ diag_printf("Invalid FLASH offset %p: %s\n", flash_offset, flash_errmsg(&flash_info, stat));
+ diag_printf(" maximum offset is %p\n", (void*)flash_size);
}
#ifdef CYGOPT_REDBOOT_FIS
@@ -228,27 +237,27 @@ static void
fis_update_directory(void)
{
int stat;
- void *err_addr;
+ unsigned long err_addr;
#ifdef CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG
memcpy((char *)fis_work_block+fisdir_size, config, cfg_size);
#endif
#ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
// Ensure [quietly] that the directory is unlocked before trying to update
- flash_unlock((void *)fis_addr, flash_block_size, (void **)&err_addr);
+ flash_unlock(&flash_info, fis_offset, flash_block_size, &err_addr);
#endif
- if ((stat = flash_erase(fis_addr, flash_block_size, (void **)&err_addr)) != 0) {
- diag_printf("Error erasing FIS directory at %p: %s\n", err_addr, flash_errmsg(stat));
+ if ((stat = flash_erase(&flash_info, fis_offset, flash_block_size, &err_addr)) != 0) {
+ diag_printf("Error erasing FIS directory at %p: %s\n", err_addr, flash_errmsg(&flash_info, stat));
} else {
- if ((stat = flash_program(fis_addr, fis_work_block, flash_block_size,
- (void **)&err_addr)) != 0) {
+ if ((stat = flash_program(&flash_info, fis_offset, fis_work_block, flash_block_size,
+ &err_addr)) != 0) {
diag_printf("Error writing FIS directory at %p: %s\n",
- err_addr, flash_errmsg(stat));
+ err_addr, flash_errmsg(&flash_info, stat));
}
}
#ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
// Ensure [quietly] that the directory is locked after the update
- flash_lock((void *)fis_addr, flash_block_size, (void **)&err_addr);
+ flash_lock(&flash_info, fis_offset, flash_block_size, &err_addr);
#endif
}
@@ -257,7 +266,7 @@ fis_init(int argc, char *argv[])
{
int stat;
struct fis_image_desc *img;
- void *err_addr;
+ unsigned long err_addr;
bool full_init = false;
struct option_info opts[1];
CYG_ADDRESS redboot_flash_start;
@@ -286,12 +295,12 @@ fis_init(int argc, char *argv[])
#ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE
memset(img, 0, sizeof(*img));
strcpy(img->name, "(reserved)");
- img->flash_base = (CYG_ADDRESS)flash_start;
+ img->flash_base = 0;
img->mem_base = (CYG_ADDRESS)flash_start;
img->size = CYGNUM_REDBOOT_FLASH_RESERVED_BASE;
img++;
#endif
- redboot_flash_start = (CYG_ADDRESS)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET;
+ redboot_flash_start = CYGBLD_REDBOOT_FLASH_BOOT_OFFSET;
#ifdef CYGOPT_REDBOOT_FIS_REDBOOT
memset(img, 0, sizeof(*img));
strcpy(img->name, "RedBoot");
@@ -304,7 +313,7 @@ fis_init(int argc, char *argv[])
#ifdef CYGOPT_REDBOOT_FIS_REDBOOT_POST
#ifdef CYGNUM_REDBOOT_FIS_REDBOOT_POST_OFFSET
// Take care to place the POST entry at the right offset:
- redboot_flash_start = (CYG_ADDRESS)flash_start + CYGNUM_REDBOOT_FIS_REDBOOT_POST_OFFSET;
+ redboot_flash_start = CYGNUM_REDBOOT_FIS_REDBOOT_POST_OFFSET;
#endif
memset(img, 0, sizeof(*img));
strcpy(img->name, "RedBoot[post]");
@@ -336,8 +345,8 @@ fis_init(int argc, char *argv[])
// And a descriptor for the descriptor table itself
memset(img, 0, sizeof(*img));
strcpy(img->name, "FIS directory");
- img->flash_base = (CYG_ADDRESS)fis_addr;
- img->mem_base = (CYG_ADDRESS)fis_addr;
+ img->flash_base = (CYG_ADDRESS)fis_offset;
+ img->mem_base = (CYG_ADDRESS)fis_offset;
img->size = fisdir_size;
img++;
@@ -382,17 +391,17 @@ fis_init(int argc, char *argv[])
if (full_init) {
unsigned long erase_size;
- CYG_ADDRESS erase_start;
+ unsigned long erase_start;
// Erase everything except default RedBoot images, fis block,
// and config block.
// First deal with the possible first part, before RedBoot images:
#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;
+ erase_start = CYGNUM_REDBOOT_FLASH_RESERVED_BASE;
+ erase_size = 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) {
+ &err_addr)) != 0) {
diag_printf(" initialization failed at %p: %s\n",
err_addr, flash_errmsg(stat));
}
@@ -403,43 +412,39 @@ fis_init(int argc, char *argv[])
// Now the empty bits between the end of Redboot and the cfg and dir
// blocks.
#if defined(CYGSEM_REDBOOT_FLASH_CONFIG) && !defined(CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG)
- if (fis_addr > cfg_base) {
+ if (fis_offset > 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
+ erase_size = (CYG_ADDRESS)fis_offset - erase_start; // the gap between HWM and fis data
}
- if ((stat = flash_erase((void *)erase_start, erase_size,
- (void **)&err_addr)) != 0) {
+ if ((stat = flash_erase(&flash_info, erase_start, erase_size, &err_addr)) != 0) {
diag_printf(" initialization failed %p: %s\n",
- err_addr, flash_errmsg(stat));
+ err_addr, flash_errmsg(&flash_info, 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
+ if (fis_offset > cfg_base) {
+ erase_size = (CYG_ADDRESS)fis_offset - 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 = flash_erase(&flash_info, erase_start, erase_size, &err_addr)) != 0) {
diag_printf(" initialization failed %p: %s\n",
- err_addr, flash_errmsg(stat));
+ err_addr, flash_errmsg(&flash_info, 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) {
+ erase_size = (CYG_ADDRESS)fis_offset - erase_start; // the gap between HWM and fis data
+ if ((stat = flash_erase(&flash_info, erase_start, erase_size,
+ &err_addr)) != 0) {
diag_printf(" initialization failed %p: %s\n",
- err_addr, flash_errmsg(stat));
+ err_addr, flash_errmsg(&flash_info, stat));
}
erase_start += (erase_size + flash_block_size);
#endif
// Lastly, anything at the end
- 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));
+ erase_size = ((CYG_ADDRESS)flash_size - erase_start) + 1;
+ if ((stat = flash_erase(&flash_info, erase_start, erase_size, &err_addr)) != 0) {
+ diag_printf(" initialization failed at %p: %s\n", err_addr, flash_errmsg(&flash_info, stat));
}
} else {
diag_printf(" Warning: device contents not erased, some blocks may not be usable\n");
@@ -451,19 +456,12 @@ fis_init(int argc, char *argv[])
static void
fis_list(int argc, char *argv[])
{
- struct fis_image_desc *img;
- int i;
+ struct fis_image_desc img;
+ unsigned long i, err_addr;
bool show_cksums = false;
bool show_datalen = false;
struct option_info opts[2];
-#ifdef CYGHWR_REDBOOT_ARM_FLASH_SIB
- // FIXME: this is somewhat half-baked
- extern void arm_fis_list(void);
- arm_fis_list();
- return;
-#endif
-
init_opts(&opts[0], 'd', false, OPTION_ARG_TYPE_FLG,
(void **)&show_datalen, (bool *)0, "display data length");
#ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK
@@ -477,7 +475,7 @@ fis_list(int argc, char *argv[])
{
return;
}
- img = (struct fis_image_desc *) fis_addr;
+
// Let diag_printf do the formatting in both cases, rather than counting
// cols by hand....
diag_printf("%-16s %-10s %-10s %-10s %-s\n",
@@ -485,18 +483,19 @@ fis_list(int argc, char *argv[])
show_cksums ? "Checksum" : "Mem addr",
show_datalen ? "Datalen" : "Length",
"Entry point" );
- for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) {
- if (img->name[0] != (unsigned char)0xFF) {
- diag_printf("%-16s 0x%08lX 0x%08lX 0x%08lX 0x%08lX\n", img->name,
- img->flash_base,
+ for (i = fis_offset; i < fis_offset + fisdir_size; i += sizeof(struct fis_image_desc)) {
+ flash_read(&flash_info, &img, i, sizeof(struct fis_image_desc), &err_addr);
+ if (img.name[0] != (unsigned char)0xFF) {
+ diag_printf("%-16s 0x%08lX 0x%08lX 0x%08lX 0x%08lX\n", img.name,
+ img.flash_base,
#ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK
- show_cksums ? img->file_cksum : img->mem_base,
- show_datalen ? img->data_length : img->size,
+ show_cksums ? img.file_cksum : img.mem_base,
+ show_datalen ? img.data_length : img.size,
#else
- img->mem_base,
- img->size,
+ img.mem_base,
+ img.size,
#endif
- img->entry_point);
+ img.entry_point);
}
}
}
@@ -504,15 +503,17 @@ fis_list(int argc, char *argv[])
static void
fis_free(int argc, char *argv[])
{
- unsigned long *fis_ptr, *fis_end;
- unsigned long *area_start;
+ unsigned long fis_ptr, fis_end;
+ unsigned long area_start;
+ unsigned long temp;
// 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;
+ fis_ptr = CYGNUM_REDBOOT_FLASH_RESERVED_BASE;
+ fis_end = flash_size;
area_start = fis_ptr;
while (fis_ptr < fis_end) {
- if (*fis_ptr != (unsigned long)0xFFFFFFFF) {
+ flash_read(&flash_info, &temp, fis_ptr, sizeof(unsigned long), NULL);
+ if (temp != (unsigned long)0xFFFFFFFF) {
if (area_start != fis_ptr) {
// Assume that this is something
diag_printf(" 0x%08lX .. 0x%08lX\n",
@@ -521,7 +522,8 @@ fis_free(int argc, char *argv[])
// Find next blank block
area_start = fis_ptr;
while (area_start < fis_end) {
- if (*area_start == (unsigned long)0xFFFFFFFF) {
+ flash_read(&flash_info, &temp, area_start, sizeof(unsigned long), NULL);
+ if (temp == (unsigned long)0xFFFFFFFF) {
break;
}
area_start += flash_block_size / sizeof(CYG_ADDRESS);
@@ -545,8 +547,8 @@ fis_find_free(CYG_ADDRESS *addr, unsigne
unsigned long *area_start;
// 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;
+ fis_ptr = (unsigned long *)(CYGNUM_REDBOOT_FLASH_RESERVED_BASE);
+ fis_end = (unsigned long *)(CYG_ADDRESS)flash_size;
area_start = fis_ptr;
while (fis_ptr < fis_end) {
if (*fis_ptr != (unsigned long)0xFFFFFFFF) {
@@ -593,7 +595,7 @@ fis_create(int argc, char *argv[])
bool length_set = false;
bool img_size_set = false;
bool no_copy = false;
- void *err_addr;
+ unsigned long err_addr;
struct fis_image_desc *img = NULL;
bool defaults_assumed;
struct option_info opts[7];
@@ -619,7 +621,7 @@ fis_create(int argc, char *argv[])
return;
}
- memcpy(fis_work_block, fis_addr, fisdir_size);
+ flash_read(&flash_info, fis_work_block, fis_offset, fisdir_size, &err_addr);
defaults_assumed = false;
if (name) {
// Search existing files to acquire defaults for params not specified:
@@ -683,9 +685,9 @@ fis_create(int argc, char *argv[])
}
#endif
if (flash_addr_set &&
- ((stat = flash_verify_addr((void *)flash_addr)) ||
- (stat = flash_verify_addr((void *)(flash_addr+img_size-1))))) {
- _show_invalid_flash_address(flash_addr, stat);
+ ((stat = flash_verify_addr(&flash_info, flash_addr)) ||
+ (stat = flash_verify_addr(&flash_info, (flash_addr+img_size-1))))) {
+ _show_invalid_flash_offset(flash_addr, stat);
return;
}
if (flash_addr_set && flash_addr & (flash_block_size-1)) {
@@ -746,21 +748,29 @@ fis_create(int argc, char *argv[])
}
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))) {
+#ifdef CYGHWR_IO_FLASH_DEVICE_V2
+ if (flash_code_overlaps(&flash_info, flash_addr, (flash_addr+img_size-1))) {
+ diag_printf("Can't program this region - contains code in use!\n");
+ return;
+ }
+#else
+ if (flash_code_overlaps((void*)((cyg_uint8*)flash_info.start + flash_addr),
+ (void*)((cyg_uint8*)flash_info.start + flash_addr + img_size - 1))) {
diag_printf("Can't program this region - contains code in use!\n");
return;
}
+#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 = flash_erase(&flash_info, flash_addr, length, &err_addr)) != 0) {
+ diag_printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(&flash_info, 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 = flash_program(&flash_info, flash_addr, (void *)mem_addr, img_size, &err_addr)) != 0) {
+ diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(&flash_info, stat));
prog_ok = false;
}
}
@@ -787,7 +797,7 @@ fis_delete(int argc, char *argv[])
{
char *name;
int num_reserved, i, stat;
- void *err_addr;
+ unsigned long err_addr;
struct fis_image_desc *img;
if (!scan_opts(argc, argv, 2, 0, 0, (void **)&name, OPTION_ARG_TYPE_STR, "image name"))
@@ -795,11 +805,6 @@ fis_delete(int argc, char *argv[])
fis_usage("invalid arguments");
return;
}
-#ifdef CYGHWR_REDBOOT_ARM_FLASH_SIB
- // FIXME: this is somewhat half-baked
- arm_fis_delete(name);
- return;
-#endif
img = (struct fis_image_desc *)fis_work_block;
num_reserved = 0;
#ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE
@@ -821,7 +826,8 @@ fis_delete(int argc, char *argv[])
num_reserved++;
#endif
- memcpy(fis_work_block, fis_addr, fisdir_size);
+ flash_read(&flash_info, fis_work_block, fis_offset, fisdir_size, &err_addr);
+
img = fis_lookup(name, &i);
if (img) {
if (i < num_reserved) {
@@ -836,8 +842,8 @@ fis_delete(int argc, char *argv[])
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 = flash_erase(&flash_info, img->flash_base, img->size, &err_addr)) != 0) {
+ diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(&flash_info, stat));
} else {
img->name[0] = (unsigned char)0xFF;
fis_update_directory();
@@ -853,6 +859,7 @@ fis_load(int argc, char *argv[])
bool mem_addr_set = false;
bool show_cksum = false;
struct option_info opts[3];
+ unsigned long err_addr;
#ifdef CYGPKG_REDBOOT_FIS_CRC_CHECK
unsigned long cksum;
#endif
@@ -877,7 +884,8 @@ fis_load(int argc, char *argv[])
fis_usage("invalid arguments");
return;
}
- memcpy(fis_work_block, fis_addr, fisdir_size);
+
+ flash_read(&flash_info, fis_work_block, fis_offset, fisdir_size, &err_addr);
if ((img = fis_lookup(name, NULL)) == (struct fis_image_desc *)0) {
diag_printf("No image '%s' found\n", name);
return;
@@ -921,11 +929,11 @@ fis_load(int argc, char *argv[])
load_address_end = (unsigned long)p->out_buf;
// Reload fis directory
- memcpy(fis_work_block, fis_addr, fisdir_size);
+ flash_read(&flash_info, fis_work_block, fis_offset, fisdir_size);
} else // dangling block
#endif
{
- memcpy((void *)mem_addr, (void *)img->flash_base, img->data_length);
+ flash_read(&flash_info, (void *)mem_addr, img->flash_base, img->data_length, &err_addr);
// Set load address/top
load_address = mem_addr;
@@ -958,7 +966,7 @@ fis_write(int argc, char *argv[])
bool mem_addr_set = false;
bool flash_addr_set = false;
bool length_set = false;
- void *err_addr;
+ unsigned long err_addr;
struct option_info opts[3];
bool prog_ok;
@@ -984,9 +992,9 @@ fis_write(int argc, char *argv[])
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))))) {
- _show_invalid_flash_address(flash_addr, stat);
+ ((stat = flash_verify_addr(&flash_info, flash_addr)) ||
+ (stat = flash_verify_addr(&flash_info, (flash_addr+length-1))))) {
+ _show_invalid_flash_offset(flash_addr, stat);
return;
}
if (flash_addr_set && flash_addr & (flash_block_size-1)) {
@@ -1000,10 +1008,18 @@ fis_write(int argc, char *argv[])
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))) {
+#ifdef CYGHWR_IO_FLASH_DEVICE_V2
+ if (flash_code_overlaps(&flash_info, flash_addr, (flash_addr+length-1))) {
+ diag_printf("Can't program this region - contains code in use!\n");
+ return;
+ }
+#else
+ if (flash_code_overlaps((void*)((cyg_uint8*)flash_info.start + flash_addr),
+ (void*)((cyg_uint8*)flash_info.start + flash_addr + length - 1))) {
diag_printf("Can't program this region - contains code in use!\n");
return;
}
+#endif
if (!verify_action("* CAUTION * about to program FLASH\n at %p..%p from %p",
(void *)flash_addr, (void *)(flash_addr+length-1),
(void *)mem_addr)) {
@@ -1012,15 +1028,15 @@ fis_write(int argc, char *argv[])
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 = flash_erase(&flash_info, flash_addr, length, &err_addr)) != 0) {
+ diag_printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(&flash_info, 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 = flash_program(&flash_info, flash_addr, (void *)mem_addr, length, &err_addr)) != 0) {
+ diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(&flash_info, stat));
prog_ok = false;
}
}
@@ -1034,7 +1050,7 @@ fis_erase(int argc, char *argv[])
CYG_ADDRESS flash_addr;
bool flash_addr_set = false;
bool length_set = false;
- void *err_addr;
+ unsigned long err_addr;
struct option_info opts[2];
init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM,
@@ -1052,9 +1068,9 @@ fis_erase(int argc, char *argv[])
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);
+ ((stat = flash_verify_addr(&flash_info, flash_addr)) ||
+ (stat = flash_verify_addr(&flash_info, (flash_addr+length-1))))) {
+ _show_invalid_flash_offset(flash_addr, stat);
return;
}
if (flash_addr_set && flash_addr & (flash_block_size-1)) {
@@ -1063,12 +1079,20 @@ fis_erase(int argc, char *argv[])
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))) {
- diag_printf("Can't erase this region - contains code in use!\n");
+#ifdef CYGHWR_IO_FLASH_DEVICE_V2
+ if (flash_code_overlaps(&flash_info, flash_addr, (flash_addr+length-1))) {
+ diag_printf("Can't program 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));
+#else
+ if (flash_code_overlaps((void*)((cyg_uint8*)flash_info.start + flash_addr),
+ (void*)((cyg_uint8*)flash_info.start + flash_addr + length - 1))) {
+ diag_printf("Can't program this region - contains code in use!\n");
+ return;
+ }
+#endif
+ if ((stat = flash_erase(&flash_info, flash_addr, length, &err_addr)) != 0) {
+ diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(&flash_info, stat));
}
}
@@ -1083,7 +1107,7 @@ fis_lock(int argc, char *argv[])
CYG_ADDRESS flash_addr;
bool flash_addr_set = false;
bool length_set = false;
- void *err_addr;
+ unsigned long err_addr;
struct option_info opts[2];
init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM,
@@ -1099,7 +1123,7 @@ fis_lock(int argc, char *argv[])
/* Get parameters from image if specified */
if (name) {
struct fis_image_desc *img;
- memcpy(fis_work_block, fis_addr, fisdir_size);
+ flash_read(&flash_info, fis_work_block, fis_offset, fisdir_size, &err_addr);
if ((img = fis_lookup(name, NULL)) == (struct fis_image_desc *)0) {
diag_printf("No image '%s' found\n", name);
return;
@@ -1112,13 +1136,13 @@ fis_lock(int argc, char *argv[])
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);
+ ((stat = flash_verify_addr(&flash_info, flash_addr)) ||
+ (stat = flash_verify_addr(&flash_info, (flash_addr+length-1))))) {
+ _show_invalid_flash_offset(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 = flash_lock(&flash_info, flash_addr, length, &err_addr)) != 0) {
+ diag_printf("Error locking at %p: %s\n", err_addr, flash_errmsg(&flash_info, stat));
}
}
@@ -1131,7 +1155,7 @@ fis_unlock(int argc, char *argv[])
CYG_ADDRESS flash_addr;
bool flash_addr_set = false;
bool length_set = false;
- void *err_addr;
+ unsigned long err_addr;
struct option_info opts[2];
init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM,
@@ -1146,7 +1170,7 @@ fis_unlock(int argc, char *argv[])
if (name) {
struct fis_image_desc *img;
- memcpy(fis_work_block, fis_addr, fisdir_size);
+ flash_read(&flash_info, fis_work_block, fis_offset, fisdir_size, &err_addr);
if ((img = fis_lookup(name, NULL)) == (struct fis_image_desc *)0) {
diag_printf("No image '%s' found\n", name);
return;
@@ -1159,14 +1183,14 @@ fis_unlock(int argc, char *argv[])
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);
+ ((stat = flash_verify_addr(&flash_info, flash_addr)) ||
+ (stat = flash_verify_addr(&flash_info, (flash_addr+length-1))))) {
+ _show_invalid_flash_offset(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 = flash_unlock(&flash_info, flash_addr, length, &err_addr)) != 0) {
+ diag_printf("Error unlocking at %p: %s\n", err_addr, flash_errmsg(&flash_info, stat));
}
}
#endif
@@ -1178,8 +1202,9 @@ void
_flash_info(void)
{
if (!__flash_init) return;
- diag_printf("FLASH: %p - %p, %d blocks of %p bytes each.\n",
- flash_start, (CYG_ADDRWORD)flash_end + 1, flash_num_blocks, (void *)flash_block_size);
+ /* FIXME: +1 because somewhere we do -1 */
+ diag_printf("FLASH: size %p, %d blocks of %p bytes each.\n",
+ flash_size+1, flash_num_blocks, (void *)flash_block_size);
}
static bool
@@ -1188,15 +1213,18 @@ do_flash_init(void)
int stat;
if (!__flash_init) {
- if ((stat = flash_init((void *)(workspace_end-FLASH_MIN_WORKSPACE),
+ if ((stat = flash_init(&flash_info,
+ (void *)(workspace_end-FLASH_MIN_WORKSPACE),
FLASH_MIN_WORKSPACE, diag_printf)) != 0) {
- diag_printf("FLASH: driver init failed: %s\n", flash_errmsg(stat));
+ diag_printf("FLASH: driver init failed: %s\n", flash_errmsg(&flash_info, stat));
return false;
}
- flash_get_limits((void *)0, (void **)&flash_start, (void **)&flash_end);
+ flash_get_limit(&flash_info, &flash_size);
+
// 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);
+ flash_size = flash_size - 1;
+ flash_get_block_info(&flash_info, &flash_block_size, &flash_num_blocks);
+
workspace_end = (unsigned char *)(workspace_end-FLASH_MIN_WORKSPACE);
#ifdef CYGOPT_REDBOOT_FIS
# ifdef CYGOPT_REDBOOT_FIS_ZLIB_COMMON_BUFFER
@@ -1212,11 +1240,10 @@ do_flash_init(void)
# endif
fisdir_size = flash_block_size;
if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) {
- fis_addr = (void *)((CYG_ADDRESS)flash_end + 1 +
+ fis_offset = (flash_size + 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_offset = (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*flash_block_size);
}
#endif
__flash_init = 1;
@@ -1813,8 +1840,8 @@ flash_write_config(void)
{
#ifndef CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG
int stat;
- void *err_addr;
#endif
+ unsigned long err_addr;
config->len = sizeof(struct _config);
config->key1 = CONFIG_KEY1;
@@ -1822,25 +1849,25 @@ flash_write_config(void)
config->cksum = cyg_crc32((unsigned char *)config, sizeof(struct _config)-sizeof(config->cksum));
if (verify_action("Update RedBoot non-volatile configuration")) {
#ifdef CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG
- memcpy(fis_work_block, fis_addr, fisdir_size);
+ flash_read(&flash_info, fis_work_block, fis_offset, fisdir_size, &err_addr);
fis_update_directory();
#else // CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG
#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);
+ flash_unlock(&flash_info, 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 = flash_erase(&flash_info, cfg_base, cfg_size, &err_addr)) != 0) {
+ diag_printf(" initialization failed at %p: %s\n", err_addr, flash_errmsg(&flash_info, stat));
} else {
- if ((stat = flash_program(cfg_base, (void *)config, sizeof(struct _config),
- (void **)&err_addr)) != 0) {
+ if ((stat = flash_program(&flash_info, 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));
+ err_addr, flash_errmsg(&flash_info, stat));
}
}
#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);
+ flash_lock(&flash_info, cfg_base, cfg_size, &err_addr);
#endif
#endif
}
@@ -1880,6 +1907,7 @@ flash_get_config(char *key, void *val, i
void *val_ptr;
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG_READONLY_FALLBACK
struct _config *save_config = 0;
+ unsigned long err_addr;
#endif
if (!config_ok) return false;
@@ -2062,6 +2090,7 @@ static void
load_flash_config(void)
{
bool use_boot_script;
+ unsigned long err_addr;
config_ok = false;
script = (unsigned char *)0;
@@ -2080,20 +2109,19 @@ load_flash_config(void)
return;
}
fisdir_size = flash_block_size - cfg_size;
- cfg_base = (void *)(((CYG_ADDRESS)fis_addr + flash_block_size) - cfg_size);
+ cfg_base = fis_offset + flash_block_size - cfg_size;
#else
if (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK < 0) {
- cfg_base = (void *)((CYG_ADDRESS)flash_end + 1 -
+ cfg_base = (flash_size + 1 -
_rup(_rup((-CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*flash_block_size), cfg_size), flash_block_size));
} else {
- cfg_base = (void *)((CYG_ADDRESS)flash_start +
- _rup(_rup((CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*flash_block_size), cfg_size), flash_block_size));
+ cfg_base = (_rup(_rup((CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*flash_block_size), cfg_size), flash_block_size));
}
#endif
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG_READONLY_FALLBACK
- readonly_config = cfg_base;
+ readonly_config_offset = cfg_base;
#endif
- memcpy(config, cfg_base, sizeof(struct _config));
+ flash_read(&flash_info, config, cfg_base, sizeof(struct _config), &err_addr);
if ((cyg_crc32((unsigned char *)config,
sizeof(struct _config)-sizeof(config->cksum)) != config->cksum) ||
(config->key1 != CONFIG_KEY1)|| (config->key2 != CONFIG_KEY2)) {
-------------- next part --------------
--
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss
More information about the Ecos-discuss
mailing list