diff options
Diffstat (limited to 'src/flash')
-rw-r--r-- | src/flash/at91sam7.c | 32 | ||||
-rw-r--r-- | src/flash/at91sam7.h | 1 | ||||
-rw-r--r-- | src/flash/cfi.c | 76 | ||||
-rw-r--r-- | src/flash/cfi.h | 1 | ||||
-rw-r--r-- | src/flash/flash.c | 368 | ||||
-rw-r--r-- | src/flash/flash.h | 8 | ||||
-rw-r--r-- | src/flash/lpc2000.c | 33 | ||||
-rw-r--r-- | src/flash/lpc2000.h | 1 | ||||
-rw-r--r-- | src/flash/non_cfi.c | 86 | ||||
-rw-r--r-- | src/flash/stellaris.c | 40 | ||||
-rw-r--r-- | src/flash/stellaris.h | 2 | ||||
-rw-r--r-- | src/flash/stm32x.c | 37 | ||||
-rw-r--r-- | src/flash/stm32x.h | 1 | ||||
-rw-r--r-- | src/flash/str7x.c | 47 | ||||
-rw-r--r-- | src/flash/str7x.h | 1 | ||||
-rw-r--r-- | src/flash/str9x.c | 37 | ||||
-rw-r--r-- | src/flash/str9x.h | 1 | ||||
-rw-r--r-- | src/flash/str9xpec.c | 9 | ||||
-rw-r--r-- | src/flash/str9xpec.h | 1 |
19 files changed, 505 insertions, 277 deletions
diff --git a/src/flash/at91sam7.c b/src/flash/at91sam7.c index 0d97c34c..fdc1c51a 100644 --- a/src/flash/at91sam7.c +++ b/src/flash/at91sam7.c @@ -131,8 +131,7 @@ int at91sam7_register_commands(struct command_context_s *cmd_ctx) u32 at91sam7_get_flash_status(flash_bank_t *bank) { - at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; - target_t *target = at91sam7_info->target; + target_t *target = bank->target; u32 fsr; target_read_u32(target, MC_FSR, &fsr); @@ -144,7 +143,7 @@ u32 at91sam7_get_flash_status(flash_bank_t *bank) void at91sam7_read_clock_info(flash_bank_t *bank) { at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; - target_t *target = at91sam7_info->target; + target_t *target = bank->target; u32 mckr, mcfr, pllr; unsigned long tmp = 0, mainfreq; @@ -203,7 +202,7 @@ void at91sam7_set_flash_mode(flash_bank_t *bank,int mode) { u32 fmr, fmcn = 0, fws = 0; at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; - target_t *target = at91sam7_info->target; + target_t *target = bank->target; if (mode && (mode != at91sam7_info->flashmode)) { @@ -272,7 +271,7 @@ int at91sam7_flash_command(struct flash_bank_s *bank,u8 cmd,u16 pagen) { u32 fcr; at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; - target_t *target = at91sam7_info->target; + target_t *target = bank->target; fcr = (0x5A<<24) | (pagen<<8) | cmd; target_write_u32(target, MC_FCR, fcr); @@ -299,10 +298,10 @@ int at91sam7_flash_command(struct flash_bank_s *bank,u8 cmd,u16 pagen) int at91sam7_read_part_info(struct flash_bank_s *bank) { at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; - target_t *target = at91sam7_info->target; + target_t *target = bank->target; u32 cidr, status; - if (at91sam7_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -525,6 +524,8 @@ int at91sam7_protect_check(struct flash_bank_s *bank) return ERROR_OK; } +/* flash_bank at91sam7 0 0 0 0 <target#> + */ int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank) { at91sam7_flash_bank_t *at91sam7_info; @@ -538,13 +539,6 @@ int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, ch at91sam7_info = malloc(sizeof(at91sam7_flash_bank_t)); bank->driver_priv = at91sam7_info; - at91sam7_info->target = get_target_by_num(strtoul(args[5], NULL, 0)); - if (!at91sam7_info->target) - { - ERROR("no target '%s' configured", args[5]); - exit(-1); - } - /* part wasn't probed for info yet */ at91sam7_info->cidr = 0; @@ -555,7 +549,7 @@ int at91sam7_erase(struct flash_bank_s *bank, int first, int last) { at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; - if (at91sam7_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -596,7 +590,7 @@ int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last) at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; - if (at91sam7_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -644,11 +638,11 @@ int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last) int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) { at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; - target_t *target = at91sam7_info->target; + target_t *target = bank->target; u32 dst_min_alignment, wcount, bytes_remaining = count; u32 first_page, last_page, pagen, buffer_pos; - if (at91sam7_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -809,7 +803,7 @@ int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, at91sam7_info = bank->driver_priv; - if (at91sam7_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } diff --git a/src/flash/at91sam7.h b/src/flash/at91sam7.h index 0bb8f439..317af710 100644 --- a/src/flash/at91sam7.h +++ b/src/flash/at91sam7.h @@ -25,7 +25,6 @@ typedef struct at91sam7_flash_bank_s { - struct target_s *target; u32 working_area; u32 working_area_size; diff --git a/src/flash/cfi.c b/src/flash/cfi.c index 69494b5f..4f2375de 100644 --- a/src/flash/cfi.c +++ b/src/flash/cfi.c @@ -84,6 +84,10 @@ cfi_fixup_t cfi_jedec_fixups[] = { {CFI_MFR_SST, 0x00D5, cfi_fixup_non_cfi, NULL}, {CFI_MFR_SST, 0x00D6, cfi_fixup_non_cfi, NULL}, {CFI_MFR_SST, 0x00D7, cfi_fixup_non_cfi, NULL}, + {CFI_MFR_ST, 0x00D5, cfi_fixup_non_cfi, NULL}, + {CFI_MFR_ST, 0x00D6, cfi_fixup_non_cfi, NULL}, + {CFI_MFR_AMD, 0x2223, cfi_fixup_non_cfi, NULL}, + {CFI_MFR_AMD, 0x22ab, cfi_fixup_non_cfi, NULL}, {0, 0, NULL, NULL} }; @@ -137,7 +141,6 @@ inline u32 flash_address(flash_bank_t *bank, int sector, u32 offset) void cfi_command(flash_bank_t *bank, u8 cmd, u8 *cmd_buf) { - cfi_flash_bank_t *cfi_info = bank->driver_priv; int i; /* clear whole buffer, to ensure bits that exceed the bus_width @@ -146,7 +149,7 @@ void cfi_command(flash_bank_t *bank, u8 cmd, u8 *cmd_buf) for (i = 0; i < CFI_MAX_BUS_WIDTH; i++) cmd_buf[i] = 0; - if (cfi_info->target->endianness == TARGET_LITTLE_ENDIAN) + if (bank->target->endianness == TARGET_LITTLE_ENDIAN) { for (i = bank->bus_width; i > 0; i--) { @@ -168,13 +171,12 @@ void cfi_command(flash_bank_t *bank, u8 cmd, u8 *cmd_buf) */ u8 cfi_query_u8(flash_bank_t *bank, int sector, u32 offset) { - cfi_flash_bank_t *cfi_info = bank->driver_priv; - target_t *target = cfi_info->target; + target_t *target = bank->target; u8 data[CFI_MAX_BUS_WIDTH]; target->type->read_memory(target, flash_address(bank, sector, offset), bank->bus_width, 1, data); - if (cfi_info->target->endianness == TARGET_LITTLE_ENDIAN) + if (bank->target->endianness == TARGET_LITTLE_ENDIAN) return data[0]; else return data[bank->bus_width - 1]; @@ -186,14 +188,13 @@ u8 cfi_query_u8(flash_bank_t *bank, int sector, u32 offset) */ u8 cfi_get_u8(flash_bank_t *bank, int sector, u32 offset) { - cfi_flash_bank_t *cfi_info = bank->driver_priv; - target_t *target = cfi_info->target; + target_t *target = bank->target; u8 data[CFI_MAX_BUS_WIDTH]; int i; target->type->read_memory(target, flash_address(bank, sector, offset), bank->bus_width, 1, data); - if (cfi_info->target->endianness == TARGET_LITTLE_ENDIAN) + if (bank->target->endianness == TARGET_LITTLE_ENDIAN) { for (i = 0; i < bank->bus_width / bank->chip_width; i++) data[0] |= data[i]; @@ -212,13 +213,12 @@ u8 cfi_get_u8(flash_bank_t *bank, int sector, u32 offset) u16 cfi_query_u16(flash_bank_t *bank, int sector, u32 offset) { - cfi_flash_bank_t *cfi_info = bank->driver_priv; - target_t *target = cfi_info->target; + target_t *target = bank->target; u8 data[CFI_MAX_BUS_WIDTH * 2]; target->type->read_memory(target, flash_address(bank, sector, offset), bank->bus_width, 2, data); - if (cfi_info->target->endianness == TARGET_LITTLE_ENDIAN) + if (bank->target->endianness == TARGET_LITTLE_ENDIAN) return data[0] | data[bank->bus_width] << 8; else return data[bank->bus_width - 1] | data[(2 * bank->bus_width) - 1] << 8; @@ -226,13 +226,12 @@ u16 cfi_query_u16(flash_bank_t *bank, int sector, u32 offset) u32 cfi_query_u32(flash_bank_t *bank, int sector, u32 offset) { - cfi_flash_bank_t *cfi_info = bank->driver_priv; - target_t *target = cfi_info->target; + target_t *target = bank->target; u8 data[CFI_MAX_BUS_WIDTH * 4]; target->type->read_memory(target, flash_address(bank, sector, offset), bank->bus_width, 4, data); - if (cfi_info->target->endianness == TARGET_LITTLE_ENDIAN) + if (bank->target->endianness == TARGET_LITTLE_ENDIAN) return data[0] | data[bank->bus_width] << 8 | data[bank->bus_width * 2] << 16 | data[bank->bus_width * 3] << 24; else return data[bank->bus_width - 1] | data[(2* bank->bus_width) - 1] << 8 | @@ -241,8 +240,7 @@ u32 cfi_query_u32(flash_bank_t *bank, int sector, u32 offset) void cfi_intel_clear_status_register(flash_bank_t *bank) { - cfi_flash_bank_t *cfi_info = bank->driver_priv; - target_t *target = cfi_info->target; + target_t *target = bank->target; u8 command[8]; if (target->state != TARGET_HALTED) @@ -334,7 +332,7 @@ int cfi_read_intel_pri_ext(flash_bank_t *bank) { cfi_flash_bank_t *cfi_info = bank->driver_priv; cfi_intel_pri_ext_t *pri_ext = malloc(sizeof(cfi_intel_pri_ext_t)); - target_t *target = cfi_info->target; + target_t *target = bank->target; u8 command[8]; cfi_info->pri_ext = pri_ext; @@ -389,7 +387,7 @@ int cfi_read_spansion_pri_ext(flash_bank_t *bank) { cfi_flash_bank_t *cfi_info = bank->driver_priv; cfi_spansion_pri_ext_t *pri_ext = malloc(sizeof(cfi_spansion_pri_ext_t)); - target_t *target = cfi_info->target; + target_t *target = bank->target; u8 command[8]; cfi_info->pri_ext = pri_ext; @@ -450,7 +448,7 @@ int cfi_read_atmel_pri_ext(flash_bank_t *bank) cfi_atmel_pri_ext_t atmel_pri_ext; cfi_flash_bank_t *cfi_info = bank->driver_priv; cfi_spansion_pri_ext_t *pri_ext = malloc(sizeof(cfi_spansion_pri_ext_t)); - target_t *target = cfi_info->target; + target_t *target = bank->target; u8 command[8]; /* ATMEL devices use the same CFI primary command set (0x2) as AMD/Spansion, @@ -619,13 +617,6 @@ int cfi_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char ** cfi_info->jedec_probe = 0; cfi_info->not_cfi = 0; - cfi_info->target = get_target_by_num(strtoul(args[5], NULL, 0)); - if (!cfi_info->target) - { - ERROR("no target '%s' configured", args[5]); - exit(-1); - } - for (i = 6; i < argc; i++) { if (strcmp(args[i], "x16_as_x8") == 0) @@ -649,7 +640,7 @@ int cfi_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char ** int cfi_intel_erase(struct flash_bank_s *bank, int first, int last) { cfi_flash_bank_t *cfi_info = bank->driver_priv; - target_t *target = cfi_info->target; + target_t *target = bank->target; u8 command[8]; int i; @@ -685,7 +676,7 @@ int cfi_spansion_erase(struct flash_bank_s *bank, int first, int last) { cfi_flash_bank_t *cfi_info = bank->driver_priv; cfi_spansion_pri_ext_t *pri_ext = cfi_info->pri_ext; - target_t *target = cfi_info->target; + target_t *target = bank->target; u8 command[8]; int i; @@ -731,7 +722,7 @@ int cfi_erase(struct flash_bank_s *bank, int first, int last) { cfi_flash_bank_t *cfi_info = bank->driver_priv; - if (cfi_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -765,7 +756,7 @@ int cfi_intel_protect(struct flash_bank_s *bank, int set, int first, int last) { cfi_flash_bank_t *cfi_info = bank->driver_priv; cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext; - target_t *target = cfi_info->target; + target_t *target = bank->target; u8 command[8]; int retry = 0; int i; @@ -860,7 +851,7 @@ int cfi_protect(struct flash_bank_s *bank, int set, int first, int last) { cfi_flash_bank_t *cfi_info = bank->driver_priv; - if (cfi_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -889,8 +880,7 @@ int cfi_protect(struct flash_bank_s *bank, int set, int first, int last) void cfi_add_byte(struct flash_bank_s *bank, u8 *word, u8 byte) { - cfi_flash_bank_t *cfi_info = bank->driver_priv; - target_t *target = cfi_info->target; + target_t *target = bank->target; int i; @@ -913,7 +903,7 @@ void cfi_add_byte(struct flash_bank_s *bank, u8 *word, u8 byte) int cfi_intel_write_block(struct flash_bank_s *bank, u8 *buffer, u32 address, u32 count) { cfi_flash_bank_t *cfi_info = bank->driver_priv; - target_t *target = cfi_info->target; + target_t *target = bank->target; reg_param_t reg_params[7]; armv4_5_algorithm_t armv4_5_info; working_area_t *source; @@ -1122,7 +1112,7 @@ int cfi_spansion_write_block(struct flash_bank_s *bank, u8 *buffer, u32 address, { cfi_flash_bank_t *cfi_info = bank->driver_priv; cfi_spansion_pri_ext_t *pri_ext = cfi_info->pri_ext; - target_t *target = cfi_info->target; + target_t *target = bank->target; reg_param_t reg_params[10]; armv4_5_algorithm_t armv4_5_info; working_area_t *source; @@ -1383,7 +1373,7 @@ int cfi_spansion_write_block(struct flash_bank_s *bank, u8 *buffer, u32 address, int cfi_intel_write_word(struct flash_bank_s *bank, u8 *word, u32 address) { cfi_flash_bank_t *cfi_info = bank->driver_priv; - target_t *target = cfi_info->target; + target_t *target = bank->target; u8 command[8]; cfi_intel_clear_status_register(bank); @@ -1408,7 +1398,7 @@ int cfi_spansion_write_word(struct flash_bank_s *bank, u8 *word, u32 address) { cfi_flash_bank_t *cfi_info = bank->driver_priv; cfi_spansion_pri_ext_t *pri_ext = cfi_info->pri_ext; - target_t *target = cfi_info->target; + target_t *target = bank->target; u8 command[8]; cfi_command(bank, 0xaa, command); @@ -1458,7 +1448,7 @@ int cfi_write_word(struct flash_bank_s *bank, u8 *word, u32 address) int cfi_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) { cfi_flash_bank_t *cfi_info = bank->driver_priv; - target_t *target = cfi_info->target; + target_t *target = bank->target; u32 address = bank->base + offset; /* address of first byte to be programmed */ u32 write_p, copy_p; int align; /* number of unaligned bytes */ @@ -1466,7 +1456,7 @@ int cfi_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) int i; int retval; - if (cfi_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -1632,7 +1622,7 @@ void cfi_fixup_0002_unlock_addresses(flash_bank_t *bank, void *param) int cfi_probe(struct flash_bank_s *bank) { cfi_flash_bank_t *cfi_info = bank->driver_priv; - target_t *target = cfi_info->target; + target_t *target = bank->target; u8 command[8]; int num_sectors = 0; int i; @@ -1855,7 +1845,7 @@ int cfi_probe(struct flash_bank_s *bank) int cfi_erase_check(struct flash_bank_s *bank) { cfi_flash_bank_t *cfi_info = bank->driver_priv; - target_t *target = cfi_info->target; + target_t *target = bank->target; int i; int retval; @@ -1967,7 +1957,7 @@ int cfi_intel_protect_check(struct flash_bank_s *bank) { cfi_flash_bank_t *cfi_info = bank->driver_priv; cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext; - target_t *target = cfi_info->target; + target_t *target = bank->target; u8 command[CFI_MAX_BUS_WIDTH]; int i; @@ -1998,7 +1988,7 @@ int cfi_spansion_protect_check(struct flash_bank_s *bank) { cfi_flash_bank_t *cfi_info = bank->driver_priv; cfi_spansion_pri_ext_t *pri_ext = cfi_info->pri_ext; - target_t *target = cfi_info->target; + target_t *target = bank->target; u8 command[8]; int i; diff --git a/src/flash/cfi.h b/src/flash/cfi.h index b4e3ab22..bf58522b 100644 --- a/src/flash/cfi.h +++ b/src/flash/cfi.h @@ -25,7 +25,6 @@ typedef struct cfi_flash_bank_s { - struct target_s *target; working_area_t *write_algorithm; working_area_t *erase_check_algorithm; diff --git a/src/flash/flash.c b/src/flash/flash.c index 1e091d26..e3389b19 100644 --- a/src/flash/flash.c +++ b/src/flash/flash.c @@ -25,6 +25,9 @@ #include "command.h" #include "target.h" #include "time_support.h" +#include "fileio.h" +#include "image.h" +#include "log.h" #include <string.h> #include <unistd.h> @@ -32,10 +35,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <errno.h> - -#include <fileio.h> -#include <image.h> -#include "log.h" +#include <inttypes.h> /* command handlers */ int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); @@ -46,6 +46,8 @@ int handle_flash_erase_check_command(struct command_context_s *cmd_ctx, char *cm int handle_flash_protect_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int handle_flash_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int handle_flash_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); +int handle_flash_write_binary_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_protect_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); /* flash drivers @@ -100,8 +102,12 @@ int flash_init(struct command_context_s *cmd_ctx) "check protection state of sectors in flash bank <num>"); register_command(cmd_ctx, flash_cmd, "erase", handle_flash_erase_command, COMMAND_EXEC, "erase sectors at <bank> <first> <last>"); - register_command(cmd_ctx, flash_cmd, "write", handle_flash_write_command, COMMAND_EXEC, + register_command(cmd_ctx, flash_cmd, "write", handle_flash_write_binary_command, COMMAND_EXEC, + "DEPRECATED, use 'write_binary' or 'write_image' instead"); + register_command(cmd_ctx, flash_cmd, "write_binary", handle_flash_write_binary_command, COMMAND_EXEC, "write binary <bank> <file> <offset>"); + register_command(cmd_ctx, flash_cmd, "write_image", handle_flash_write_image_command, COMMAND_EXEC, + "write image <file> [offset] [type]"); register_command(cmd_ctx, flash_cmd, "protect", handle_flash_protect_command, COMMAND_EXEC, "set protection of sectors at <bank> <first> <last> <on|off>"); } @@ -125,16 +131,24 @@ flash_bank_t *get_flash_bank_by_num(int num) return NULL; } -/* flash_bank <driver> <base> <size> <chip_width> <bus_width> [driver_options ...] +/* flash_bank <driver> <base> <size> <chip_width> <bus_width> <target> [driver_options ...] */ int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { int i; int found = 0; + target_t *target; - if (argc < 5) + if (argc < 6) { WARNING("incomplete flash_bank configuration"); + WARNING("flash_bank <driver> <base> <size> <chip_width> <bus_width> <target> [driver_options ...]"); + return ERROR_OK; + } + + if ((target = get_target_by_num(strtoul(args[5], NULL, 0))) == NULL) + { + ERROR("target %lu not defined", strtoul(args[5], NULL, 0)); return ERROR_OK; } @@ -152,6 +166,7 @@ int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char } c = malloc(sizeof(flash_bank_t)); + c->target = target; c->driver = flash_drivers[i]; c->driver_priv = NULL; c->base = strtoul(args[1], NULL, 0); @@ -226,9 +241,9 @@ int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char return ERROR_OK; } - for (p = flash_banks; p; p = p->next) + for (p = flash_banks; p; p = p->next, i++) { - if (i++ == strtoul(args[0], NULL, 0)) + if (i == strtoul(args[0], NULL, 0)) { char buf[1024]; @@ -494,15 +509,96 @@ int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, c return ERROR_OK; } -int handle_flash_write_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) +{ + target_t *target = get_current_target(cmd_ctx); + + image_t image; + u32 image_size; + char *error_str; + u32 *failed; + + int i; + + duration_t duration; + char *duration_text; + + int retval; + + if (!strcmp(cmd, "write")) + { + command_print(cmd_ctx, "'flash write' has been deprecated in favor of 'flash write_binary' and 'flash write_image'"); + DEBUG("'flash write' has been deprecated in favor of 'flash write_binary' and 'flash write_image'"); + } + + if (argc < 1) + { + command_print(cmd_ctx, "usage: flash write <file> [offset] [type]"); + return ERROR_OK; + } + + if (!target) + { + ERROR("no target selected"); + return ERROR_OK; + } + + duration_start_measure(&duration); + + if (argc >= 2) + { + image.base_address_set = 1; + image.base_address = strtoul(args[1], NULL, 0); + } + else + { + image.base_address_set = 0; + image.base_address = 0x0; + } + + image.start_address_set = 0; + + if (image_open(&image, args[0], (argc == 4) ? args[2] : NULL) != ERROR_OK) + { + command_print(cmd_ctx, "flash write error: %s", image.error_str); + return ERROR_OK; + } + + failed = malloc(sizeof(u32) * image.num_sections); + + if ((retval = flash_write(target, &image, &image_size, &error_str, failed)) != ERROR_OK) + { + command_print(cmd_ctx, "failed writing image %s: %s", args[0], error_str); + free(error_str); + } + + for (i = 0; i < image.num_sections; i++) + { + if (failed[i]) + { + command_print(cmd_ctx, "didn't write section at 0x%8.8x, size 0x%8.8x", + image.sections[i].base_address, image.sections[i].size); + } + } + + duration_stop_measure(&duration, &duration_text); + command_print(cmd_ctx, "wrote %u byte from file %s in %s (%f kb/s)", + image_size, args[0], duration_text, + (float)image_size / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0))); + free(duration_text); + + image_close(&image); + + return ERROR_OK; +} + +int handle_flash_write_binary_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { u32 offset; u8 *buffer; u32 buf_cnt; - u32 image_size; - int i; - image_t image; + fileio_t fileio; duration_t duration; char *duration_text; @@ -512,17 +608,12 @@ int handle_flash_write_command(struct command_context_s *cmd_ctx, char *cmd, cha if (argc < 3) { - command_print(cmd_ctx, "usage: flash write <bank> <file> <offset> [type]"); + command_print(cmd_ctx, "usage: flash write <bank> <file> <offset>"); return ERROR_OK; } duration_start_measure(&duration); - image.base_address_set = 1; - image.base_address = strtoul(args[1], NULL, 0); - - image.start_address_set = 0; - offset = strtoul(args[2], NULL, 0); p = get_flash_bank_by_num(strtoul(args[0], NULL, 0)); if (!p) @@ -531,69 +622,208 @@ int handle_flash_write_command(struct command_context_s *cmd_ctx, char *cmd, cha return ERROR_OK; } - if (image_open(&image, args[1], (argc == 4) ? args[3] : NULL) != ERROR_OK) + if (fileio_open(&fileio, args[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK) { - command_print(cmd_ctx, "flash write error: %s", image.error_str); + command_print(cmd_ctx, "flash write error: %s", fileio.error_str); return ERROR_OK; } - image_size = 0x0; - for (i = 0; i < image.num_sections; i++) + buffer = malloc(fileio.size); + if (fileio_read(&fileio, fileio.size, buffer, &buf_cnt) != ERROR_OK) { - buffer = malloc(image.sections[i].size); - if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK) - { - ERROR("image_read_section failed with error code: %i", retval); - command_print(cmd_ctx, "image reading failed, flash write aborted"); - free(buffer); - image_close(&image); - return ERROR_OK; - } - - if ((retval = p->driver->write(p, buffer, offset, buf_cnt)) != ERROR_OK) + command_print(cmd_ctx, "flash write error: %s", fileio.error_str); + return ERROR_OK; + } + + if ((retval = p->driver->write(p, buffer, offset, buf_cnt)) != ERROR_OK) + { + command_print(cmd_ctx, "failed writing file %s to flash bank %i at offset 0x%8.8x", + args[1], strtoul(args[0], NULL, 0), strtoul(args[2], NULL, 0)); + switch (retval) { - command_print(cmd_ctx, "failed writing file %s to flash bank %i at offset 0x%8.8x", - args[1], strtoul(args[0], NULL, 0), strtoul(args[2], NULL, 0)); - switch (retval) - { - case ERROR_TARGET_NOT_HALTED: - command_print(cmd_ctx, "can't work with this flash while target is running"); - break; - case ERROR_INVALID_ARGUMENTS: - command_print(cmd_ctx, "usage: flash write <bank> <file> <offset>"); - break; - case ERROR_FLASH_BANK_INVALID: - command_print(cmd_ctx, "no '%s' flash found at 0x%8.8x", p->driver->name, p->base); - break; - case ERROR_FLASH_OPERATION_FAILED: - command_print(cmd_ctx, "flash program error"); - break; - case ERROR_FLASH_DST_BREAKS_ALIGNMENT: - command_print(cmd_ctx, "offset breaks required alignment"); - break; - case ERROR_FLASH_DST_OUT_OF_BANK: - command_print(cmd_ctx, "destination is out of flash bank (offset and/or file too large)"); - break; - case ERROR_FLASH_SECTOR_NOT_ERASED: - command_print(cmd_ctx, "destination sector(s) not erased"); - break; - default: - command_print(cmd_ctx, "unknown error"); - } + case ERROR_TARGET_NOT_HALTED: + command_print(cmd_ctx, "can't work with this flash while target is running"); + break; + case ERROR_INVALID_ARGUMENTS: + command_print(cmd_ctx, "usage: flash write <bank> <file> <offset>"); + break; + case ERROR_FLASH_BANK_INVALID: + command_print(cmd_ctx, "no '%s' flash found at 0x%8.8x", p->driver->name, p->base); + break; + case ERROR_FLASH_OPERATION_FAILED: + command_print(cmd_ctx, "flash program error"); + break; + case ERROR_FLASH_DST_BREAKS_ALIGNMENT: + command_print(cmd_ctx, "offset breaks required alignment"); + break; + case ERROR_FLASH_DST_OUT_OF_BANK: + command_print(cmd_ctx, "destination is out of flash bank (offset and/or file too large)"); + break; + case ERROR_FLASH_SECTOR_NOT_ERASED: + command_print(cmd_ctx, "destination sector(s) not erased"); + break; + default: + command_print(cmd_ctx, "unknown error"); } - image_size += buf_cnt; - - free(buffer); } + free(buffer); duration_stop_measure(&duration, &duration_text); - command_print(cmd_ctx, "wrote %u byte from file %s to flash bank %i at offset 0x%8.8x in %s (%f kb/s)", - image_size, args[1], strtoul(args[0], NULL, 0), offset, duration_text, - (float)image_size / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0))); + command_print(cmd_ctx, "wrote %"PRIi64" byte from file %s to flash bank %i at offset 0x%8.8x in %s (%f kb/s)", + fileio.size, args[1], strtoul(args[0], NULL, 0), offset, duration_text, + (float)fileio.size / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0))); free(duration_text); - image_close(&image); + fileio_close(&fileio); + + return ERROR_OK; +} + +/* lookup flash bank by address */ +flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr) +{ + flash_bank_t *c; + + /* cycle through bank list */ + for (c = flash_banks; c; c = c->next) + { + /* check whether address belongs to this flash bank */ + if ((addr >= c->base) && (addr < c->base + c->size) && target == c->target) + return c; + } + + return NULL; +} + +/* erase given flash region, selects proper bank according to target and address */ +int flash_erase(target_t *target, u32 addr, u32 length) +{ + flash_bank_t *c; + unsigned long sector_size; + int first; + int last; + + if ((c = get_flash_bank_by_addr(target, addr)) == NULL) + return ERROR_FLASH_DST_OUT_OF_BANK; /* no corresponding bank found */ + + /* sanity checks */ + if (c->size == 0 || c->num_sectors == 0 || c->size % c->num_sectors) + return ERROR_FLASH_BANK_INVALID; + + if (length == 0) + { + /* special case, erase whole bank when length is zero */ + if (addr != c->base) + return ERROR_FLASH_DST_BREAKS_ALIGNMENT; + + return c->driver->erase(c, 0, c->num_sectors - 1); + } + + /* check whether it fits */ + if (addr + length > c->base + c->size) + return ERROR_FLASH_DST_BREAKS_ALIGNMENT; + + /* calculate sector size */ + sector_size = c->size / c->num_sectors; + + /* check alignment */ + if ((addr - c->base) % sector_size || length % sector_size) + return ERROR_FLASH_DST_BREAKS_ALIGNMENT; + + first = (addr - c->base) / sector_size; + last = first + length / sector_size - 1; + return c->driver->erase(c, first, last); +} + +int flash_write(target_t *target, image_t *image, u32 *image_size, char **error_str, u32 *failed) +{ + int section; + int retval; + + *image_size = 0; + + /* for each section in the image */ + for (section = 0; section < image->num_sections; section++) + { + u32 offset = 0; + u32 address = image->sections[section].base_address; + u32 size = image->sections[section].size; + + failed[section] = 0; + + while (size != 0) + { + flash_bank_t *c; + u32 thisrun_size = size; + u32 size_read; + u8 *buffer; + + /* find the corresponding flash bank */ + if ((c = get_flash_bank_by_addr(target, address)) == NULL) + { + /* mark as failed, and skip the current section */ + failed[section] = 1; + break; + } + + /* check whether it fits, split into multiple runs if not */ + if ((address + size) > (c->base + c->size)) + thisrun_size = c->base + c->size - address; + + buffer = malloc(thisrun_size); + if (((retval = image_read_section(image, section, offset, size, buffer, &size_read)) != ERROR_OK) + || (thisrun_size != size_read)) + { + *error_str = malloc(FLASH_MAX_ERROR_STR); + snprintf(*error_str, FLASH_MAX_ERROR_STR, "error reading from image"); + return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE; + } + + if ((retval = c->driver->write(c, buffer, address - c->base, thisrun_size)) != ERROR_OK) + { + /* mark the current section as failed */ + failed[section] = 1; + *error_str = malloc(FLASH_MAX_ERROR_STR); + switch (retval) + { + case ERROR_TARGET_NOT_HALTED: + snprintf(*error_str, FLASH_MAX_ERROR_STR, "can't flash image while target is running"); + break; + case ERROR_INVALID_ARGUMENTS: + snprintf(*error_str, FLASH_MAX_ERROR_STR, "flash driver can't fulfill request"); + break; + case ERROR_FLASH_OPERATION_FAILED: + snprintf(*error_str, FLASH_MAX_ERROR_STR, "flash program error"); + break; + case ERROR_FLASH_DST_BREAKS_ALIGNMENT: + snprintf(*error_str, FLASH_MAX_ERROR_STR, "offset breaks required alignment"); + break; + case ERROR_FLASH_DST_OUT_OF_BANK: + snprintf(*error_str, FLASH_MAX_ERROR_STR, "no flash mapped at requested address"); + break; + case ERROR_FLASH_SECTOR_NOT_ERASED: + snprintf(*error_str, FLASH_MAX_ERROR_STR, "destination sector(s) not erased"); + break; + default: + snprintf(*error_str, FLASH_MAX_ERROR_STR, "unknown error: %i", retval); + } + + free(buffer); + + /* abort operation */ + return retval; + } + + free(buffer); + + offset += thisrun_size; + address += thisrun_size; + size -= thisrun_size; + } + + *image_size += image->sections[section].size; + } return ERROR_OK; } diff --git a/src/flash/flash.h b/src/flash/flash.h index a8cc1869..513ede81 100644 --- a/src/flash/flash.h +++ b/src/flash/flash.h @@ -21,6 +21,9 @@ #define FLASH_H #include "target.h" +#include "image.h" + +#define FLASH_MAX_ERROR_STR (128) typedef struct flash_sector_s { @@ -48,6 +51,7 @@ typedef struct flash_driver_s typedef struct flash_bank_s { + target_t *target; flash_driver_t *driver; void *driver_priv; u32 base; @@ -62,7 +66,11 @@ typedef struct flash_bank_s extern int flash_register_commands(struct command_context_s *cmd_ctx); extern int flash_init(struct command_context_s *cmd_ctx); +extern int flash_erase(target_t *target, u32 addr, u32 length); +extern int flash_write(target_t *target, image_t *image, u32 *image_size, char **error, u32 *failed); + extern flash_bank_t *get_flash_bank_by_num(int num); +extern flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr); #define ERROR_FLASH_BANK_INVALID (-900) #define ERROR_FLASH_SECTOR_INVALID (-901) diff --git a/src/flash/lpc2000.c b/src/flash/lpc2000.c index e3c7e742..2252ca42 100644 --- a/src/flash/lpc2000.c +++ b/src/flash/lpc2000.c @@ -233,7 +233,7 @@ int lpc2000_build_sector_list(struct flash_bank_s *bank) int lpc2000_iap_call(flash_bank_t *bank, int code, u32 param_table[5], u32 result_table[2]) { lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv; - target_t *target = lpc2000_info->target; + target_t *target = bank->target; mem_param_t mem_params[2]; reg_param_t reg_params[5]; armv4_5_algorithm_t armv4_5_info; @@ -350,7 +350,7 @@ int lpc2000_iap_blank_check(struct flash_bank_s *bank, int first, int last) return ERROR_OK; } -/* flash bank lpc2000 <base> <size> 0 0 <lpc_variant> <target#> <cclk> [calc_checksum] +/* flash bank lpc2000 <base> <size> 0 0 <target#> <lpc_variant> <cclk> [calc_checksum] */ int lpc2000_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank) { @@ -365,14 +365,14 @@ int lpc2000_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, cha lpc2000_info = malloc(sizeof(lpc2000_flash_bank_t)); bank->driver_priv = lpc2000_info; - if (strcmp(args[5], "lpc2000_v1") == 0) + if (strcmp(args[6], "lpc2000_v1") == 0) { lpc2000_info->variant = 1; lpc2000_info->cmd51_dst_boundary = 512; lpc2000_info->cmd51_can_256b = 0; lpc2000_info->cmd51_can_8192b = 1; } - else if (strcmp(args[5], "lpc2000_v2") == 0) + else if (strcmp(args[6], "lpc2000_v2") == 0) { lpc2000_info->variant = 2; lpc2000_info->cmd51_dst_boundary = 256; @@ -386,18 +386,11 @@ int lpc2000_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, cha return ERROR_FLASH_BANK_INVALID; } - lpc2000_info->target = get_target_by_num(strtoul(args[6], NULL, 0)); - if (!lpc2000_info->target) - { - ERROR("no target '%s' configured", args[6]); - exit(-1); - } lpc2000_info->iap_working_area = NULL; lpc2000_info->cclk = strtoul(args[7], NULL, 0); lpc2000_info->calc_checksum = 0; lpc2000_build_sector_list(bank); - - + if (argc >= 9) { if (strcmp(args[8], "calc_checksum") == 0) @@ -414,7 +407,7 @@ int lpc2000_erase(struct flash_bank_s *bank, int first, int last) u32 result_table[2]; int status_code; - if (lpc2000_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -472,7 +465,7 @@ int lpc2000_protect(struct flash_bank_s *bank, int set, int first, int last) int lpc2000_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) { lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv; - target_t *target = lpc2000_info->target; + target_t *target = bank->target; u32 dst_min_alignment; u32 bytes_remaining = count; u32 bytes_written = 0; @@ -484,7 +477,7 @@ int lpc2000_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) int i; working_area_t *download_area; - if (lpc2000_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -568,7 +561,7 @@ int lpc2000_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) if (bytes_remaining >= thisrun_bytes) { - if (target_write_buffer(lpc2000_info->target, download_area->address, thisrun_bytes, buffer + bytes_written) != ERROR_OK) + if (target_write_buffer(bank->target, download_area->address, thisrun_bytes, buffer + bytes_written) != ERROR_OK) { target_free_working_area(target, download_area); return ERROR_FLASH_OPERATION_FAILED; @@ -581,7 +574,7 @@ int lpc2000_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) memcpy(last_buffer, buffer + bytes_written, bytes_remaining); for (i = bytes_remaining; i < thisrun_bytes; i++) last_buffer[i] = 0xff; - target_write_buffer(lpc2000_info->target, download_area->address, thisrun_bytes, last_buffer); + target_write_buffer(bank->target, download_area->address, thisrun_bytes, last_buffer); free(last_buffer); } @@ -629,9 +622,7 @@ int lpc2000_probe(struct flash_bank_s *bank) int lpc2000_erase_check(struct flash_bank_s *bank) { - lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv; - - if (lpc2000_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -676,7 +667,7 @@ int lpc2000_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, } lpc2000_info = bank->driver_priv; - if (lpc2000_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } diff --git a/src/flash/lpc2000.h b/src/flash/lpc2000.h index dbbe4b6a..bf7358f6 100644 --- a/src/flash/lpc2000.h +++ b/src/flash/lpc2000.h @@ -26,7 +26,6 @@ typedef struct lpc2000_flash_bank_s { int variant; - struct target_s *target; struct working_area_s *iap_working_area; u32 cclk; int cmd51_dst_boundary; diff --git a/src/flash/non_cfi.c b/src/flash/non_cfi.c index 3a74ff92..d80f3784 100644 --- a/src/flash/non_cfi.c +++ b/src/flash/non_cfi.c @@ -35,13 +35,13 @@ non_cfi_t non_cfi_flashes[] = { .mfr = CFI_MFR_SST, .id = 0xd4, .pri_id = 0x02, - .dev_size = 0x10, - .interface_desc = 0x0, + .dev_size = 0x10, /* 2^16 = 64KB */ + .interface_desc = 0x0, /* x8 only device */ .max_buf_write_size = 0x0, .num_erase_regions = 1, .erase_region_info = { - 0x0010000f, + 0x0010000f, /* 16x 4KB */ 0x00000000 } }, @@ -49,8 +49,8 @@ non_cfi_t non_cfi_flashes[] = { .mfr = CFI_MFR_SST, .id = 0xd5, .pri_id = 0x02, - .dev_size = 0x11, - .interface_desc = 0x0, + .dev_size = 0x11, /* 2^17 = 128KB */ + .interface_desc = 0x0, /* x8 only device */ .max_buf_write_size = 0x0, .num_erase_regions = 1, .erase_region_info = @@ -63,8 +63,8 @@ non_cfi_t non_cfi_flashes[] = { .mfr = CFI_MFR_SST, .id = 0xd6, .pri_id = 0x02, - .dev_size = 0x12, - .interface_desc = 0x0, + .dev_size = 0x12, /* 2^18 = 256KB */ + .interface_desc = 0x0, /* x8 only device */ .max_buf_write_size = 0x0, .num_erase_regions = 1, .erase_region_info = @@ -77,8 +77,8 @@ non_cfi_t non_cfi_flashes[] = { .mfr = CFI_MFR_SST, .id = 0xd7, .pri_id = 0x02, - .dev_size = 0x13, - .interface_desc = 0x0, + .dev_size = 0x13, /* 2^19 = 512KB */ + .interface_desc = 0x0, /* x8 only device */ .max_buf_write_size = 0x0, .num_erase_regions = 1, .erase_region_info = @@ -88,6 +88,74 @@ non_cfi_t non_cfi_flashes[] = { } }, { + .mfr = CFI_MFR_ST, + .id = 0xd6, /* ST29F400BB */ + .pri_id = 0x02, + .dev_size = 0x13, /* 2^19 = 512KB */ + .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ + .max_buf_write_size = 0x0, + .num_erase_regions = 4, + .erase_region_info = + { + 0x00400000, /* 1x 16KB */ + 0x00200001, /* 2x 8KB */ + 0x00800000, /* 1x 32KB */ + 0x01000006, /* 7x 64KB */ + 0x00000000 + } + }, + { + .mfr = CFI_MFR_ST, + .id = 0xd5, /* ST29F400BT */ + .pri_id = 0x02, + .dev_size = 0x13, /* 2^19 = 512KB */ + .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ + .max_buf_write_size = 0x0, + .num_erase_regions = 4, + .erase_region_info = + { + 0x01000006, /* 7x 64KB */ + 0x00800000, /* 1x 32KB */ + 0x00200001, /* 2x 8KB */ + 0x00400000, /* 1x 16KB */ + 0x00000000 + } + }, + { + .mfr = CFI_MFR_AMD, + .id = 0x22ab, /* AM29F400BB */ + .pri_id = 0x02, + .dev_size = 0x13, /* 2^19 = 512KB */ + .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ + .max_buf_write_size = 0x0, + .num_erase_regions = 4, + .erase_region_info = + { + 0x00400000, /* 1x 16KB */ + 0x00200001, /* 2x 8KB */ + 0x00800000, /* 1x 32KB */ + 0x01000006, /* 7x 64KB */ + 0x00000000 + } + }, + { + .mfr = CFI_MFR_AMD, + .id = 0x2223, /* AM29F400BT */ + .pri_id = 0x02, + .dev_size = 0x13, /* 2^19 = 512KB */ + .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ + .max_buf_write_size = 0x0, + .num_erase_regions = 4, + .erase_region_info = + { + 0x01000006, /* 7x 64KB */ + 0x00800000, /* 1x 32KB */ + 0x00200001, /* 2x 8KB */ + 0x00400000, /* 1x 16KB */ + 0x00000000 + } + }, + { .mfr = 0, .id = 0, } diff --git a/src/flash/stellaris.c b/src/flash/stellaris.c index 376a80fd..490b02cc 100644 --- a/src/flash/stellaris.c +++ b/src/flash/stellaris.c @@ -57,6 +57,8 @@ u32 stellaris_get_flash_status(flash_bank_t *bank); void stellaris_set_flash_mode(flash_bank_t *bank,int mode); u32 stellaris_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout); +int stellaris_read_part_info(struct flash_bank_s *bank); + flash_driver_t stellaris_flash = { .name = "stellaris", @@ -130,6 +132,8 @@ struct { * openocd command interface * ***************************************************************************/ +/* flash_bank stellaris <base> <size> 0 0 <target#> + */ int stellaris_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank) { stellaris_flash_bank_t *stellaris_info; @@ -144,13 +148,7 @@ int stellaris_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, c bank->base = 0x0; bank->driver_priv = stellaris_info; - stellaris_info->target_name ="Unknown target"; - stellaris_info->target = get_target_by_num(strtoul(args[5], NULL, 0)); - if (!stellaris_info->target) - { - ERROR("no target '%s' configured", args[5]); - exit(-1); - } + stellaris_info->target_name = "Unknown target"; /* part wasn't probed for info yet */ stellaris_info->did1 = 0; @@ -214,7 +212,7 @@ int stellaris_info(struct flash_bank_s *bank, char *buf, int buf_size) u32 stellaris_get_flash_status(flash_bank_t *bank) { stellaris_flash_bank_t *stellaris_info = bank->driver_priv; - target_t *target = stellaris_info->target; + target_t *target = bank->target; u32 fmc; target_read_u32(target, FLASH_CONTROL_BASE|FLASH_FMC, &fmc); @@ -227,7 +225,7 @@ u32 stellaris_get_flash_status(flash_bank_t *bank) void stellaris_read_clock_info(flash_bank_t *bank) { stellaris_flash_bank_t *stellaris_info = bank->driver_priv; - target_t *target = stellaris_info->target; + target_t *target = bank->target; u32 rcc, pllcfg, sysdiv, usesysdiv, bypass, oscsrc; unsigned long tmp, mainfreq; @@ -275,7 +273,7 @@ void stellaris_read_clock_info(flash_bank_t *bank) void stellaris_set_flash_mode(flash_bank_t *bank,int mode) { stellaris_flash_bank_t *stellaris_info = bank->driver_priv; - target_t *target = stellaris_info->target; + target_t *target = bank->target; u32 usecrl = (stellaris_info->mck_freq/1000000ul-1); DEBUG("usecrl = %i",usecrl); @@ -305,7 +303,7 @@ int stellaris_flash_command(struct flash_bank_s *bank,u8 cmd,u16 pagen) { u32 fmc; stellaris_flash_bank_t *stellaris_info = bank->driver_priv; - target_t *target = stellaris_info->target; + target_t *target = bank->target; fmc = FMC_WRKEY | cmd; target_write_u32(target, FLASH_CONTROL_BASE|FLASH_FMC, fmc); @@ -323,7 +321,7 @@ int stellaris_flash_command(struct flash_bank_s *bank,u8 cmd,u16 pagen) int stellaris_read_part_info(struct flash_bank_s *bank) { stellaris_flash_bank_t *stellaris_info = bank->driver_priv; - target_t *target = stellaris_info->target; + target_t *target = bank->target; u32 did0,did1, ver, fam, status; int i; @@ -390,7 +388,7 @@ int stellaris_read_part_info(struct flash_bank_s *bank) int stellaris_erase_check(struct flash_bank_s *bank) { stellaris_flash_bank_t *stellaris_info = bank->driver_priv; - target_t *target = stellaris_info->target; + target_t *target = bank->target; int i; /* */ @@ -403,7 +401,7 @@ int stellaris_protect_check(struct flash_bank_s *bank) u32 status; stellaris_flash_bank_t *stellaris_info = bank->driver_priv; - target_t *target = stellaris_info->target; + target_t *target = bank->target; if (stellaris_info->did1 == 0) { @@ -427,9 +425,9 @@ int stellaris_erase(struct flash_bank_s *bank, int first, int last) int banknr; u32 flash_fmc, flash_cris; stellaris_flash_bank_t *stellaris_info = bank->driver_priv; - target_t *target = stellaris_info->target; + target_t *target = bank->target; - if (stellaris_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -517,9 +515,9 @@ int stellaris_protect(struct flash_bank_s *bank, int set, int first, int last) int lockregion; stellaris_flash_bank_t *stellaris_info = bank->driver_priv; - target_t *target = stellaris_info->target; + target_t *target = bank->target; - if (stellaris_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -625,7 +623,7 @@ u8 stellaris_write_code[] = int stellaris_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 wcount) { stellaris_flash_bank_t *stellaris_info = bank->driver_priv; - target_t *target = stellaris_info->target; + target_t *target = bank->target; u32 buffer_size = 8192; working_area_t *source; working_area_t *write_algorithm; @@ -721,7 +719,7 @@ int stellaris_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 int stellaris_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) { stellaris_flash_bank_t *stellaris_info = bank->driver_priv; - target_t *target = stellaris_info->target; + target_t *target = bank->target; u32 dst_min_alignment, wcount, bytes_remaining = count; u32 address = offset; u32 fcr,flash_cris,flash_fmc; @@ -730,7 +728,7 @@ int stellaris_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count DEBUG("(bank=%08X buffer=%08X offset=%08X count=%08X)", bank, buffer, offset, count); - if (stellaris_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } diff --git a/src/flash/stellaris.h b/src/flash/stellaris.h index e899b30f..8024258e 100644 --- a/src/flash/stellaris.h +++ b/src/flash/stellaris.h @@ -25,8 +25,6 @@ typedef struct stellaris_flash_bank_s { - struct target_s *target; - /* chip id register */ u32 did0; u32 did1; diff --git a/src/flash/stm32x.c b/src/flash/stm32x.c index a09fa40d..15cbb74c 100644 --- a/src/flash/stm32x.c +++ b/src/flash/stm32x.c @@ -137,13 +137,6 @@ int stm32x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char WARNING("overriding flash base address for STM32x device with 0x08000000"); bank->base = 0x08000000; } - - stm32x_info->target = get_target_by_num(strtoul(args[5], NULL, 0)); - if (!stm32x_info->target) - { - ERROR("no target '%s' configured", args[5]); - exit(-1); - } stm32x_build_block_list(bank); @@ -154,8 +147,7 @@ int stm32x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char u32 stm32x_get_flash_status(flash_bank_t *bank) { - stm32x_flash_bank_t *stm32x_info = bank->driver_priv; - target_t *target = stm32x_info->target; + target_t *target = bank->target; u32 status; target_read_u32(target, STM32_FLASH_SR, &status); @@ -179,8 +171,7 @@ u32 stm32x_wait_status_busy(flash_bank_t *bank, int timeout) int stm32x_blank_check(struct flash_bank_s *bank, int first, int last) { - stm32x_flash_bank_t *stm32x_info = bank->driver_priv; - target_t *target = stm32x_info->target; + target_t *target = bank->target; u8 *buffer; int i; int nBytes; @@ -218,8 +209,7 @@ int stm32x_blank_check(struct flash_bank_s *bank, int first, int last) int stm32x_protect_check(struct flash_bank_s *bank) { - stm32x_flash_bank_t *stm32x_info = bank->driver_priv; - target_t *target = stm32x_info->target; + target_t *target = bank->target; u32 protection; int i, s; @@ -248,8 +238,7 @@ int stm32x_protect_check(struct flash_bank_s *bank) int stm32x_erase(struct flash_bank_s *bank, int first, int last) { - stm32x_flash_bank_t *stm32x_info = bank->driver_priv; - target_t *target = stm32x_info->target; + target_t *target = bank->target; int i; u32 status; @@ -285,8 +274,7 @@ int stm32x_erase(struct flash_bank_s *bank, int first, int last) int stm32x_protect(struct flash_bank_s *bank, int set, int first, int last) { - stm32x_flash_bank_t *stm32x_info = bank->driver_priv; - target_t *target = stm32x_info->target; + target_t *target = bank->target; if (target->state != TARGET_HALTED) { @@ -299,7 +287,7 @@ int stm32x_protect(struct flash_bank_s *bank, int set, int first, int last) int stm32x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) { stm32x_flash_bank_t *stm32x_info = bank->driver_priv; - target_t *target = stm32x_info->target; + target_t *target = bank->target; u32 buffer_size = 8192; working_area_t *source; u32 address = bank->base + offset; @@ -409,8 +397,7 @@ int stm32x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 co int stm32x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) { - stm32x_flash_bank_t *stm32x_info = bank->driver_priv; - target_t *target = stm32x_info->target; + target_t *target = bank->target; u32 words_remaining = (count / 2); u32 bytes_remaining = (count & 0x00000001); u32 address = bank->base + offset; @@ -547,7 +534,7 @@ int stm32x_handle_lock_command(struct command_context_s *cmd_ctx, char *cmd, cha stm32x_info = bank->driver_priv; - target = stm32x_info->target; + target = bank->target; if (target->state != TARGET_HALTED) { @@ -614,7 +601,7 @@ int stm32x_handle_unlock_command(struct command_context_s *cmd_ctx, char *cmd, c stm32x_info = bank->driver_priv; - target = stm32x_info->target; + target = bank->target; if (target->state != TARGET_HALTED) { @@ -681,7 +668,7 @@ int stm32x_handle_options_read_command(struct command_context_s *cmd_ctx, char * stm32x_info = bank->driver_priv; - target = stm32x_info->target; + target = bank->target; if (target->state != TARGET_HALTED) { @@ -749,7 +736,7 @@ int stm32x_handle_options_write_command(struct command_context_s *cmd_ctx, char stm32x_info = bank->driver_priv; - target = stm32x_info->target; + target = bank->target; if (target->state != TARGET_HALTED) { @@ -831,7 +818,7 @@ int stm32x_handle_mass_erase_command(struct command_context_s *cmd_ctx, char *cm stm32x_info = bank->driver_priv; - target = stm32x_info->target; + target = bank->target; if (target->state != TARGET_HALTED) { diff --git a/src/flash/stm32x.h b/src/flash/stm32x.h index ad189ac4..59fcb04b 100644 --- a/src/flash/stm32x.h +++ b/src/flash/stm32x.h @@ -25,7 +25,6 @@ typedef struct stm32x_flash_bank_s { - struct target_s *target; working_area_t *write_algorithm; } stm32x_flash_bank_t; diff --git a/src/flash/str7x.c b/src/flash/str7x.c index 0fa2f6ce..6771506a 100644 --- a/src/flash/str7x.c +++ b/src/flash/str7x.c @@ -150,7 +150,7 @@ int str7x_build_block_list(struct flash_bank_s *bank) return ERROR_OK; } -/* flash bank str7x <base> <size> 0 0 <str71_variant> <target#> +/* flash bank str7x <base> <size> 0 0 <target#> <str71_variant> */ int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank) { @@ -165,7 +165,7 @@ int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char str7x_info = malloc(sizeof(str7x_flash_bank_t)); bank->driver_priv = str7x_info; - if (strcmp(args[5], "STR71x") == 0) + if (strcmp(args[6], "STR71x") == 0) { str7x_info->bank1 = 1; if (bank->base != 0x40000000) @@ -174,7 +174,7 @@ int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char bank->base = 0x40000000; } } - else if (strcmp(args[5], "STR73x") == 0) + else if (strcmp(args[6], "STR73x") == 0) { str7x_info->bank1 = 0; if (bank->base != 0x80000000) @@ -183,7 +183,7 @@ int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char bank->base = 0x80000000; } } - else if (strcmp(args[5], "STR75x") == 0) + else if (strcmp(args[6], "STR75x") == 0) { str7x_info->bank1 = 1; if (bank->base != 0x20000000) @@ -194,17 +194,10 @@ int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char } else { - ERROR("unknown STR7x variant"); + ERROR("unknown STR7x variant: '%s'", args[6]); free(str7x_info); return ERROR_FLASH_BANK_INVALID; } - - str7x_info->target = get_target_by_num(strtoul(args[6], NULL, 0)); - if (!str7x_info->target) - { - ERROR("no target '%s' configured", args[6]); - exit(-1); - } str7x_build_block_list(bank); @@ -215,8 +208,7 @@ int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char u32 str7x_status(struct flash_bank_s *bank) { - str7x_flash_bank_t *str7x_info = bank->driver_priv; - target_t *target = str7x_info->target; + target_t *target = bank->target; u32 retval; target_read_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), &retval); @@ -226,8 +218,7 @@ u32 str7x_status(struct flash_bank_s *bank) u32 str7x_result(struct flash_bank_s *bank) { - str7x_flash_bank_t *str7x_info = bank->driver_priv; - target_t *target = str7x_info->target; + target_t *target = bank->target; u32 retval; target_read_u32(target, str7x_get_flash_adr(bank, FLASH_ER), &retval); @@ -237,8 +228,7 @@ u32 str7x_result(struct flash_bank_s *bank) int str7x_blank_check(struct flash_bank_s *bank, int first, int last) { - str7x_flash_bank_t *str7x_info = bank->driver_priv; - target_t *target = str7x_info->target; + target_t *target = bank->target; u8 *buffer; int i; int nBytes; @@ -246,7 +236,7 @@ int str7x_blank_check(struct flash_bank_s *bank, int first, int last) if ((first < 0) || (last > bank->num_sectors)) return ERROR_FLASH_SECTOR_INVALID; - if (str7x_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -277,12 +267,12 @@ int str7x_blank_check(struct flash_bank_s *bank, int first, int last) int str7x_protect_check(struct flash_bank_s *bank) { str7x_flash_bank_t *str7x_info = bank->driver_priv; - target_t *target = str7x_info->target; + target_t *target = bank->target; int i; u32 retval; - if (str7x_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -303,14 +293,14 @@ int str7x_protect_check(struct flash_bank_s *bank) int str7x_erase(struct flash_bank_s *bank, int first, int last) { str7x_flash_bank_t *str7x_info = bank->driver_priv; - target_t *target = str7x_info->target; + target_t *target = bank->target; int i; u32 cmd; u32 retval; u32 b0_sectors = 0, b1_sectors = 0; - if (str7x_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -392,13 +382,13 @@ int str7x_erase(struct flash_bank_s *bank, int first, int last) int str7x_protect(struct flash_bank_s *bank, int set, int first, int last) { str7x_flash_bank_t *str7x_info = bank->driver_priv; - target_t *target = str7x_info->target; + target_t *target = bank->target; int i; u32 cmd; u32 retval; u32 protect_blocks; - if (str7x_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -445,7 +435,7 @@ int str7x_protect(struct flash_bank_s *bank, int set, int first, int last) int str7x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) { str7x_flash_bank_t *str7x_info = bank->driver_priv; - target_t *target = str7x_info->target; + target_t *target = bank->target; u32 buffer_size = 8192; working_area_t *source; u32 address = bank->base + offset; @@ -564,8 +554,7 @@ int str7x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou int str7x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) { - str7x_flash_bank_t *str7x_info = bank->driver_priv; - target_t *target = str7x_info->target; + target_t *target = bank->target; u32 dwords_remaining = (count / 8); u32 bytes_remaining = (count & 0x00000007); u32 address = bank->base + offset; @@ -575,7 +564,7 @@ int str7x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) u32 check_address = offset; int i; - if (str7x_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } diff --git a/src/flash/str7x.h b/src/flash/str7x.h index ecf64322..a823bb80 100644 --- a/src/flash/str7x.h +++ b/src/flash/str7x.h @@ -26,7 +26,6 @@ typedef struct str7x_flash_bank_s { int bank1; - struct target_s *target; u32 *sector_bank; u32 *sector_bits; working_area_t *write_algorithm; diff --git a/src/flash/str9x.c b/src/flash/str9x.c index b47758d2..66b27036 100644 --- a/src/flash/str9x.c +++ b/src/flash/str9x.c @@ -156,13 +156,6 @@ int str9x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char WARNING("overriding flash base address for STR91x device with 0x00000000"); bank->base = 0x00000000; } - - str9x_info->target = get_target_by_num(strtoul(args[5], NULL, 0)); - if (!str9x_info->target) - { - ERROR("no target '%s' configured", args[5]); - exit(-1); - } str9x_build_block_list(bank); @@ -173,8 +166,7 @@ int str9x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char int str9x_blank_check(struct flash_bank_s *bank, int first, int last) { - str9x_flash_bank_t *str9x_info = bank->driver_priv; - target_t *target = str9x_info->target; + target_t *target = bank->target; u8 *buffer; int i; int nBytes; @@ -182,7 +174,7 @@ int str9x_blank_check(struct flash_bank_s *bank, int first, int last) if ((first < 0) || (last > bank->num_sectors)) return ERROR_FLASH_SECTOR_INVALID; - if (str9x_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -213,13 +205,13 @@ int str9x_blank_check(struct flash_bank_s *bank, int first, int last) int str9x_protect_check(struct flash_bank_s *bank) { str9x_flash_bank_t *str9x_info = bank->driver_priv; - target_t *target = str9x_info->target; + target_t *target = bank->target; int i; u32 adr; u16 status; - if (str9x_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -245,13 +237,12 @@ int str9x_protect_check(struct flash_bank_s *bank) int str9x_erase(struct flash_bank_s *bank, int first, int last) { - str9x_flash_bank_t *str9x_info = bank->driver_priv; - target_t *target = str9x_info->target; + target_t *target = bank->target; int i; u32 adr; u8 status; - if (str9x_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -295,13 +286,12 @@ int str9x_erase(struct flash_bank_s *bank, int first, int last) int str9x_protect(struct flash_bank_s *bank, int set, int first, int last) { - str9x_flash_bank_t *str9x_info = bank->driver_priv; - target_t *target = str9x_info->target; + target_t *target = bank->target; int i; u32 adr; u8 status; - if (str9x_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -328,7 +318,7 @@ int str9x_protect(struct flash_bank_s *bank, int set, int first, int last) int str9x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) { str9x_flash_bank_t *str9x_info = bank->driver_priv; - target_t *target = str9x_info->target; + target_t *target = bank->target; u32 buffer_size = 8192; working_area_t *source; u32 address = bank->base + offset; @@ -440,8 +430,7 @@ int str9x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou int str9x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) { - str9x_flash_bank_t *str9x_info = bank->driver_priv; - target_t *target = str9x_info->target; + target_t *target = bank->target; u32 words_remaining = (count / 2); u32 bytes_remaining = (count & 0x00000001); u32 address = bank->base + offset; @@ -452,7 +441,7 @@ int str9x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) u32 bank_adr; int i; - if (str9x_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -616,9 +605,9 @@ int str9x_handle_flash_config_command(struct command_context_s *cmd_ctx, char *c bank = get_flash_bank_by_num(0); str9x_info = bank->driver_priv; - target = str9x_info->target; + target = bank->target; - if (str9x_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } diff --git a/src/flash/str9x.h b/src/flash/str9x.h index 0cd1f196..e65e3730 100644 --- a/src/flash/str9x.h +++ b/src/flash/str9x.h @@ -25,7 +25,6 @@ typedef struct str9x_flash_bank_s { - struct target_s *target; u32 *sector_bits; working_area_t *write_algorithm; } str9x_flash_bank_t; diff --git a/src/flash/str9xpec.c b/src/flash/str9xpec.c index e8830314..7a8fb2fe 100644 --- a/src/flash/str9xpec.c +++ b/src/flash/str9xpec.c @@ -336,18 +336,11 @@ int str9xpec_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, ch WARNING("overriding flash base address for STR91x device with 0x00000000"); bank->base = 0x00000000; } - - str9xpec_info->target = get_target_by_num(strtoul(args[5], NULL, 0)); - if (!str9xpec_info->target) - { - ERROR("no target '%s' configured", args[5]); - exit(-1); - } /* find out jtag position of flash controller * it is always after the arm966 core */ - armv4_5 = str9xpec_info->target->arch_info; + armv4_5 = bank->target->arch_info; arm7_9 = armv4_5->arch_info; jtag_info = &arm7_9->jtag_info; diff --git a/src/flash/str9xpec.h b/src/flash/str9xpec.h index 3d1b0068..52340a54 100644 --- a/src/flash/str9xpec.h +++ b/src/flash/str9xpec.h @@ -26,7 +26,6 @@ typedef struct str9xpec_flash_controller_s { - struct target_s *target; u32 *sector_bits; int chain_pos; int isc_enable; |