X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fflash%2Fstr9x.c;h=2904d565f3a82d6186b399281a5d2ad51732b741;hb=32310efe1a4b55920eab1d41ab473dc989c9b8ea;hp=a34d40a9ffca200ad19c55733d81138a51dfba11;hpb=bcb0124b1501fb42659cdc2a343dec173aaa196a;p=openocd.git diff --git a/src/flash/str9x.c b/src/flash/str9x.c index a34d40a9ff..2904d565f3 100644 --- a/src/flash/str9x.c +++ b/src/flash/str9x.c @@ -36,24 +36,6 @@ #include #include -str9x_mem_layout_t mem_layout_str9bank0[] = { - {0x00000000, 0x10000, 0x01}, - {0x00010000, 0x10000, 0x02}, - {0x00020000, 0x10000, 0x04}, - {0x00030000, 0x10000, 0x08}, - {0x00040000, 0x10000, 0x10}, - {0x00050000, 0x10000, 0x20}, - {0x00060000, 0x10000, 0x40}, - {0x00070000, 0x10000, 0x80}, -}; - -str9x_mem_layout_t mem_layout_str9bank1[] = { - {0x00000000, 0x02000, 0x100}, - {0x00002000, 0x02000, 0x200}, - {0x00004000, 0x02000, 0x400}, - {0x00006000, 0x02000, 0x800} -}; - static u32 bank1start = 0x00080000; int str9x_register_commands(struct command_context_s *cmd_ctx); @@ -64,7 +46,6 @@ int str9x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count); int str9x_probe(struct flash_bank_s *bank); int str9x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int str9x_protect_check(struct flash_bank_s *bank); -int str9x_erase_check(struct flash_bank_s *bank); int str9x_info(struct flash_bank_s *bank, char *buf, int buf_size); int str9x_handle_flash_config_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); @@ -79,7 +60,7 @@ flash_driver_t str9x_flash = .write = str9x_write, .probe = str9x_probe, .auto_probe = str9x_probe, - .erase_check = str9x_erase_check, + .erase_check = default_flash_blank_check, .protect_check = str9x_protect_check, .info = str9x_info }; @@ -99,9 +80,14 @@ int str9x_build_block_list(struct flash_bank_s *bank) str9x_flash_bank_t *str9x_info = bank->driver_priv; int i; - int num_sectors = 0; + int num_sectors; int b0_sectors = 0, b1_sectors = 0; - + u32 offset = 0; + + /* set if we have large flash str9 */ + str9x_info->variant = 0; + str9x_info->bank1 = 0; + switch (bank->size) { case (256 * 1024): @@ -110,12 +96,29 @@ int str9x_build_block_list(struct flash_bank_s *bank) case (512 * 1024): b0_sectors = 8; break; + case (1024 * 1024): + bank1start = 0x00100000; + str9x_info->variant = 1; + b0_sectors = 16; + break; + case (2048 * 1024): + bank1start = 0x00200000; + str9x_info->variant = 1; + b0_sectors = 32; + break; + case (128 * 1024): + str9x_info->variant = 1; + str9x_info->bank1 = 1; + b1_sectors = 8; + bank1start = bank->base; + break; case (32 * 1024): + str9x_info->bank1 = 1; b1_sectors = 4; bank1start = bank->base; break; default: - ERROR("BUG: unknown bank->size encountered"); + LOG_ERROR("BUG: unknown bank->size encountered"); exit(-1); } @@ -129,20 +132,25 @@ int str9x_build_block_list(struct flash_bank_s *bank) for (i = 0; i < b0_sectors; i++) { - bank->sectors[num_sectors].offset = mem_layout_str9bank0[i].sector_start; - bank->sectors[num_sectors].size = mem_layout_str9bank0[i].sector_size; + bank->sectors[num_sectors].offset = offset; + bank->sectors[num_sectors].size = 0x10000; + offset += bank->sectors[i].size; bank->sectors[num_sectors].is_erased = -1; bank->sectors[num_sectors].is_protected = 1; - str9x_info->sector_bits[num_sectors++] = mem_layout_str9bank0[i].sector_bit; + str9x_info->sector_bits[num_sectors++] = (1<sectors[num_sectors].offset = mem_layout_str9bank1[i].sector_start; - bank->sectors[num_sectors].size = mem_layout_str9bank1[i].sector_size; + bank->sectors[num_sectors].offset = offset; + bank->sectors[num_sectors].size = str9x_info->variant == 0 ? 0x2000 : 0x4000; + offset += bank->sectors[i].size; bank->sectors[num_sectors].is_erased = -1; bank->sectors[num_sectors].is_protected = 1; - str9x_info->sector_bits[num_sectors++] = mem_layout_str9bank1[i].sector_bit; + if (str9x_info->variant) + str9x_info->sector_bits[num_sectors++] = (1<sector_bits[num_sectors++] = (1<<(i+8)); } return ERROR_OK; @@ -156,7 +164,7 @@ int str9x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char if (argc < 6) { - WARNING("incomplete flash_bank str9x configuration"); + LOG_WARNING("incomplete flash_bank str9x configuration"); return ERROR_FLASH_BANK_INVALID; } @@ -170,44 +178,6 @@ int str9x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char return ERROR_OK; } -int str9x_blank_check(struct flash_bank_s *bank, int first, int last) -{ - target_t *target = bank->target; - u8 *buffer; - int i; - int nBytes; - - if ((first < 0) || (last > bank->num_sectors)) - return ERROR_FLASH_SECTOR_INVALID; - - if (bank->target->state != TARGET_HALTED) - { - return ERROR_TARGET_NOT_HALTED; - } - - buffer = malloc(256); - - for (i = first; i <= last; i++) - { - bank->sectors[i].is_erased = 1; - - target->type->read_memory(target, bank->base + bank->sectors[i].offset, 4, 256/4, buffer); - - for (nBytes = 0; nBytes < 256; nBytes++) - { - if (buffer[nBytes] != 0xFF) - { - bank->sectors[i].is_erased = 0; - break; - } - } - } - - free(buffer); - - return ERROR_OK; -} - int str9x_protect_check(struct flash_bank_s *bank) { str9x_flash_bank_t *str9x_info = bank->driver_priv; @@ -215,7 +185,7 @@ int str9x_protect_check(struct flash_bank_s *bank) int i; u32 adr; - u16 status; + u32 status = 0; if (bank->target->state != TARGET_HALTED) { @@ -224,10 +194,29 @@ int str9x_protect_check(struct flash_bank_s *bank) /* read level one protection */ - adr = bank1start + 0x10; + if (str9x_info->variant) + { + if (str9x_info->bank1) + { + adr = bank1start + 0x18; + target_write_u16(target, adr, 0x90); + target_read_u16(target, adr, (u16*)&status); + } + else + { + adr = bank1start + 0x14; + target_write_u16(target, adr, 0x90); + target_read_u32(target, adr, &status); + } + } + else + { + adr = bank1start + 0x10; + target_write_u16(target, adr, 0x90); + target_read_u16(target, adr, (u16*)&status); + } - target_write_u16(target, adr, 0x90); - target_read_u16(target, adr, &status); + /* read array command */ target_write_u16(target, adr, 0xFF); for (i = 0; i < bank->num_sectors; i++) @@ -248,11 +237,16 @@ int str9x_erase(struct flash_bank_s *bank, int first, int last) u32 adr; u8 status; + if (bank->target->state != TARGET_HALTED) + { + return ERROR_TARGET_NOT_HALTED; + } + for (i = first; i <= last; i++) { adr = bank->base + bank->sectors[i].offset; - /* erase sectors */ + /* erase sectors */ target_write_u16(target, adr, 0x20); target_write_u16(target, adr, 0xD0); @@ -274,7 +268,7 @@ int str9x_erase(struct flash_bank_s *bank, int first, int last) if( status & 0x22 ) { - ERROR("error erasing flash bank, status: 0x%x", status); + LOG_ERROR("error erasing flash bank, status: 0x%x", status); return ERROR_FLASH_OPERATION_FAILED; } } @@ -311,6 +305,12 @@ int str9x_protect(struct flash_bank_s *bank, int set, int first, int last) /* query status */ target_read_u8(target, adr, &status); + + /* clear status, also clear read array */ + target_write_u16(target, adr, 0x50); + + /* read array command */ + target_write_u16(target, adr, 0xFF); } return ERROR_OK; @@ -325,7 +325,7 @@ int str9x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou u32 address = bank->base + offset; reg_param_t reg_params[4]; armv4_5_algorithm_t armv4_5_info; - int retval; + int retval = ERROR_OK; u32 str9x_flash_write_code[] = { /* write: */ @@ -355,7 +355,7 @@ int str9x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou /* flash write code */ if (target_alloc_working_area(target, 4 * 19, &str9x_info->write_algorithm) != ERROR_OK) { - WARNING("no working area available, can't do block memory writes"); + LOG_WARNING("no working area available, can't do block memory writes"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; }; @@ -371,7 +371,7 @@ int str9x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou if (str9x_info->write_algorithm) target_free_working_area(target, str9x_info->write_algorithm); - WARNING("no large enough working area available, can't do block memory writes"); + LOG_WARNING("no large enough working area available, can't do block memory writes"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } } @@ -399,13 +399,14 @@ int str9x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou { target_free_working_area(target, source); target_free_working_area(target, str9x_info->write_algorithm); - ERROR("error executing str9x flash write algorithm"); - return ERROR_FLASH_OPERATION_FAILED; + LOG_ERROR("error executing str9x flash write algorithm"); + break; } if (buf_get_u32(reg_params[3].value, 0, 32) != 0x80) { - return ERROR_FLASH_OPERATION_FAILED; + retval = ERROR_FLASH_OPERATION_FAILED; + break; } buffer += thisrun_count * 2; @@ -421,7 +422,7 @@ int str9x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou destroy_reg_param(®_params[2]); destroy_reg_param(®_params[3]); - return ERROR_OK; + return retval; } int str9x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) @@ -437,9 +438,14 @@ int str9x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) u32 bank_adr; int i; + if (bank->target->state != TARGET_HALTED) + { + return ERROR_TARGET_NOT_HALTED; + } + if (offset & 0x1) { - WARNING("offset 0x%x breaks required 2-byte alignment", offset); + LOG_WARNING("offset 0x%x breaks required 2-byte alignment", offset); return ERROR_FLASH_DST_BREAKS_ALIGNMENT; } @@ -472,11 +478,11 @@ int str9x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) { /* if block write failed (no sufficient working area), * we use normal (slow) single dword accesses */ - WARNING("couldn't use block writes, falling back to single memory accesses"); + LOG_WARNING("couldn't use block writes, falling back to single memory accesses"); } else if (retval == ERROR_FLASH_OPERATION_FAILED) { - ERROR("flash writing failed with error code: 0x%x", retval); + LOG_ERROR("flash writing failed with error code: 0x%x", retval); return ERROR_FLASH_OPERATION_FAILED; } } @@ -571,11 +577,6 @@ int str9x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, c return ERROR_OK; } -int str9x_erase_check(struct flash_bank_s *bank) -{ - return str9x_blank_check(bank, 0, bank->num_sectors - 1); -} - int str9x_info(struct flash_bank_s *bank, char *buf, int buf_size) { snprintf(buf, buf_size, "str9x flash driver info" );