X-Git-Url: https://git.karo-electronics.de/?p=karo-tx-redboot.git;a=blobdiff_plain;f=packages%2Fio%2Fflash%2Fv2_0%2Fsrc%2Fflash.c;h=59725c5083fc252919b6c8ed9b85412ced7b5d5c;hp=aee6b861c522a76affdf2ca92f06c1a21eb70088;hb=4c2006ffbdfc5374f88746332a30f8356deecc69;hpb=ed79ec1d7b8f717e56b493c21422d78d39ebbcde diff --git a/packages/io/flash/v2_0/src/flash.c b/packages/io/flash/v2_0/src/flash.c index aee6b861..59725c50 100644 --- a/packages/io/flash/v2_0/src/flash.c +++ b/packages/io/flash/v2_0/src/flash.c @@ -44,12 +44,13 @@ // Author(s): gthomas // Contributors: gthomas // Date: 2000-07-26 -// Purpose: -// Description: -// +// Purpose: +// Description: +// //####DESCRIPTIONEND#### // //========================================================================== + #include #include @@ -84,17 +85,17 @@ externC code_fun flash_unlock_block; 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 @@ -111,285 +112,286 @@ static void *__anonymizer(void *p) 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); - } + /* 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("... 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 } @@ -398,65 +400,65 @@ flash_read(void *_addr, void *_data, int len, void **err_addr) 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 @@ -526,38 +528,38 @@ flash_unlock(void *addr, int len, void **err_addr) 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