// Author(s): gthomas
// Contributors: gthomas
// Date: 2000-07-26
-// Purpose:
-// Description:
-//
+// Purpose:
+// Description:
+//
//####DESCRIPTIONEND####
//
//==========================================================================
-
#include <pkgconf/system.h>
#include <pkgconf/io_flash.h>
int
flash_init(_printf *pf)
{
- int err;
+ int err;
- flash_info.pf = pf; // Do this before calling into the driver
- if (flash_info.init) return FLASH_ERR_OK;
+ flash_info.pf = pf; // Do this before calling into the driver
+ if (flash_info.init) return FLASH_ERR_OK;
- if ((err = flash_hwr_init()) != FLASH_ERR_OK) {
- return err;
- }
- flash_info.block_mask = ~(flash_info.block_size-1);
- flash_info.init = 1;
- return FLASH_ERR_OK;
+ if ((err = flash_hwr_init()) != FLASH_ERR_OK) {
+ return err;
+ }
+ flash_info.block_mask = ~(flash_info.block_size - 1);
+ flash_info.init = 1;
+ return FLASH_ERR_OK;
}
// Use this function to make function pointers anonymous - forcing the
void
flash_dev_query(void *data)
{
- typedef void code_fun(void *);
- code_fun *_flash_query;
- int d_cache, i_cache;
+ typedef void code_fun(void *);
+ code_fun *_flash_query;
+ int d_cache, i_cache;
- _flash_query = (code_fun*)__anonymizer(&flash_query);
+ _flash_query = (code_fun*)__anonymizer(&flash_query);
- HAL_FLASH_CACHES_OFF(d_cache, i_cache);
- (*_flash_query)(data);
- HAL_FLASH_CACHES_ON(d_cache, i_cache);
+ HAL_FLASH_CACHES_OFF(d_cache, i_cache);
+ (*_flash_query)(data);
+ HAL_FLASH_CACHES_ON(d_cache, i_cache);
}
int
flash_verify_addr(void *target)
{
- 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))) {
- return FLASH_ERR_OK;
- } else {
- return FLASH_ERR_INVALID;
- }
+ 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))) {
+ return FLASH_ERR_OK;
+ } else {
+ return FLASH_ERR_INVALID;
+ }
}
int
flash_get_limits(void *target, void **start, void **end)
{
- if (!flash_info.init) {
- return FLASH_ERR_NOT_INIT;
- }
- *start = flash_info.start;
- *end = flash_info.end;
- return FLASH_ERR_OK;
+ if (!flash_info.init) {
+ return FLASH_ERR_NOT_INIT;
+ }
+ *start = flash_info.start;
+ *end = flash_info.end;
+ return FLASH_ERR_OK;
}
int
flash_get_block_info(int *block_size, int *blocks)
{
- if (!flash_info.init) {
- return FLASH_ERR_NOT_INIT;
- }
- *block_size = flash_info.block_size;
- *blocks = flash_info.blocks;
- return FLASH_ERR_OK;
+ if (!flash_info.init) {
+ return FLASH_ERR_NOT_INIT;
+ }
+ *block_size = flash_info.block_size;
+ *blocks = flash_info.blocks;
+ return FLASH_ERR_OK;
}
int
flash_erase(void *addr, int len, void **err_addr)
{
- unsigned short *block, *end_addr;
- int stat = 0;
- typedef int code_fun(unsigned short *, unsigned int);
- code_fun *_flash_erase_block;
- int d_cache, i_cache;
+ unsigned short *block, *end_addr;
+ int stat = 0;
+ typedef int code_fun(unsigned short *, unsigned int);
+ code_fun *_flash_erase_block;
+ int d_cache, i_cache;
- if (!flash_info.init) {
- return FLASH_ERR_NOT_INIT;
- }
+ if (!flash_info.init) {
+ return FLASH_ERR_NOT_INIT;
+ }
#ifdef CYGSEM_IO_FLASH_SOFT_WRITE_PROTECT
- if (plf_flash_query_soft_wp(addr,len))
- return FLASH_ERR_PROTECT;
+ if (plf_flash_query_soft_wp(addr,len))
+ return FLASH_ERR_PROTECT;
#endif
- _flash_erase_block = (code_fun*)__anonymizer(&flash_erase_block);
+ _flash_erase_block = (code_fun*)__anonymizer(&flash_erase_block);
- block = (unsigned short *)((CYG_ADDRESS)addr & flash_info.block_mask);
- end_addr = (unsigned short *)((CYG_ADDRESS)addr + len);
+ block = (unsigned short *)((CYG_ADDRESS)addr & flash_info.block_mask);
+ end_addr = (unsigned short *)((CYG_ADDRESS)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);
- }
+ /* Check to see if end_addr overflowed */
+ if ((end_addr < block) && (len > 0)) {
+ end_addr = (unsigned short *)((CYG_ADDRESS)flash_info.end);
+ }
#ifdef CYGSEM_IO_FLASH_CHATTER
- flash_info.pf("... Erase from %p-%p: ", block, end_addr);
+ flash_info.pf("... Erase from %p-%p: ", block, end_addr);
#endif
- HAL_FLASH_CACHES_OFF(d_cache, i_cache);
- FLASH_Enable(block, end_addr);
- while (block < end_addr) {
- // Supply the blocksize for a gross check for erase success
- unsigned short *tmp_block;
+ HAL_FLASH_CACHES_OFF(d_cache, i_cache);
+ FLASH_Enable(block, end_addr);
+ while (block < end_addr) {
+ // Supply the blocksize for a gross check for erase success
+ unsigned short *tmp_block;
#if !defined(CYGSEM_IO_FLASH_READ_INDIRECT)
- int i;
- unsigned char *dp;
- bool erased = true;
-
- dp = (unsigned char *)block;
- for (i = 0; i < flash_info.block_size; i++) {
- if (*dp++ != 0xFF) {
- erased = false;
- break;
- }
- }
+ int i;
+ unsigned char *dp;
+ bool erased = true;
+
+ dp = (unsigned char *)block;
+ for (i = 0; i < flash_info.block_size; i++) {
+ if (*dp++ != 0xFF) {
+ erased = false;
+ break;
+ }
+ }
#else
- bool erased = false;
+ bool erased = false;
#endif
- if (!erased) {
- stat = (*_flash_erase_block)(block, flash_info.block_size);
- stat = flash_hwr_map_error(stat);
- }
- if (stat) {
- *err_addr = block;
- break;
- }
-
- // Check to see if block will overflow
- tmp_block = block + flash_info.block_size / sizeof(*block);
- if (tmp_block < block) {
- // If block address overflows, set block value to end on this loop
- block = end_addr;
- } else {
- block = tmp_block;
- }
+ if (!erased) {
+ stat = (*_flash_erase_block)(block, flash_info.block_size);
+ stat = flash_hwr_map_error(stat);
+ }
+ if (stat) {
+ *err_addr = block;
+ break;
+ }
+
+ // Check to see if block will overflow
+ tmp_block = block + flash_info.block_size / sizeof(*block);
+ if (tmp_block < block) {
+ // If block address overflows, set block value to end on this loop
+ block = end_addr;
+ } else {
+ block = tmp_block;
+ }
#ifdef CYGSEM_IO_FLASH_CHATTER
- flash_info.pf(".");
+ flash_info.pf(".");
#endif
- }
- FLASH_Disable((void *)((CYG_ADDRESS)addr & flash_info.block_mask),
- end_addr);
- HAL_FLASH_CACHES_ON(d_cache, i_cache);
+ }
+ FLASH_Disable((void *)((CYG_ADDRESS)addr & flash_info.block_mask),
+ end_addr);
+ HAL_FLASH_CACHES_ON(d_cache, i_cache);
#ifdef CYGSEM_IO_FLASH_CHATTER
- flash_info.pf("\n");
+ flash_info.pf("\n");
#endif
- return stat;
+ return stat;
}
int
flash_program(void *_addr, void *_data, int len, void **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 = _addr;
- unsigned char *data = _data;
- CYG_ADDRESS tmp;
- int d_cache, i_cache;
-
- if (!flash_info.init) {
- return FLASH_ERR_NOT_INIT;
- }
+ int stat = 0;
+ int size;
+ typedef int code_fun(void *, void *, int, unsigned long, int);
+ code_fun *_flash_program_buf;
+ unsigned char *addr = _addr;
+ unsigned char *data = _data;
+ CYG_ADDRESS tmp;
+ int d_cache, i_cache;
+
+ if (!flash_info.init) {
+ return FLASH_ERR_NOT_INIT;
+ }
#ifdef CYGSEM_IO_FLASH_SOFT_WRITE_PROTECT
- if (plf_flash_query_soft_wp(addr,len))
- return FLASH_ERR_PROTECT;
+ if (plf_flash_query_soft_wp(addr,len))
+ return FLASH_ERR_PROTECT;
#endif
- _flash_program_buf = (code_fun*)__anonymizer(&flash_program_buf);
+ _flash_program_buf = (code_fun*)__anonymizer(&flash_program_buf);
#ifdef CYGSEM_IO_FLASH_CHATTER
- flash_info.pf("... Program from %p-%p at %p: ", data,
- (void *)((CYG_ADDRESS)data + len), addr);
+ flash_info.pf("... Program from %p-%p at %p: ", data,
+ (void *)((CYG_ADDRESS)data + len), addr);
#endif
- HAL_FLASH_CACHES_OFF(d_cache, i_cache);
- FLASH_Enable(addr, addr + len);
- while (len > 0) {
- size = len;
+ HAL_FLASH_CACHES_OFF(d_cache, i_cache);
+ FLASH_Enable(addr, addr + len);
+ while (len > 0) {
+ size = len;
#if defined(MXCFLASH_SELECT_NAND) || defined(MXCFLASH_SELECT_MMC)
- if (flash_info.start != 0)
+ if (flash_info.start != 0)
#endif
- 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;
- if (tmp) {
- tmp = flash_info.block_size - tmp;
- if (size > tmp) size = tmp;
- }
+ tmp = (CYG_ADDRESS)addr & ~flash_info.block_mask;
+ if (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);
- stat = flash_hwr_map_error(stat);
+ stat = (*_flash_program_buf)(addr, data, size,
+ flash_info.block_mask, flash_info.buffer_size);
+ stat = flash_hwr_map_error(stat);
#ifdef CYGSEM_IO_FLASH_VERIFY_PROGRAM
- if (0 == stat) // Claims to be OK
- if (memcmp(addr, data, size) != 0) {
- stat = 0x0BAD;
+ if (0 == stat) // Claims to be OK
+ if (memcmp(addr, data, size) != 0) {
+ stat = 0x0BAD;
#ifdef CYGSEM_IO_FLASH_CHATTER
- flash_info.pf("V");
+ flash_info.pf("V");
#endif
- }
+ }
#endif
- if (stat) {
- *err_addr = addr;
- break;
- }
+ if (stat) {
+ *err_addr = addr;
+ break;
+ }
#ifdef CYGSEM_IO_FLASH_CHATTER
- flash_info.pf(".");
+ flash_info.pf(".");
#endif
- len -= size;
- addr += size / sizeof(*addr);
- data += size / sizeof(*data);
- }
- FLASH_Disable(_addr, addr + len);
- HAL_FLASH_CACHES_ON(d_cache, i_cache);
+ len -= size;
+ addr += size / sizeof(*addr);
+ data += size / sizeof(*data);
+ }
+ FLASH_Disable(_addr, addr + len);
+ HAL_FLASH_CACHES_ON(d_cache, i_cache);
#ifdef CYGSEM_IO_FLASH_CHATTER
- flash_info.pf("\n");
+ flash_info.pf("\n");
#endif
- return stat;
+ return stat;
}
int
flash_read(void *_addr, void *_data, int len, void **err_addr)
{
#ifdef CYGSEM_IO_FLASH_READ_INDIRECT
- int stat = 0;
- int size;
- typedef int code_fun(void *, void *, int, unsigned long, int);
- code_fun *_flash_read_buf;
- unsigned char *addr = _addr;
- unsigned char *data = _data;
- CYG_ADDRESS tmp;
- int d_cache, i_cache;
+ int stat = 0;
+ int size;
+ typedef int code_fun(void *, void *, int, unsigned long, int);
+ code_fun *_flash_read_buf;
+ unsigned char *addr = _addr;
+ unsigned char *data = _data;
+ CYG_ADDRESS tmp;
+ int d_cache, i_cache;
- if (!flash_info.init) {
- return FLASH_ERR_NOT_INIT;
- }
+ if (!flash_info.init) {
+ return FLASH_ERR_NOT_INIT;
+ }
- _flash_read_buf = (code_fun*)__anonymizer(&flash_read_buf);
+ _flash_read_buf = (code_fun*)__anonymizer(&flash_read_buf);
#ifdef CYGSEM_IO_FLASH_CHATTER_VERBOSE
- flash_info.pf("... Read from %p-%p at %p: ", data,
- (void *)((CYG_ADDRESS)data + len), addr);
+ flash_info.pf("... Read from %p-%p at %p: ", data,
+ (void *)((CYG_ADDRESS)data + len), addr);
#endif
- HAL_FLASH_CACHES_OFF(d_cache, i_cache);
- FLASH_Enable(addr, addr + len);
- while (len > 0) {
- size = len;
+ HAL_FLASH_CACHES_OFF(d_cache, i_cache);
+ FLASH_Enable(addr, addr + len);
+ while (len > 0) {
+ size = len;
#if defined(MXCFLASH_SELECT_NAND) || defined(MXCFLASH_SELECT_MMC)
- if (flash_info.start !=0)
+ if (flash_info.start != 0)
#endif
- 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;
- if (tmp) {
- tmp = flash_info.block_size - tmp;
- if (size>tmp) size = tmp;
-
- }
+ tmp = (CYG_ADDRESS)addr & ~flash_info.block_mask;
+ if (tmp) {
+ tmp = flash_info.block_size - tmp;
+ if (size>tmp) size = tmp;
+ }
- stat = (*_flash_read_buf)(addr, data, size,
- flash_info.block_mask, flash_info.buffer_size);
- stat = flash_hwr_map_error(stat);
+ stat = (*_flash_read_buf)(addr, data, size,
+ flash_info.block_mask, flash_info.buffer_size);
+ stat = flash_hwr_map_error(stat);
#ifdef CYGSEM_IO_FLASH_VERIFY_PROGRAM
- if (0 == stat) // Claims to be OK
- if (memcmp(addr, data, size) != 0) {
- stat = 0x0BAD;
+ if (0 == stat) // Claims to be OK
+ if (memcmp(addr, data, size) != 0) {
+ stat = 0x0BAD;
#ifdef CYGSEM_IO_FLASH_CHATTER_VERBOSE
- flash_info.pf("V");
+ flash_info.pf("V");
#endif
- }
+ }
#endif
- if (stat) {
- *err_addr = addr;
- break;
- }
+ if (stat) {
+ *err_addr = addr;
+ break;
+ }
#ifdef CYGSEM_IO_FLASH_CHATTER_VERBOSE
- flash_info.pf(".");
+ flash_info.pf(".");
#endif
- len -= size;
- addr += size / sizeof(*addr);
- data += size / sizeof(*data);
- }
- FLASH_Disable(_addr, addr + len);
- HAL_FLASH_CACHES_ON(d_cache, i_cache);
+ len -= size;
+ addr += size / sizeof(*addr);
+ data += size / sizeof(*data);
+ }
+ FLASH_Disable(_addr, addr + len);
+ HAL_FLASH_CACHES_ON(d_cache, i_cache);
#ifdef CYGSEM_IO_FLASH_CHATTER_VERBOSE
- flash_info.pf("\n");
+ flash_info.pf("\n");
#endif
- return stat;
+ return stat;
#else // CYGSEM_IO_FLASH_READ_INDIRECT
- // Direct access to FLASH memory is possible - just move the requested bytes
- if (!flash_info.init) {
- return FLASH_ERR_NOT_INIT;
- }
- memcpy(_data, _addr, len);
- return FLASH_ERR_OK;
+ // Direct access to FLASH memory is possible - just move the requested bytes
+ if (!flash_info.init) {
+ return FLASH_ERR_NOT_INIT;
+ }
+ memcpy(_data, _addr, len);
+ return FLASH_ERR_OK;
#endif
}
int
flash_lock(void *addr, int len, void **err_addr)
{
- unsigned short *block, *end_addr;
- int stat = 0;
- typedef int code_fun(unsigned short *);
- code_fun *_flash_lock_block;
- int d_cache, i_cache;
+ unsigned short *block, *end_addr;
+ int stat = 0;
+ typedef int code_fun(unsigned short *);
+ code_fun *_flash_lock_block;
+ int d_cache, i_cache;
- if (!flash_info.init) {
- return FLASH_ERR_NOT_INIT;
- }
+ if (!flash_info.init) {
+ return FLASH_ERR_NOT_INIT;
+ }
#ifdef CYGSEM_IO_FLASH_SOFT_WRITE_PROTECT
- if (plf_flash_query_soft_wp(addr,len))
- return FLASH_ERR_PROTECT;
+ if (plf_flash_query_soft_wp(addr,len))
+ return FLASH_ERR_PROTECT;
#endif
- _flash_lock_block = (code_fun*)__anonymizer(&flash_lock_block);
+ _flash_lock_block = (code_fun*)__anonymizer(&flash_lock_block);
- block = (unsigned short *)((CYG_ADDRESS)addr & flash_info.block_mask);
- end_addr = (unsigned short *)((CYG_ADDRESS)addr + len);
+ block = (unsigned short *)((CYG_ADDRESS)addr & flash_info.block_mask);
+ end_addr = (unsigned short *)((CYG_ADDRESS)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);
- }
+ /* Check to see if end_addr overflowed */
+ if ((end_addr < block) && (len > 0)) {
+ end_addr = (unsigned short *)((CYG_ADDRESS)flash_info.end - 1);
+ }
#ifdef CYGSEM_IO_FLASH_CHATTER
- flash_info.pf("... Lock from %p-%p: ", block, end_addr);
+ flash_info.pf("... Lock from %p-%p: ", block, end_addr);
#endif
- 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);
- stat = flash_hwr_map_error(stat);
- if (stat) {
- *err_addr = block;
- break;
- }
-
- // Check to see if block will overflow
- tmp_block = block + flash_info.block_size / sizeof(*block);
- if (tmp_block < block) {
- // If block address overflows, set block value to end on this loop
- block = end_addr;
- } else {
- block = tmp_block;
- }
+ 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);
+ stat = flash_hwr_map_error(stat);
+ if (stat) {
+ *err_addr = block;
+ break;
+ }
+
+ // Check to see if block will overflow
+ tmp_block = block + flash_info.block_size / sizeof(*block);
+ if (tmp_block < block) {
+ // If block address overflows, set block value to end on this loop
+ block = end_addr;
+ } else {
+ block = tmp_block;
+ }
#ifdef CYGSEM_IO_FLASH_CHATTER
- flash_info.pf(".");
+ flash_info.pf(".");
#endif
- }
- FLASH_Disable((void *)((CYG_ADDRESS)addr & flash_info.block_mask),
- end_addr);
- HAL_FLASH_CACHES_ON(d_cache, i_cache);
+ }
+ FLASH_Disable((void *)((CYG_ADDRESS)addr & flash_info.block_mask),
+ end_addr);
+ HAL_FLASH_CACHES_ON(d_cache, i_cache);
#ifdef CYGSEM_IO_FLASH_CHATTER
- flash_info.pf("\n");
+ flash_info.pf("\n");
#endif
- return stat;
+ return stat;
}
int
char *
flash_errmsg(int err)
{
- switch (err) {
- case FLASH_ERR_OK:
- return "No error - operation complete";
- case FLASH_ERR_ERASE_SUSPEND:
- return "Device is in erase suspend state";
- case FLASH_ERR_PROGRAM_SUSPEND:
- return "Device is in program suspend state";
- case FLASH_ERR_INVALID:
- return "Invalid FLASH address";
- case FLASH_ERR_ERASE:
- return "Error trying to erase";
- case FLASH_ERR_LOCK:
- return "Error trying to lock/unlock";
- case FLASH_ERR_PROGRAM:
- return "Error trying to program";
- case FLASH_ERR_PROTOCOL:
- return "Generic error";
- case FLASH_ERR_PROTECT:
- return "Device/region is write-protected";
- case FLASH_ERR_NOT_INIT:
- return "FLASH sub-system not initialized";
- case FLASH_ERR_DRV_VERIFY:
- return "Data verify failed after operation";
- case FLASH_ERR_DRV_TIMEOUT:
- return "Driver timed out waiting for device";
- case FLASH_ERR_DRV_WRONG_PART:
- return "Driver does not support device";
- case FLASH_ERR_LOW_VOLTAGE:
- return "Device reports low voltage";
- default:
- return "Unknown error";
- }
+ switch (err) {
+ case FLASH_ERR_OK:
+ return "No error - operation complete";
+ case FLASH_ERR_ERASE_SUSPEND:
+ return "Device is in erase suspend state";
+ case FLASH_ERR_PROGRAM_SUSPEND:
+ return "Device is in program suspend state";
+ case FLASH_ERR_INVALID:
+ return "Invalid FLASH address";
+ case FLASH_ERR_ERASE:
+ return "Error trying to erase";
+ case FLASH_ERR_LOCK:
+ return "Error trying to lock/unlock";
+ case FLASH_ERR_PROGRAM:
+ return "Error trying to program";
+ case FLASH_ERR_PROTOCOL:
+ return "Generic error";
+ case FLASH_ERR_PROTECT:
+ return "Device/region is write-protected";
+ case FLASH_ERR_NOT_INIT:
+ return "FLASH sub-system not initialized";
+ case FLASH_ERR_DRV_VERIFY:
+ return "Data verify failed after operation";
+ case FLASH_ERR_DRV_TIMEOUT:
+ return "Driver timed out waiting for device";
+ case FLASH_ERR_DRV_WRONG_PART:
+ return "Driver does not support device";
+ case FLASH_ERR_LOW_VOLTAGE:
+ return "Device reports low voltage";
+ default:
+ return "Unknown error";
+ }
}
// EOF io/flash/..../flash.c