X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fflash%2Fflash.c;h=a0c8984124445fc5e766df5f617d61e107ceedb8;hb=ff53e47b54bce4ae31d2a862739cf03da38cab42;hp=d61ecf20dac9ef6782ea1c381e1670890f0cb652;hpb=43126e8f495ba8158f1a03f6309e305768ad7b99;p=openocd.git diff --git a/src/flash/flash.c b/src/flash/flash.c index d61ecf20da..a0c8984124 100644 --- a/src/flash/flash.c +++ b/src/flash/flash.c @@ -49,6 +49,7 @@ int handle_flash_erase_command(struct command_context_s *cmd_ctx, char *cmd, cha 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); @@ -93,7 +94,7 @@ static int flash_driver_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, 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; @@ -106,7 +107,7 @@ static int flash_driver_erase(struct flash_bank_s *bank, int first, int last) 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; @@ -119,7 +120,7 @@ int flash_driver_protect(struct flash_bank_s *bank, int set, int first, int last 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; @@ -154,6 +155,14 @@ int flash_init_drivers(struct command_context_s *cmd_ctx) "erase sectors at "); register_command(cmd_ctx, flash_cmd, "erase_address", handle_flash_erase_address_command, COMMAND_EXEC, "erase address range
"); + + register_command(cmd_ctx, flash_cmd, "fillw", handle_flash_fill_command, COMMAND_EXEC, + "fill with pattern
"); + register_command(cmd_ctx, flash_cmd, "fillh", handle_flash_fill_command, COMMAND_EXEC, + "fill with pattern
"); + register_command(cmd_ctx, flash_cmd, "fillb", handle_flash_fill_command, COMMAND_EXEC, + "fill with pattern
"); + register_command(cmd_ctx, flash_cmd, "write_bank", handle_flash_write_bank_command, COMMAND_EXEC, "write binary data to "); register_command(cmd_ctx, flash_cmd, "write_image", handle_flash_write_image_command, COMMAND_EXEC, @@ -177,10 +186,21 @@ flash_bank_t *get_flash_bank_by_num_noprobe(int num) 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); @@ -193,7 +213,7 @@ flash_bank_t *get_flash_bank_by_num(int num) if (retval != ERROR_OK) { - ERROR("auto_probe failed %d\n", retval); + LOG_ERROR("auto_probe failed %d\n", retval); return NULL; } return p; @@ -212,7 +232,7 @@ int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char 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; } @@ -225,7 +245,7 @@ int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char /* 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); } @@ -243,7 +263,7 @@ int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char 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; } @@ -268,7 +288,7 @@ int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char /* 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); } @@ -300,6 +320,7 @@ int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char flash_bank_t *p; int i = 0; int j = 0; + int retval; if (argc != 1) { @@ -340,8 +361,11 @@ int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char 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); } } @@ -583,7 +607,7 @@ int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cm if (!target) { - ERROR("no target selected"); + LOG_ERROR("no target selected"); return ERROR_OK; } @@ -605,7 +629,6 @@ int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cm 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; } @@ -631,6 +654,113 @@ int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cm 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; @@ -662,14 +792,12 @@ int handle_flash_write_bank_command(struct command_context_s *cmd_ctx, char *cmd 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; } @@ -719,14 +847,14 @@ flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr) 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; } @@ -811,7 +939,7 @@ int flash_write(target_t *target, image_t *image, u32 *written, int erase) if (image->sections[section].size == 0) { - WARNING("empty section %d", section); + LOG_WARNING("empty section %d", section); section++; section_offset = 0; continue; @@ -833,7 +961,7 @@ int flash_write(target_t *target, image_t *image, u32 *written, int erase) { 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)) @@ -910,7 +1038,6 @@ int handle_flash_auto_erase_command(struct command_context_s *cmd_ctx, char *cmd if (argc != 1) { return ERROR_COMMAND_SYNTAX_ERROR; - } if (strcmp(args[0], "on") == 0)