static int at91sam7_erase_check(struct flash_bank *bank)
{
- struct target *target = bank->target;
- uint16_t retval;
- uint32_t blank;
- uint16_t fast_check;
- uint8_t *buffer;
- uint16_t nSector;
- uint16_t nByte;
-
if (bank->target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
at91sam7_read_clock_info(bank);
at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
- fast_check = 1;
- for (nSector = 0; nSector < bank->num_sectors; nSector++) {
- retval = target_blank_check_memory(target,
- bank->base + bank->sectors[nSector].offset,
- bank->sectors[nSector].size,
- &blank, bank->erased_value);
- if (retval != ERROR_OK) {
- fast_check = 0;
- break;
- }
- if (blank == 0xFF)
- bank->sectors[nSector].is_erased = 1;
- else
- bank->sectors[nSector].is_erased = 0;
- }
-
- if (fast_check)
- return ERROR_OK;
-
- LOG_USER("Running slow fallback erase check - add working memory");
-
- buffer = malloc(bank->sectors[0].size);
- for (nSector = 0; nSector < bank->num_sectors; nSector++) {
- bank->sectors[nSector].is_erased = 1;
- retval = target_read_memory(target, bank->base + bank->sectors[nSector].offset, 4,
- bank->sectors[nSector].size/4, buffer);
- if (retval != ERROR_OK)
- return retval;
-
- for (nByte = 0; nByte < bank->sectors[nSector].size; nByte++) {
- if (buffer[nByte] != 0xFF) {
- bank->sectors[nSector].is_erased = 0;
- break;
- }
- }
- }
- free(buffer);
-
- return ERROR_OK;
+ return default_flash_blank_check(bank);
}
static int at91sam7_protect_check(struct flash_bank *bank)
struct target *target = bank->target;
int i;
int retval;
- int fast_check = 0;
- uint32_t blank;
if (bank->target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
}
+ struct target_memory_check_block *block_array;
+ block_array = malloc(bank->num_sectors * sizeof(struct target_memory_check_block));
+ if (block_array == NULL)
+ return default_flash_mem_blank_check(bank);
+
for (i = 0; i < bank->num_sectors; i++) {
- uint32_t address = bank->base + bank->sectors[i].offset;
- uint32_t size = bank->sectors[i].size;
+ block_array[i].address = bank->base + bank->sectors[i].offset;
+ block_array[i].size = bank->sectors[i].size;
+ block_array[i].result = UINT32_MAX; /* erase state unknown */
+ }
- retval = target_blank_check_memory(target, address, size, &blank, bank->erased_value);
- if (retval != ERROR_OK) {
- fast_check = 0;
+ bool fast_check = true;
+ for (i = 0; i < bank->num_sectors; ) {
+ retval = target_blank_check_memory(target,
+ block_array + i, bank->num_sectors - i,
+ bank->erased_value);
+ if (retval < 1) {
+ /* Run slow fallback if the first run gives no result
+ * otherwise use possibly incomplete results */
+ if (i == 0)
+ fast_check = false;
break;
}
- if (blank == bank->erased_value)
- bank->sectors[i].is_erased = 1;
- else
- bank->sectors[i].is_erased = 0;
- fast_check = 1;
+ i += retval; /* add number of blocks done this round */
}
- if (!fast_check) {
+ if (fast_check) {
+ for (i = 0; i < bank->num_sectors; i++)
+ bank->sectors[i].is_erased = block_array[i].result;
+ retval = ERROR_OK;
+ } else {
LOG_USER("Running slow fallback erase check - add working memory");
- return default_flash_mem_blank_check(bank);
+ retval = default_flash_mem_blank_check(bank);
}
+ free(block_array);
- return ERROR_OK;
+ return retval;
}
/* Manipulate given flash region, selecting the bank according to target
int arm_checksum_memory(struct target *target,
target_addr_t address, uint32_t count, uint32_t *checksum);
int arm_blank_check_memory(struct target *target,
- target_addr_t address, uint32_t count, uint32_t *blank, uint8_t erased_value);
+ struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value);
void arm_set_cpsr(struct arm *arm, uint32_t cpsr);
struct reg *arm_reg_current(struct arm *arm, unsigned regnum);
*
*/
int arm_blank_check_memory(struct target *target,
- target_addr_t address, uint32_t count, uint32_t *blank, uint8_t erased_value)
+ struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value)
{
struct working_area *check_algorithm;
struct reg_param reg_params[3];
arm_algo.core_state = ARM_STATE_ARM;
init_reg_param(®_params[0], "r0", 32, PARAM_OUT);
- buf_set_u32(reg_params[0].value, 0, 32, address);
+ buf_set_u32(reg_params[0].value, 0, 32, blocks[0].address);
init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
- buf_set_u32(reg_params[1].value, 0, 32, count);
+ buf_set_u32(reg_params[1].value, 0, 32, blocks[0].size);
init_reg_param(®_params[2], "r2", 32, PARAM_IN_OUT);
buf_set_u32(reg_params[2].value, 0, 32, erased_value);
10000, &arm_algo);
if (retval == ERROR_OK)
- *blank = buf_get_u32(reg_params[2].value, 0, 32);
+ blocks[0].result = buf_get_u32(reg_params[2].value, 0, 32);
destroy_reg_param(®_params[0]);
destroy_reg_param(®_params[1]);
cleanup:
target_free_working_area(target, check_algorithm);
- return retval;
+ if (retval != ERROR_OK)
+ return retval;
+
+ return 1; /* only one block has been checked */
}
static int arm_full_context(struct target *target)
/** Checks whether a memory region is erased. */
int armv7m_blank_check_memory(struct target *target,
- target_addr_t address, uint32_t count, uint32_t *blank, uint8_t erased_value)
+ struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value)
{
struct working_area *erase_check_algorithm;
struct reg_param reg_params[3];
armv7m_info.core_mode = ARM_MODE_THREAD;
init_reg_param(®_params[0], "r0", 32, PARAM_OUT);
- buf_set_u32(reg_params[0].value, 0, 32, address);
+ buf_set_u32(reg_params[0].value, 0, 32, blocks->address);
init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
- buf_set_u32(reg_params[1].value, 0, 32, count);
+ buf_set_u32(reg_params[1].value, 0, 32, blocks->size);
init_reg_param(®_params[2], "r2", 32, PARAM_IN_OUT);
buf_set_u32(reg_params[2].value, 0, 32, erased_value);
&armv7m_info);
if (retval == ERROR_OK)
- *blank = buf_get_u32(reg_params[2].value, 0, 32);
+ blocks->result = buf_get_u32(reg_params[2].value, 0, 32);
destroy_reg_param(®_params[0]);
destroy_reg_param(®_params[1]);
cleanup:
target_free_working_area(target, erase_check_algorithm);
- return retval;
+ if (retval != ERROR_OK)
+ return retval;
+
+ return 1; /* only one block checked */
}
int armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found)
int armv7m_checksum_memory(struct target *target,
target_addr_t address, uint32_t count, uint32_t *checksum);
int armv7m_blank_check_memory(struct target *target,
- target_addr_t address, uint32_t count, uint32_t *blank, uint8_t erased_value);
+ struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value);
int armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found);
/** Checks whether a memory region is erased. */
int mips32_blank_check_memory(struct target *target,
- target_addr_t address, uint32_t count, uint32_t *blank, uint8_t erased_value)
+ struct target_memory_check_block *blocks, int num_blocks,
+ uint8_t erased_value)
{
struct working_area *erase_check_algorithm;
struct reg_param reg_params[3];
int retval = target_write_buffer(target, erase_check_algorithm->address,
sizeof(erase_check_code), erase_check_code_8);
if (retval != ERROR_OK)
- return retval;
+ goto cleanup;
mips32_info.common_magic = MIPS32_COMMON_MAGIC;
mips32_info.isa_mode = isa ? MIPS32_ISA_MMIPS32 : MIPS32_ISA_MIPS32;
init_reg_param(®_params[0], "r4", 32, PARAM_OUT);
- buf_set_u32(reg_params[0].value, 0, 32, address);
+ buf_set_u32(reg_params[0].value, 0, 32, blocks[0].address);
init_reg_param(®_params[1], "r5", 32, PARAM_OUT);
- buf_set_u32(reg_params[1].value, 0, 32, count);
+ buf_set_u32(reg_params[1].value, 0, 32, blocks[0].size);
init_reg_param(®_params[2], "r6", 32, PARAM_IN_OUT);
buf_set_u32(reg_params[2].value, 0, 32, erased_value);
erase_check_algorithm->address + (sizeof(erase_check_code) - 4), 10000, &mips32_info);
if (retval == ERROR_OK)
- *blank = buf_get_u32(reg_params[2].value, 0, 32);
+ blocks[0].result = buf_get_u32(reg_params[2].value, 0, 32);
destroy_reg_param(®_params[0]);
destroy_reg_param(®_params[1]);
destroy_reg_param(®_params[2]);
+cleanup:
target_free_working_area(target, erase_check_algorithm);
- return retval;
+ if (retval != ERROR_OK)
+ return retval;
+
+ return 1; /* only one block has been checked */
}
static int mips32_verify_pointer(struct command_context *cmd_ctx,
int mips32_checksum_memory(struct target *target, target_addr_t address,
uint32_t count, uint32_t *checksum);
int mips32_blank_check_memory(struct target *target,
- target_addr_t address, uint32_t count, uint32_t *blank, uint8_t erased_value);
+ struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value);
#endif /* OPENOCD_TARGET_MIPS32_H */
/** Checks whether a memory region is erased. */
static int stm8_blank_check_memory(struct target *target,
- target_addr_t address, uint32_t count, uint32_t *blank, uint8_t erased_value)
+ struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value)
{
struct working_area *erase_check_algorithm;
struct reg_param reg_params[2];
stm8_info.common_magic = STM8_COMMON_MAGIC;
init_mem_param(&mem_params[0], 0x0, 3, PARAM_OUT);
- buf_set_u32(mem_params[0].value, 0, 24, address);
+ buf_set_u32(mem_params[0].value, 0, 24, blocks[0].address);
init_mem_param(&mem_params[1], 0x3, 3, PARAM_OUT);
- buf_set_u32(mem_params[1].value, 0, 24, count);
+ buf_set_u32(mem_params[1].value, 0, 24, blocks[0].size);
init_reg_param(®_params[0], "a", 32, PARAM_IN_OUT);
buf_set_u32(reg_params[0].value, 0, 32, erased_value);
10000, &stm8_info);
if (retval == ERROR_OK)
- *blank = (*(reg_params[0].value) == 0xff);
+ blocks[0].result = (*(reg_params[0].value) == 0xff);
destroy_mem_param(&mem_params[0]);
destroy_mem_param(&mem_params[1]);
target_free_working_area(target, erase_check_algorithm);
- return retval;
+ if (retval != ERROR_OK)
+ return retval;
+
+ return 1; /* only one block has been checked */
}
static int stm8_checksum_memory(struct target *target, target_addr_t address,
return retval;
}
-int target_blank_check_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t* blank,
+int target_blank_check_memory(struct target *target,
+ struct target_memory_check_block *blocks, int num_blocks,
uint8_t erased_value)
{
- int retval;
if (!target_was_examined(target)) {
LOG_ERROR("Target not examined yet");
return ERROR_FAIL;
}
- if (target->type->blank_check_memory == 0)
+ if (target->type->blank_check_memory == NULL)
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- retval = target->type->blank_check_memory(target, address, size, blank, erased_value);
-
- return retval;
+ return target->type->blank_check_memory(target, blocks, num_blocks, erased_value);
}
int target_read_u64(struct target *target, target_addr_t address, uint64_t *value)
struct target_timer_callback *next;
};
+struct target_memory_check_block {
+ target_addr_t address;
+ uint32_t size;
+ uint32_t result;
+};
+
int target_register_commands(struct command_context *cmd_ctx);
int target_examine(void);
int target_checksum_memory(struct target *target,
target_addr_t address, uint32_t size, uint32_t *crc);
int target_blank_check_memory(struct target *target,
- target_addr_t address, uint32_t size, uint32_t *blank, uint8_t erased_value);
+ struct target_memory_check_block *blocks, int num_blocks,
+ uint8_t erased_value);
int target_wait_state(struct target *target, enum target_state state, int ms);
/**
int (*checksum_memory)(struct target *target, target_addr_t address,
uint32_t count, uint32_t *checksum);
- int (*blank_check_memory)(struct target *target, target_addr_t address,
- uint32_t count, uint32_t *blank, uint8_t erased_value);
+ int (*blank_check_memory)(struct target *target,
+ struct target_memory_check_block *blocks, int num_blocks,
+ uint8_t erased_value);
/*
* target break-/watchpoint control