+ goto cleanup1;
+
+ /* prepare blocks array for algo */
+ struct algo_block {
+ union {
+ uint32_t size;
+ uint32_t result;
+ };
+ uint32_t address;
+ };
+
+ uint32_t avail = target_get_working_area_avail(target);
+ int blocks_to_check = avail / sizeof(struct algo_block) - 1;
+ if (num_blocks < blocks_to_check)
+ blocks_to_check = num_blocks;
+
+ struct algo_block *params = malloc((blocks_to_check+1)*sizeof(struct algo_block));
+ if (params == NULL) {
+ retval = ERROR_FAIL;
+ goto cleanup1;
+ }
+
+ int i;
+ uint32_t total_size = 0;
+ for (i = 0; i < blocks_to_check; i++) {
+ total_size += blocks[i].size;
+ target_buffer_set_u32(target, (uint8_t *)&(params[i].size),
+ blocks[i].size / sizeof(uint32_t));
+ target_buffer_set_u32(target, (uint8_t *)&(params[i].address),
+ blocks[i].address);
+ }
+ target_buffer_set_u32(target, (uint8_t *)&(params[blocks_to_check].size), 0);
+
+ uint32_t param_size = (blocks_to_check + 1) * sizeof(struct algo_block);
+ if (target_alloc_working_area(target, param_size,
+ &erase_check_params) != ERROR_OK) {
+ retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ goto cleanup2;
+ }
+
+ retval = target_write_buffer(target, erase_check_params->address,
+ param_size, (uint8_t *)params);
+ if (retval != ERROR_OK)
+ goto cleanup3;
+
+ uint32_t erased_word = erased_value | (erased_value << 8)
+ | (erased_value << 16) | (erased_value << 24);
+
+ LOG_DEBUG("Starting erase check of %d blocks, parameters@"
+ TARGET_ADDR_FMT, blocks_to_check, erase_check_params->address);