int handle_flash_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_flash_write_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int handle_flash_fill_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_flash_auto_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr);
retval=bank->driver->write(bank, buffer, offset, count);
if (retval!=ERROR_OK)
{
- ERROR("error writing to flash at address 0x%08x at offset 0x%8.8x", bank->base, offset);
+ LOG_ERROR("error writing to flash at address 0x%08x at offset 0x%8.8x (%d)", bank->base, offset, retval);
}
return retval;
retval=bank->driver->erase(bank, first, last);
if (retval!=ERROR_OK)
{
- ERROR("failed erasing sectors %d to %d", first, last);
+ LOG_ERROR("failed erasing sectors %d to %d (%d)", first, last, retval);
}
return retval;
retval=bank->driver->protect(bank, set, first, last);
if (retval!=ERROR_OK)
{
- ERROR("failed setting protection for areas %d to %d", first, last);
+ LOG_ERROR("failed setting protection for areas %d to %d (%d)", first, last, retval);
}
return retval;
"erase sectors at <bank> <first> <last>");
register_command(cmd_ctx, flash_cmd, "erase_address", handle_flash_erase_address_command, COMMAND_EXEC,
"erase address range <address> <length>");
+
+ register_command(cmd_ctx, flash_cmd, "fillw", handle_flash_fill_command, COMMAND_EXEC,
+ "fill with pattern <address> <word_pattern> <count>");
+ register_command(cmd_ctx, flash_cmd, "fillh", handle_flash_fill_command, COMMAND_EXEC,
+ "fill with pattern <address> <halfword_pattern> <count>");
+ register_command(cmd_ctx, flash_cmd, "fillb", handle_flash_fill_command, COMMAND_EXEC,
+ "fill with pattern <address> <byte_pattern> <count>");
+
register_command(cmd_ctx, flash_cmd, "write_bank", handle_flash_write_bank_command, COMMAND_EXEC,
"write binary data to <bank> <file> <offset>");
register_command(cmd_ctx, flash_cmd, "write_image", handle_flash_write_image_command, COMMAND_EXEC,
return p;
}
}
- ERROR("flash bank %d does not exist", num);
+ LOG_ERROR("flash bank %d does not exist", num);
return NULL;
}
+int flash_get_bank_count()
+{
+ flash_bank_t *p;
+ int i = 0;
+ for (p = flash_banks; p; p = p->next)
+ {
+ i++;
+ }
+ return i;
+}
+
flash_bank_t *get_flash_bank_by_num(int num)
{
flash_bank_t *p = get_flash_bank_by_num_noprobe(num);
if (retval != ERROR_OK)
{
- ERROR("auto_probe failed %d\n", retval);
+ LOG_ERROR("auto_probe failed %d\n", retval);
return NULL;
}
return p;
if ((target = get_target_by_num(strtoul(args[5], NULL, 0))) == NULL)
{
- ERROR("target %lu not defined", strtoul(args[5], NULL, 0));
+ LOG_ERROR("target %lu not defined", strtoul(args[5], NULL, 0));
return ERROR_OK;
}
/* register flash specific commands */
if (flash_drivers[i]->register_commands(cmd_ctx) != ERROR_OK)
{
- ERROR("couldn't register '%s' commands", args[0]);
+ LOG_ERROR("couldn't register '%s' commands", args[0]);
exit(-1);
}
if (flash_drivers[i]->flash_bank_command(cmd_ctx, cmd, args, argc, c) != ERROR_OK)
{
- ERROR("'%s' driver rejected flash bank at 0x%8.8x", args[0], c->base);
+ LOG_ERROR("'%s' driver rejected flash bank at 0x%8.8x", args[0], c->base);
free(c);
return ERROR_OK;
}
/* no matching flash driver found */
if (!found)
{
- ERROR("flash driver '%s' not found", args[0]);
+ LOG_ERROR("flash driver '%s' not found", args[0]);
exit(-1);
}
flash_bank_t *p;
int i = 0;
int j = 0;
+ int retval;
if (argc != 1)
{
erase_state, protect_state);
}
- p->driver->info(p, buf, 1024);
+ *buf = '\0'; /* initialize buffer, otherwise it migh contain garbage if driver function fails */
+ retval = p->driver->info(p, buf, sizeof(buf));
command_print(cmd_ctx, "%s", buf);
+ if (retval != ERROR_OK)
+ LOG_ERROR("error retrieving flash info (%d)", retval);
}
}
if (!target)
{
- ERROR("no target selected");
+ LOG_ERROR("no target selected");
return ERROR_OK;
}
retval = image_open(&image, args[0], (argc == 3) ? args[2] : NULL);
if (retval != ERROR_OK)
{
- command_print(cmd_ctx, "image_open error: %s", image.error_str);
return retval;
}
return retval;
}
+int handle_flash_fill_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+ int err = ERROR_OK;
+ u32 address;
+ u32 pattern;
+ u32 count;
+ u8 chunk[1024];
+ u32 wrote = 0;
+ int chunk_count;
+ char *duration_text;
+ duration_t duration;
+ target_t *target = get_current_target(cmd_ctx);
+ u32 i;
+ int wordsize;
+
+ if (argc != 3)
+ {
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ address = strtoul(args[0], NULL, 0);
+ pattern = strtoul(args[1], NULL, 0);
+ count = strtoul(args[2], NULL, 0);
+
+ if(count == 0)
+ return ERROR_OK;
+
+
+ switch(cmd[4])
+ {
+ case 'w':
+ wordsize=4;
+ break;
+ case 'h':
+ wordsize=2;
+ break;
+ case 'b':
+ wordsize=1;
+ break;
+ default:
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ chunk_count = MIN(count, (1024 / wordsize));
+ switch(wordsize)
+ {
+ case 4:
+ for(i = 0; i < chunk_count; i++)
+ {
+ target_buffer_set_u32(target, chunk + i * wordsize, pattern);
+ }
+ break;
+ case 2:
+ for(i = 0; i < chunk_count; i++)
+ {
+ target_buffer_set_u16(target, chunk + i * wordsize, pattern);
+ }
+ break;
+ case 1:
+ memset(chunk, pattern, chunk_count);
+ break;
+ default:
+ LOG_ERROR("BUG: can't happen");
+ exit(-1);
+ }
+
+ duration_start_measure(&duration);
+
+ flash_set_dirty();
+ err = flash_erase_address_range( target, address, count*wordsize );
+ if (err == ERROR_OK)
+ {
+ for (wrote=0; wrote<(count*wordsize); wrote+=sizeof(chunk))
+ {
+ int cur_size = MIN( (count*wordsize - wrote) , 1024 );
+ if (err == ERROR_OK)
+ {
+ flash_bank_t *bank;
+ bank = get_flash_bank_by_addr(target, address);
+ if(bank == NULL)
+ {
+ err = ERROR_FAIL;
+ break;
+ }
+ err = flash_driver_write(bank, chunk, address - bank->base + wrote, cur_size);
+ wrote += cur_size;
+ }
+ if (err!=ERROR_OK)
+ break;
+ }
+ }
+
+ duration_stop_measure(&duration, &duration_text);
+
+ if(err == ERROR_OK)
+ {
+ float speed;
+ speed=wrote / 1024.0;
+ speed/=((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0));
+ command_print(cmd_ctx, "wrote %d bytes to 0x%8.8x in %s (%f kb/s)",
+ count*wordsize, address, duration_text,
+ speed);
+ }
+ free(duration_text);
+ return ERROR_OK;
+}
+
int handle_flash_write_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
u32 offset;
if (fileio_open(&fileio, args[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
{
- command_print(cmd_ctx, "flash write_binary error: %s", fileio.error_str);
return ERROR_OK;
}
buffer = malloc(fileio.size);
if (fileio_read(&fileio, fileio.size, buffer, &buf_cnt) != ERROR_OK)
{
- command_print(cmd_ctx, "flash write_binary error: %s", fileio.error_str);
return ERROR_OK;
}
if (retval != ERROR_OK)
{
- ERROR("auto_probe failed %d\n", retval);
+ LOG_ERROR("auto_probe failed %d\n", retval);
return NULL;
}
/* check whether address belongs to this flash bank */
if ((addr >= c->base) && (addr < c->base + c->size) && target == c->target)
return c;
}
- ERROR("No flash at address 0x%08x\n", addr);
+ LOG_ERROR("No flash at address 0x%08x\n", addr);
return NULL;
}
if (image->sections[section].size == 0)
{
- WARNING("empty section %d", section);
+ LOG_WARNING("empty section %d", section);
section++;
section_offset = 0;
continue;
{
if (image->sections[section_last + 1].base_address < (run_address + run_size))
{
- DEBUG("section %d out of order(very slightly surprising, but supported)", section_last + 1);
+ LOG_DEBUG("section %d out of order(very slightly surprising, but supported)", section_last + 1);
break;
}
if (image->sections[section_last + 1].base_address != (run_address + run_size))
if (argc != 1)
{
return ERROR_COMMAND_SYNTAX_ERROR;
-
}
if (strcmp(args[0], "on") == 0)