flash/nor: Add erased_value to drivers and pass it to targets
struct flash_driver has a default_padded_value field that is similar, but it can be changed by the user for the specific purpose of padding. Add a new erased_value field and initialize it for all targets, particularly stm32lx, xmc4xxx and virtual. Use this value in core.c:default_flash_mem_blank_check(), the slow path. Extend the target API to pass erased_value down to target code. Adding an argument ensures that we catch all callers. This allows us to merge xmc4xxx.c:xmc4xxx_blank_check_memory() into armv7m:armv7m_blank_check_memory(). It further allows us to use default_flash_blank_check() in place of xmc4xxx.c:xmc4xxx_flash_blank_check(), adding a potential slow path fallback, as well as stm32lx:stm32lx_erase_check(), adding the potential armv7m fast path with fallback to default_flash_mem_blank_check(). Fix a mips32 code comment while at it (zeroed -> erased). The armv4_5 and mips32 target implementations will now error out if an erase value other than 0xff is used, causing default_flash_blank_check() to fall back to the default_flank_mem_blank_check() slow path. Change-Id: I39323fbbc4b71c256cd567e439896d0245d4745f Signed-off-by: Andreas Färber <afaerber@suse.de> Reviewed-on: http://openocd.zylin.com/3497 Tested-by: jenkins Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
This commit is contained in:
committed by
Andreas Fritiofson
parent
b9ee6dd465
commit
eaacb900dd
@@ -300,7 +300,7 @@ FLASH_BANK_COMMAND_HANDLER(stm32lx_flash_bank_command)
|
||||
stm32lx_info->user_bank_size = bank->size;
|
||||
|
||||
/* the stm32l erased value is 0x00 */
|
||||
bank->default_padded_value = 0x00;
|
||||
bank->default_padded_value = bank->erased_value = 0x00;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
@@ -884,56 +884,6 @@ static int stm32lx_auto_probe(struct flash_bank *bank)
|
||||
return stm32lx_probe(bank);
|
||||
}
|
||||
|
||||
static int stm32lx_erase_check(struct flash_bank *bank)
|
||||
{
|
||||
struct target *target = bank->target;
|
||||
const int buffer_size = 4096;
|
||||
int i;
|
||||
uint32_t nBytes;
|
||||
int retval = ERROR_OK;
|
||||
|
||||
if (bank->target->state != TARGET_HALTED) {
|
||||
LOG_ERROR("Target not halted");
|
||||
return ERROR_TARGET_NOT_HALTED;
|
||||
}
|
||||
|
||||
uint8_t *buffer = malloc(buffer_size);
|
||||
if (buffer == NULL) {
|
||||
LOG_ERROR("failed to allocate read buffer");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
for (i = 0; i < bank->num_sectors; i++) {
|
||||
uint32_t j;
|
||||
bank->sectors[i].is_erased = 1;
|
||||
|
||||
/* Loop chunk by chunk over the sector */
|
||||
for (j = 0; j < bank->sectors[i].size; j += buffer_size) {
|
||||
uint32_t chunk;
|
||||
chunk = buffer_size;
|
||||
if (chunk > (j - bank->sectors[i].size))
|
||||
chunk = (j - bank->sectors[i].size);
|
||||
|
||||
retval = target_read_memory(target, bank->base
|
||||
+ bank->sectors[i].offset + j, 4, chunk / 4, buffer);
|
||||
if (retval != ERROR_OK)
|
||||
break;
|
||||
|
||||
for (nBytes = 0; nBytes < chunk; nBytes++) {
|
||||
if (buffer[nBytes] != 0x00) {
|
||||
bank->sectors[i].is_erased = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (retval != ERROR_OK)
|
||||
break;
|
||||
}
|
||||
free(buffer);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* This method must return a string displaying information about the bank */
|
||||
static int stm32lx_get_info(struct flash_bank *bank, char *buf, int buf_size)
|
||||
{
|
||||
@@ -1022,7 +972,7 @@ struct flash_driver stm32lx_flash = {
|
||||
.read = default_flash_read,
|
||||
.probe = stm32lx_probe,
|
||||
.auto_probe = stm32lx_auto_probe,
|
||||
.erase_check = stm32lx_erase_check,
|
||||
.erase_check = default_flash_blank_check,
|
||||
.protect_check = stm32lx_protect_check,
|
||||
.info = stm32lx_get_info,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user