diff options
-rw-r--r-- | src/flash/flash.c | 431 | ||||
-rw-r--r-- | src/flash/nand.c | 601 | ||||
-rw-r--r-- | src/target/arm11.c | 1 |
3 files changed, 498 insertions, 535 deletions
diff --git a/src/flash/flash.c b/src/flash/flash.c index b40e0742..329ade63 100644 --- a/src/flash/flash.c +++ b/src/flash/flash.c @@ -177,35 +177,35 @@ int flash_init_drivers(struct command_context_s *cmd_ctx) { register_jim(cmd_ctx, "ocd_flash_banks", jim_flash_banks, "return information about the flash banks"); - if (flash_banks) - { - register_command(cmd_ctx, flash_cmd, "info", handle_flash_info_command, COMMAND_EXEC, - "print info about flash bank <num>"); - register_command(cmd_ctx, flash_cmd, "probe", handle_flash_probe_command, COMMAND_EXEC, - "identify flash bank <num>"); - register_command(cmd_ctx, flash_cmd, "erase_check", handle_flash_erase_check_command, COMMAND_EXEC, - "check erase state of sectors in flash bank <num>"); - register_command(cmd_ctx, flash_cmd, "protect_check", handle_flash_protect_check_command, COMMAND_EXEC, - "check protection state of sectors in flash bank <num>"); - register_command(cmd_ctx, flash_cmd, "erase_sector", handle_flash_erase_command, COMMAND_EXEC, - "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 (no autoerase) <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, - "write_image [erase] [unlock] <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>"); - } + if (!flash_banks) + return ERROR_OK; + + register_command(cmd_ctx, flash_cmd, "info", handle_flash_info_command, COMMAND_EXEC, + "print info about flash bank <num>"); + register_command(cmd_ctx, flash_cmd, "probe", handle_flash_probe_command, COMMAND_EXEC, + "identify flash bank <num>"); + register_command(cmd_ctx, flash_cmd, "erase_check", handle_flash_erase_check_command, COMMAND_EXEC, + "check erase state of sectors in flash bank <num>"); + register_command(cmd_ctx, flash_cmd, "protect_check", handle_flash_protect_check_command, COMMAND_EXEC, + "check protection state of sectors in flash bank <num>"); + register_command(cmd_ctx, flash_cmd, "erase_sector", handle_flash_erase_command, COMMAND_EXEC, + "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 (no autoerase) <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, + "write_image [erase] [unlock] <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>"); return ERROR_OK; } @@ -292,54 +292,54 @@ static int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cm for (i = 0; flash_drivers[i]; i++) { - if (strcmp(args[0], flash_drivers[i]->name) == 0) - { - flash_bank_t *p, *c; + if (strcmp(args[0], flash_drivers[i]->name) != 0) + continue; - /* register flash specific commands */ - if (flash_drivers[i]->register_commands(cmd_ctx) != ERROR_OK) - { - LOG_ERROR("couldn't register '%s' commands", args[0]); - return ERROR_FAIL; - } + flash_bank_t *p, *c; - c = malloc(sizeof(flash_bank_t)); - c->target = target; - c->driver = flash_drivers[i]; - c->driver_priv = NULL; - COMMAND_PARSE_NUMBER(u32, args[1], c->base); - COMMAND_PARSE_NUMBER(u32, args[2], c->size); - COMMAND_PARSE_NUMBER(int, args[3], c->chip_width); - COMMAND_PARSE_NUMBER(int, args[4], c->bus_width); - c->num_sectors = 0; - c->sectors = NULL; - c->next = NULL; - - if ((retval = flash_drivers[i]->flash_bank_command(cmd_ctx, cmd, args, argc, c)) != ERROR_OK) - { - LOG_ERROR("'%s' driver rejected flash bank at 0x%8.8" PRIx32 , args[0], c->base); - free(c); - return retval; - } + /* register flash specific commands */ + if (flash_drivers[i]->register_commands(cmd_ctx) != ERROR_OK) + { + LOG_ERROR("couldn't register '%s' commands", args[0]); + return ERROR_FAIL; + } - /* put flash bank in linked list */ - if (flash_banks) - { - int bank_num = 0; - /* find last flash bank */ - for (p = flash_banks; p && p->next; p = p->next) bank_num++; - if (p) - p->next = c; - c->bank_number = bank_num + 1; - } - else - { - flash_banks = c; - c->bank_number = 0; - } + c = malloc(sizeof(flash_bank_t)); + c->target = target; + c->driver = flash_drivers[i]; + c->driver_priv = NULL; + COMMAND_PARSE_NUMBER(u32, args[1], c->base); + COMMAND_PARSE_NUMBER(u32, args[2], c->size); + COMMAND_PARSE_NUMBER(int, args[3], c->chip_width); + COMMAND_PARSE_NUMBER(int, args[4], c->bus_width); + c->num_sectors = 0; + c->sectors = NULL; + c->next = NULL; + + if ((retval = flash_drivers[i]->flash_bank_command(cmd_ctx, cmd, args, argc, c)) != ERROR_OK) + { + LOG_ERROR("'%s' driver rejected flash bank at 0x%8.8" PRIx32 , args[0], c->base); + free(c); + return retval; + } - found = 1; + /* put flash bank in linked list */ + if (flash_banks) + { + int bank_num = 0; + /* find last flash bank */ + for (p = flash_banks; p && p->next; p = p->next) bank_num++; + if (p) + p->next = c; + c->bank_number = bank_num + 1; } + else + { + flash_banks = c; + c->bank_number = 0; + } + + found = 1; } /* no matching flash driver found */ @@ -367,48 +367,48 @@ static int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cm for (p = flash_banks; p; p = p->next, i++) { - if (i == bank_nr) + if (i != bank_nr) + continue; + + char buf[1024]; + + /* attempt auto probe */ + if ((retval = p->driver->auto_probe(p)) != ERROR_OK) + return retval; + + command_print(cmd_ctx, + "#%" PRIi32 " : %s at 0x%8.8" PRIx32 ", size 0x%8.8" PRIx32 ", buswidth %i, chipwidth %i", + i, + p->driver->name, + p->base, + p->size, + p->bus_width, + p->chip_width); + for (j = 0; j < p->num_sectors; j++) { - char buf[1024]; + char *protect_state; - /* attempt auto probe */ - if ((retval = p->driver->auto_probe(p)) != ERROR_OK) - return retval; + if (p->sectors[j].is_protected == 0) + protect_state = "not protected"; + else if (p->sectors[j].is_protected == 1) + protect_state = "protected"; + else + protect_state = "protection state unknown"; command_print(cmd_ctx, - "#%" PRIi32 " : %s at 0x%8.8" PRIx32 ", size 0x%8.8" PRIx32 ", buswidth %i, chipwidth %i", - i, - p->driver->name, - p->base, - p->size, - p->bus_width, - p->chip_width); - for (j = 0; j < p->num_sectors; j++) - { - char *protect_state; - - if (p->sectors[j].is_protected == 0) - protect_state = "not protected"; - else if (p->sectors[j].is_protected == 1) - protect_state = "protected"; - else - protect_state = "protection state unknown"; - - command_print(cmd_ctx, - "\t#%3i: 0x%8.8" PRIx32 " (0x%" PRIx32 " %" PRIi32 "kB) %s", - j, - p->sectors[j].offset, - p->sectors[j].size, - p->sectors[j].size >> 10, - protect_state); - } - - *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); + "\t#%3i: 0x%8.8" PRIx32 " (0x%" PRIx32 " %" PRIi32 "kB) %s", + j, + p->sectors[j].offset, + p->sectors[j].size, + p->sectors[j].size >> 10, + protect_state); } + + *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); } return ERROR_OK; @@ -463,38 +463,35 @@ static int handle_flash_erase_check_command(struct command_context_s *cmd_ctx, c if (ERROR_OK != retval) return retval; - if (p) + int j; + if ((retval = p->driver->erase_check(p)) == ERROR_OK) { - int j; - if ((retval = p->driver->erase_check(p)) == ERROR_OK) - { - command_print(cmd_ctx, "successfully checked erase state"); - } - else - { - command_print(cmd_ctx, "unknown error when checking erase state of flash bank #%s at 0x%8.8" PRIx32, - args[0], p->base); - } + command_print(cmd_ctx, "successfully checked erase state"); + } + else + { + command_print(cmd_ctx, "unknown error when checking erase state of flash bank #%s at 0x%8.8" PRIx32, + args[0], p->base); + } - for (j = 0; j < p->num_sectors; j++) - { - char *erase_state; + for (j = 0; j < p->num_sectors; j++) + { + char *erase_state; - if (p->sectors[j].is_erased == 0) - erase_state = "not erased"; - else if (p->sectors[j].is_erased == 1) - erase_state = "erased"; - else - erase_state = "erase state unknown"; + if (p->sectors[j].is_erased == 0) + erase_state = "not erased"; + else if (p->sectors[j].is_erased == 1) + erase_state = "erased"; + else + erase_state = "erase state unknown"; - command_print(cmd_ctx, - "\t#%3i: 0x%8.8" PRIx32 " (0x%" PRIx32 " %" PRIi32 "kB) %s", - j, - p->sectors[j].offset, - p->sectors[j].size, - p->sectors[j].size >> 10, - erase_state); - } + command_print(cmd_ctx, + "\t#%3i: 0x%8.8" PRIx32 " (0x%" PRIx32 " %" PRIi32 "kB) %s", + j, + p->sectors[j].offset, + p->sectors[j].size, + p->sectors[j].size >> 10, + erase_state); } return ERROR_OK; @@ -556,21 +553,17 @@ static int handle_flash_protect_check_command(struct command_context_s *cmd_ctx, if (ERROR_OK != retval) return retval; - if (p) + if ((retval = p->driver->protect_check(p)) == ERROR_OK) { - int retval; - if ((retval = p->driver->protect_check(p)) == ERROR_OK) - { - command_print(cmd_ctx, "successfully checked protect state"); - } - else if (retval == ERROR_FLASH_OPERATION_FAILED) - { - command_print(cmd_ctx, "checking protection state failed (possibly unsupported) by flash #%s at 0x%8.8" PRIx32, args[0], p->base); - } - else - { - command_print(cmd_ctx, "unknown error when checking protection state of flash bank '#%s' at 0x%8.8" PRIx32, args[0], p->base); - } + command_print(cmd_ctx, "successfully checked protect state"); + } + else if (retval == ERROR_FLASH_OPERATION_FAILED) + { + command_print(cmd_ctx, "checking protection state failed (possibly unsupported) by flash #%s at 0x%8.8" PRIx32, args[0], p->base); + } + else + { + command_print(cmd_ctx, "unknown error when checking protection state of flash bank '#%s' at 0x%8.8" PRIx32, args[0], p->base); } return ERROR_OK; @@ -597,45 +590,43 @@ static int flash_check_sector_parameters(struct command_context_s *cmd_ctx, static int handle_flash_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { - if (argc > 2) - { - uint32_t bank_nr; - uint32_t first; - uint32_t last; - - COMMAND_PARSE_NUMBER(u32, args[0], bank_nr); - flash_bank_t *p = get_flash_bank_by_num(bank_nr); - if (!p) - return ERROR_OK; - - COMMAND_PARSE_NUMBER(u32, args[1], first); - if (strcmp(args[2], "last") == 0) - last = p->num_sectors - 1; - else - COMMAND_PARSE_NUMBER(u32, args[2], last); + if (argc != 2) + return ERROR_COMMAND_SYNTAX_ERROR; - int retval; - if ((retval = flash_check_sector_parameters(cmd_ctx, - first, last, p->num_sectors)) != ERROR_OK) - return retval; + uint32_t bank_nr; + uint32_t first; + uint32_t last; - duration_t duration; - char *duration_text; - duration_start_measure(&duration); + COMMAND_PARSE_NUMBER(u32, args[0], bank_nr); + flash_bank_t *p = get_flash_bank_by_num(bank_nr); + if (!p) + return ERROR_OK; - if ((retval = flash_driver_erase(p, first, last)) == ERROR_OK) { - if ((retval = duration_stop_measure(&duration, - &duration_text)) != ERROR_OK) - return retval; - command_print(cmd_ctx, "erased sectors %i through %i " - "on flash bank %i in %s", - (int) first, (int) last, (int) bank_nr, - duration_text); - free(duration_text); - } - } + COMMAND_PARSE_NUMBER(u32, args[1], first); + if (strcmp(args[2], "last") == 0) + last = p->num_sectors - 1; else - return ERROR_COMMAND_SYNTAX_ERROR; + COMMAND_PARSE_NUMBER(u32, args[2], last); + + int retval; + if ((retval = flash_check_sector_parameters(cmd_ctx, + first, last, p->num_sectors)) != ERROR_OK) + return retval; + + duration_t duration; + char *duration_text; + duration_start_measure(&duration); + + if ((retval = flash_driver_erase(p, first, last)) == ERROR_OK) { + if ((retval = duration_stop_measure(&duration, + &duration_text)) != ERROR_OK) + return retval; + command_print(cmd_ctx, "erased sectors %i through %i " + "on flash bank %i in %s", + (int) first, (int) last, (int) bank_nr, + duration_text); + free(duration_text); + } return ERROR_OK; } @@ -643,47 +634,45 @@ static int handle_flash_erase_command(struct command_context_s *cmd_ctx, static int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { - if (argc > 3) - { - uint32_t bank_nr; - uint32_t first; - uint32_t last; - int set; - - COMMAND_PARSE_NUMBER(u32, args[0], bank_nr); - flash_bank_t *p = get_flash_bank_by_num(bank_nr); - if (!p) - return ERROR_OK; - - COMMAND_PARSE_NUMBER(u32, args[1], first); - if (strcmp(args[2], "last") == 0) - last = p->num_sectors - 1; - else - COMMAND_PARSE_NUMBER(u32, args[2], last); + if (argc != 3) + return ERROR_COMMAND_SYNTAX_ERROR; - if (strcmp(args[3], "on") == 0) - set = 1; - else if (strcmp(args[3], "off") == 0) - set = 0; - else - return ERROR_COMMAND_SYNTAX_ERROR; + uint32_t bank_nr; + uint32_t first; + uint32_t last; + int set; - int retval; - if ((retval = flash_check_sector_parameters(cmd_ctx, - first, last, p->num_sectors)) != ERROR_OK) - return retval; + COMMAND_PARSE_NUMBER(u32, args[0], bank_nr); + flash_bank_t *p = get_flash_bank_by_num(bank_nr); + if (!p) + return ERROR_OK; - retval = flash_driver_protect(p, set, first, last); - if (retval == ERROR_OK) { - command_print(cmd_ctx, "%s protection for sectors %i " - "through %i on flash bank %i", - (set) ? "set" : "cleared", (int) first, - (int) last, (int) bank_nr); - } - } + COMMAND_PARSE_NUMBER(u32, args[1], first); + if (strcmp(args[2], "last") == 0) + last = p->num_sectors - 1; + else + COMMAND_PARSE_NUMBER(u32, args[2], last); + + if (strcmp(args[3], "on") == 0) + set = 1; + else if (strcmp(args[3], "off") == 0) + set = 0; else return ERROR_COMMAND_SYNTAX_ERROR; + int retval; + if ((retval = flash_check_sector_parameters(cmd_ctx, + first, last, p->num_sectors)) != ERROR_OK) + return retval; + + retval = flash_driver_protect(p, set, first, last); + if (retval == ERROR_OK) { + command_print(cmd_ctx, "%s protection for sectors %i " + "through %i on flash bank %i", + (set) ? "set" : "cleared", (int) first, + (int) last, (int) bank_nr); + } + return ERROR_OK; } diff --git a/src/flash/nand.c b/src/flash/nand.c index 7fb7c99e..81a04f7a 100644 --- a/src/flash/nand.c +++ b/src/flash/nand.c @@ -1135,50 +1135,46 @@ static int handle_nand_info_command(struct command_context_s *cmd_ctx, char *cmd break; } - if (p) + if (NULL == p->device) { - if (p->device) - { - if (first >= p->num_blocks) - first = p->num_blocks - 1; + command_print(cmd_ctx, "#%s: not probed", args[0]); + return ERROR_OK; + } - if (last >= p->num_blocks) - last = p->num_blocks - 1; + if (first >= p->num_blocks) + first = p->num_blocks - 1; - command_print(cmd_ctx, "#%i: %s (%s) pagesize: %i, buswidth: %i, erasesize: %i", - i++, p->device->name, p->manufacturer->name, p->page_size, p->bus_width, p->erase_size); + if (last >= p->num_blocks) + last = p->num_blocks - 1; - for (j = first; j <= last; j++) - { - char *erase_state, *bad_state; + command_print(cmd_ctx, "#%i: %s (%s) pagesize: %i, buswidth: %i, erasesize: %i", + i++, p->device->name, p->manufacturer->name, p->page_size, p->bus_width, p->erase_size); - if (p->blocks[j].is_erased == 0) - erase_state = "not erased"; - else if (p->blocks[j].is_erased == 1) - erase_state = "erased"; - else - erase_state = "erase state unknown"; + for (j = first; j <= last; j++) + { + char *erase_state, *bad_state; - if (p->blocks[j].is_bad == 0) - bad_state = ""; - else if (p->blocks[j].is_bad == 1) - bad_state = " (marked bad)"; - else - bad_state = " (block condition unknown)"; - - command_print(cmd_ctx, - "\t#%i: 0x%8.8" PRIx32 " (%" PRId32 "kB) %s%s", - j, - p->blocks[j].offset, - p->blocks[j].size / 1024, - erase_state, - bad_state); - } - } + if (p->blocks[j].is_erased == 0) + erase_state = "not erased"; + else if (p->blocks[j].is_erased == 1) + erase_state = "erased"; else - { - command_print(cmd_ctx, "#%s: not probed", args[0]); - } + erase_state = "erase state unknown"; + + if (p->blocks[j].is_bad == 0) + bad_state = ""; + else if (p->blocks[j].is_bad == 1) + bad_state = " (marked bad)"; + else + bad_state = " (block condition unknown)"; + + command_print(cmd_ctx, + "\t#%i: 0x%8.8" PRIx32 " (%" PRId32 "kB) %s%s", + j, + p->blocks[j].offset, + p->blocks[j].size / 1024, + erase_state, + bad_state); } return ERROR_OK; @@ -1196,20 +1192,17 @@ static int handle_nand_probe_command(struct command_context_s *cmd_ctx, char *cm if (ERROR_OK != retval) return retval; - if (p) + if ((retval = nand_probe(p)) == ERROR_OK) { - if ((retval = nand_probe(p)) == ERROR_OK) - { - command_print(cmd_ctx, "NAND flash device '%s' found", p->device->name); - } - else if (retval == ERROR_NAND_OPERATION_FAILED) - { - command_print(cmd_ctx, "probing failed for NAND flash device"); - } - else - { - command_print(cmd_ctx, "unknown error when probing NAND flash device"); - } + command_print(cmd_ctx, "NAND flash device '%s' found", p->device->name); + } + else if (retval == ERROR_NAND_OPERATION_FAILED) + { + command_print(cmd_ctx, "probing failed for NAND flash device"); + } + else + { + command_print(cmd_ctx, "unknown error when probing NAND flash device"); } return ERROR_OK; @@ -1228,47 +1221,44 @@ static int handle_nand_erase_command(struct command_context_s *cmd_ctx, char *cm if (ERROR_OK != retval) return retval; - if (p) - { - unsigned long offset; - unsigned long length; + unsigned long offset; + unsigned long length; - /* erase specified part of the chip; or else everything */ - if (argc == 3) { - unsigned long size = p->erase_size * p->num_blocks; + /* erase specified part of the chip; or else everything */ + if (argc == 3) { + unsigned long size = p->erase_size * p->num_blocks; - COMMAND_PARSE_NUMBER(ulong, args[1], offset); - if ((offset % p->erase_size) != 0 || offset >= size) - return ERROR_INVALID_ARGUMENTS; + COMMAND_PARSE_NUMBER(ulong, args[1], offset); + if ((offset % p->erase_size) != 0 || offset >= size) + return ERROR_INVALID_ARGUMENTS; - COMMAND_PARSE_NUMBER(ulong, args[2], length); - if ((length == 0) || (length % p->erase_size) != 0 - || (length + offset) > size) - return ERROR_INVALID_ARGUMENTS; + COMMAND_PARSE_NUMBER(ulong, args[2], length); + if ((length == 0) || (length % p->erase_size) != 0 + || (length + offset) > size) + return ERROR_INVALID_ARGUMENTS; - offset /= p->erase_size; - length /= p->erase_size; - } else { - offset = 0; - length = p->num_blocks; - } + offset /= p->erase_size; + length /= p->erase_size; + } else { + offset = 0; + length = p->num_blocks; + } - retval = nand_erase(p, offset, offset + length - 1); - if (retval == ERROR_OK) - { - command_print(cmd_ctx, "erased blocks %lu to %lu " - "on NAND flash device #%s '%s'", - offset, offset + length, - args[0], p->device->name); - } - else if (retval == ERROR_NAND_OPERATION_FAILED) - { - command_print(cmd_ctx, "erase failed"); - } - else - { - command_print(cmd_ctx, "unknown error when erasing NAND flash device"); - } + retval = nand_erase(p, offset, offset + length - 1); + if (retval == ERROR_OK) + { + command_print(cmd_ctx, "erased blocks %lu to %lu " + "on NAND flash device #%s '%s'", + offset, offset + length, + args[0], p->device->name); + } + else if (retval == ERROR_NAND_OPERATION_FAILED) + { + command_print(cmd_ctx, "erase failed"); + } + else + { + command_print(cmd_ctx, "unknown error when erasing NAND flash device"); } return ERROR_OK; @@ -1353,150 +1343,147 @@ static int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cm if (ERROR_OK != retval) return retval; - if (p) - { - uint8_t *page = NULL; - uint32_t page_size = 0; - uint8_t *oob = NULL; - uint32_t oob_size = 0; - const int *eccpos = NULL; + uint8_t *page = NULL; + uint32_t page_size = 0; + uint8_t *oob = NULL; + uint32_t oob_size = 0; + const int *eccpos = NULL; - COMMAND_PARSE_NUMBER(u32, args[2], offset); + COMMAND_PARSE_NUMBER(u32, args[2], offset); - if (argc > 3) + if (argc > 3) + { + int i; + for (i = 3; i < argc; i++) { - int i; - for (i = 3; i < argc; i++) + if (!strcmp(args[i], "oob_raw")) + oob_format |= NAND_OOB_RAW; + else if (!strcmp(args[i], "oob_only")) + oob_format |= NAND_OOB_RAW | NAND_OOB_ONLY; + else if (!strcmp(args[i], "oob_softecc")) + oob_format |= NAND_OOB_SW_ECC; + else if (!strcmp(args[i], "oob_softecc_kw")) + oob_format |= NAND_OOB_SW_ECC_KW; + else { - if (!strcmp(args[i], "oob_raw")) - oob_format |= NAND_OOB_RAW; - else if (!strcmp(args[i], "oob_only")) - oob_format |= NAND_OOB_RAW | NAND_OOB_ONLY; - else if (!strcmp(args[i], "oob_softecc")) - oob_format |= NAND_OOB_SW_ECC; - else if (!strcmp(args[i], "oob_softecc_kw")) - oob_format |= NAND_OOB_SW_ECC_KW; - else - { - command_print(cmd_ctx, "unknown option: %s", args[i]); - return ERROR_COMMAND_SYNTAX_ERROR; - } + command_print(cmd_ctx, "unknown option: %s", args[i]); + return ERROR_COMMAND_SYNTAX_ERROR; } } + } - duration_start_measure(&duration); + duration_start_measure(&duration); - if (fileio_open(&fileio, args[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK) - { - return ERROR_OK; - } + if (fileio_open(&fileio, args[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK) + { + return ERROR_OK; + } - buf_cnt = binary_size = fileio.size; + buf_cnt = binary_size = fileio.size; - if (!(oob_format & NAND_OOB_ONLY)) - { - page_size = p->page_size; - page = malloc(p->page_size); - } + if (!(oob_format & NAND_OOB_ONLY)) + { + page_size = p->page_size; + page = malloc(p->page_size); + } - if (oob_format & (NAND_OOB_RAW | NAND_OOB_SW_ECC | NAND_OOB_SW_ECC_KW)) - { - if (p->page_size == 512) { - oob_size = 16; - eccpos = nand_oob_16.eccpos; - } else if (p->page_size == 2048) { - oob_size = 64; - eccpos = nand_oob_64.eccpos; - } - oob = malloc(oob_size); + if (oob_format & (NAND_OOB_RAW | NAND_OOB_SW_ECC | NAND_OOB_SW_ECC_KW)) + { + if (p->page_size == 512) { + oob_size = 16; + eccpos = nand_oob_16.eccpos; + } else if (p->page_size == 2048) { + oob_size = 64; + eccpos = nand_oob_64.eccpos; } + oob = malloc(oob_size); + } - if (offset % p->page_size) - { - command_print(cmd_ctx, "only page size aligned offsets and sizes are supported"); - fileio_close(&fileio); - free(oob); - free(page); - return ERROR_OK; - } + if (offset % p->page_size) + { + command_print(cmd_ctx, "only page size aligned offsets and sizes are supported"); + fileio_close(&fileio); + free(oob); + free(page); + return ERROR_OK; + } - while (buf_cnt > 0) - { - uint32_t size_read; + while (buf_cnt > 0) + { + uint32_t size_read; - if (NULL != page) + if (NULL != page) + { + fileio_read(&fileio, page_size, page, &size_read); + buf_cnt -= size_read; + if (size_read < page_size) { - fileio_read(&fileio, page_size, page, &size_read); - buf_cnt -= size_read; - if (size_read < page_size) - { - memset(page + size_read, 0xff, page_size - size_read); - } + memset(page + size_read, 0xff, page_size - size_read); } + } - if (oob_format & NAND_OOB_SW_ECC) - { - uint32_t i, j; - uint8_t ecc[3]; - memset(oob, 0xff, oob_size); - for (i = 0, j = 0; i < page_size; i += 256) { - nand_calculate_ecc(p, page + i, ecc); - oob[eccpos[j++]] = ecc[0]; - oob[eccpos[j++]] = ecc[1]; - oob[eccpos[j++]] = ecc[2]; - } - } else if (oob_format & NAND_OOB_SW_ECC_KW) - { - /* - * In this case eccpos is not used as - * the ECC data is always stored contigously - * at the end of the OOB area. It consists - * of 10 bytes per 512-byte data block. - */ - uint32_t i; - uint8_t *ecc = oob + oob_size - page_size/512 * 10; - memset(oob, 0xff, oob_size); - for (i = 0; i < page_size; i += 512) { - nand_calculate_ecc_kw(p, page + i, ecc); - ecc += 10; - } + if (oob_format & NAND_OOB_SW_ECC) + { + uint32_t i, j; + uint8_t ecc[3]; + memset(oob, 0xff, oob_size); + for (i = 0, j = 0; i < page_size; i += 256) { + nand_calculate_ecc(p, page + i, ecc); + oob[eccpos[j++]] = ecc[0]; + oob[eccpos[j++]] = ecc[1]; + oob[eccpos[j++]] = ecc[2]; + } + } else if (oob_format & NAND_OOB_SW_ECC_KW) + { + /* + * In this case eccpos is not used as + * the ECC data is always stored contigously + * at the end of the OOB area. It consists + * of 10 bytes per 512-byte data block. + */ + uint32_t i; + uint8_t *ecc = oob + oob_size - page_size/512 * 10; + memset(oob, 0xff, oob_size); + for (i = 0; i < page_size; i += 512) { + nand_calculate_ecc_kw(p, page + i, ecc); + ecc += 10; } - else if (NULL != oob) + } + else if (NULL != oob) + { + fileio_read(&fileio, oob_size, oob, &size_read); + buf_cnt -= size_read; + if (size_read < oob_size) { - fileio_read(&fileio, oob_size, oob, &size_read); - buf_cnt -= size_read; - if (size_read < oob_size) - { - memset(oob + size_read, 0xff, oob_size - size_read); - } + memset(oob + size_read, 0xff, oob_size - size_read); } + } - if (nand_write_page(p, offset / p->page_size, page, page_size, oob, oob_size) != ERROR_OK) - { - command_print(cmd_ctx, "failed writing file %s to NAND flash %s at offset 0x%8.8" PRIx32 "", - args[1], args[0], offset); + if (nand_write_page(p, offset / p->page_size, page, page_size, oob, oob_size) != ERROR_OK) + { + command_print(cmd_ctx, "failed writing file %s to NAND flash %s at offset 0x%8.8" PRIx32 "", + args[1], args[0], offset); - fileio_close(&fileio); - free(oob); - free(page); + fileio_close(&fileio); + free(oob); + free(page); - return ERROR_OK; - } - offset += page_size; + return ERROR_OK; } - - fileio_close(&fileio); - free(oob); - free(page); - oob = NULL; - page = NULL; - duration_stop_measure(&duration, &duration_text); - command_print(cmd_ctx, "wrote file %s to NAND flash %s up to offset 0x%8.8" PRIx32 " in %s", - args[1], args[0], offset, duration_text); - free(duration_text); - duration_text = NULL; + offset += page_size; } + fileio_close(&fileio); + free(oob); + free(page); + oob = NULL; + page = NULL; + duration_stop_measure(&duration, &duration_text); + command_print(cmd_ctx, "wrote file %s to NAND flash %s up to offset 0x%8.8" PRIx32 " in %s", + args[1], args[0], offset, duration_text); + free(duration_text); + duration_text = NULL; + return ERROR_OK; } @@ -1512,113 +1499,108 @@ static int handle_nand_dump_command(struct command_context_s *cmd_ctx, char *cmd if (ERROR_OK != retval) return retval; - if (p) + if (NULL == p->device) { - if (p->device) - { - fileio_t fileio; - duration_t duration; - char *duration_text; - int retval; - - uint8_t *page = NULL; - uint32_t page_size = 0; - uint8_t *oob = NULL; - uint32_t oob_size = 0; - uint32_t address; - COMMAND_PARSE_NUMBER(u32, args[2], address); - uint32_t size; - COMMAND_PARSE_NUMBER(u32, args[3], size); - uint32_t bytes_done = 0; - enum oob_formats oob_format = NAND_OOB_NONE; - - if (argc > 4) - { - int i; - for (i = 4; i < argc; i++) - { - if (!strcmp(args[i], "oob_raw")) - oob_format |= NAND_OOB_RAW; - else if (!strcmp(args[i], "oob_only")) - oob_format |= NAND_OOB_RAW | NAND_OOB_ONLY; - else - command_print(cmd_ctx, "unknown option: '%s'", args[i]); - } - } - - if ((address % p->page_size) || (size % p->page_size)) - { - command_print(cmd_ctx, "only page size aligned addresses and sizes are supported"); - return ERROR_OK; - } + command_print(cmd_ctx, "#%s: not probed", args[0]); + return ERROR_OK; + } - if (!(oob_format & NAND_OOB_ONLY)) - { - page_size = p->page_size; - page = malloc(p->page_size); - } + fileio_t fileio; + duration_t duration; + char *duration_text; - if (oob_format & NAND_OOB_RAW) - { - if (p->page_size == 512) - oob_size = 16; - else if (p->page_size == 2048) - oob_size = 64; - oob = malloc(oob_size); - } + uint8_t *page = NULL; + uint32_t page_size = 0; + uint8_t *oob = NULL; + uint32_t oob_size = 0; + uint32_t address; + COMMAND_PARSE_NUMBER(u32, args[2], address); + uint32_t size; + COMMAND_PARSE_NUMBER(u32, args[3], size); + uint32_t bytes_done = 0; + enum oob_formats oob_format = NAND_OOB_NONE; - if (fileio_open(&fileio, args[1], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK) - { - return ERROR_OK; - } + if (argc > 4) + { + int i; + for (i = 4; i < argc; i++) + { + if (!strcmp(args[i], "oob_raw")) + oob_format |= NAND_OOB_RAW; + else if (!strcmp(args[i], "oob_only")) + oob_format |= NAND_OOB_RAW | NAND_OOB_ONLY; + else + command_print(cmd_ctx, "unknown option: '%s'", args[i]); + } + } - duration_start_measure(&duration); + if ((address % p->page_size) || (size % p->page_size)) + { + command_print(cmd_ctx, "only page size aligned addresses and sizes are supported"); + return ERROR_OK; + } - while (size > 0) - { - uint32_t size_written; - if ((retval = nand_read_page(p, address / p->page_size, page, page_size, oob, oob_size)) != ERROR_OK) - { - command_print(cmd_ctx, "reading NAND flash page failed"); - free(page); - free(oob); - fileio_close(&fileio); - return ERROR_OK; - } + if (!(oob_format & NAND_OOB_ONLY)) + { + page_size = p->page_size; + page = malloc(p->page_size); + } - if (NULL != page) - { - fileio_write(&fileio, page_size, page, &size_written); - bytes_done += page_size; - } + if (oob_format & NAND_OOB_RAW) + { + if (p->page_size == 512) + oob_size = 16; + else if (p->page_size == 2048) + oob_size = 64; + oob = malloc(oob_size); + } - if (NULL != oob) - { - fileio_write(&fileio, oob_size, oob, &size_written); - bytes_done += oob_size; - } + if (fileio_open(&fileio, args[1], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK) + { + return ERROR_OK; + } - size -= p->page_size; - address += p->page_size; - } + duration_start_measure(&duration); + while (size > 0) + { + uint32_t size_written; + if ((retval = nand_read_page(p, address / p->page_size, page, page_size, oob, oob_size)) != ERROR_OK) + { + command_print(cmd_ctx, "reading NAND flash page failed"); free(page); - page = NULL; free(oob); - oob = NULL; fileio_close(&fileio); + return ERROR_OK; + } - duration_stop_measure(&duration, &duration_text); - command_print(cmd_ctx, "dumped %lld byte in %s", fileio.size, duration_text); - free(duration_text); - duration_text = NULL; + if (NULL != page) + { + fileio_write(&fileio, page_size, page, &size_written); + bytes_done += page_size; } - else + + if (NULL != oob) { - command_print(cmd_ctx, "#%s: not probed", args[0]); + fileio_write(&fileio, oob_size, oob, &size_written); + bytes_done += oob_size; } + + size -= p->page_size; + address += p->page_size; } + free(page); + page = NULL; + free(oob); + oob = NULL; + fileio_close(&fileio); + + duration_stop_measure(&duration, &duration_text); + command_print(cmd_ctx, "dumped %lld byte in %s", fileio.size, duration_text); + free(duration_text); + duration_text = NULL; + return ERROR_OK; } @@ -1634,33 +1616,24 @@ static int handle_nand_raw_access_command(struct command_context_s *cmd_ctx, cha if (ERROR_OK != retval) return retval; - if (p) + if (NULL == p->device) { - if (p->device) - { - if (argc == 2) - { - if (strcmp("enable", args[1]) == 0) - { - p->use_raw = 1; - } - else if (strcmp("disable", args[1]) == 0) - { - p->use_raw = 0; - } - else - { - return ERROR_COMMAND_SYNTAX_ERROR; - } - } + command_print(cmd_ctx, "#%s: not probed", args[0]); + return ERROR_OK; + } - command_print(cmd_ctx, "raw access is %s", (p->use_raw) ? "enabled" : "disabled"); - } + if (argc == 2) + { + if (strcmp("enable", args[1]) == 0) + p->use_raw = 1; + else if (strcmp("disable", args[1]) == 0) + p->use_raw = 0; else - { - command_print(cmd_ctx, "#%s: not probed", args[0]); - } + return ERROR_COMMAND_SYNTAX_ERROR; } + const char *msg = p->use_raw ? "enabled" : "disabled"; + command_print(cmd_ctx, "raw access is %s", msg); + return ERROR_OK; } diff --git a/src/target/arm11.c b/src/target/arm11.c index 28ee7238..9cb80f11 100644 --- a/src/target/arm11.c +++ b/src/target/arm11.c @@ -2065,6 +2065,7 @@ int arm11_handle_vcr(struct command_context_s *cmd_ctx, char *cmd, char **args, break; case 1: COMMAND_PARSE_NUMBER(u32, args[0], arm11_vcr); + break; default: return ERROR_COMMAND_SYNTAX_ERROR; } |