X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Ftarget%2Farmv4_5.c;h=9d942ae9f116d644f14987da456233c3e33216de;hb=b62ee5a3c56cfbb000a40c05083dd31720c7cb1e;hp=e1b137f968fb307a581d4ad31641b575d624a3c1;hpb=f90d8fa45f2d4c9d4b7990f198b232ee55cbb4e1;p=fw%2Fopenocd diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index e1b137f96..9d942ae9f 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -299,7 +299,7 @@ int armv4_5_arch_state(struct target_s *target) LOG_USER("target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "", armv4_5_state_strings[armv4_5->core_state], - Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason )->name, + Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name, armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)], buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32), buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)); @@ -339,9 +339,9 @@ int handle_armv4_5_reg_command(struct command_context_s *cmd_ctx, char *cmd, cha { armv4_5->full_context(target); } - output_len += snprintf(output + output_len, - 128 - output_len, - "%8s: %8.8" PRIx32 " ", + output_len += snprintf(output + output_len, + 128 - output_len, + "%8s: %8.8" PRIx32 " ", ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).name, buf_get_u32(ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).value, 0, 32)); } @@ -387,13 +387,15 @@ int handle_armv4_5_core_state_command(struct command_context_s *cmd_ctx, char *c return ERROR_OK; } -int handle_armv4_5_disassemble_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +static int +handle_armv4_5_disassemble_command(struct command_context_s *cmd_ctx, + char *cmd, char **args, int argc) { int retval = ERROR_OK; target_t *target = get_current_target(cmd_ctx); armv4_5_common_t *armv4_5 = target->arch_info; uint32_t address; - int count; + int count = 1; int i; arm_instruction_t cur_instruction; uint32_t opcode; @@ -406,19 +408,32 @@ int handle_armv4_5_disassemble_command(struct command_context_s *cmd_ctx, char * return ERROR_OK; } - if (argc < 2) - { - command_print(cmd_ctx, "usage: armv4_5 disassemble
['thumb']"); + switch (argc) { + case 3: + if (strcmp(args[2], "thumb") != 0) + goto usage; + thumb = 1; + /* FALL THROUGH */ + case 2: + COMMAND_PARSE_NUMBER(int, args[1], count); + /* FALL THROUGH */ + case 1: + COMMAND_PARSE_NUMBER(u32, args[0], address); + if (address & 0x01) { + if (!thumb) { + command_print(cmd_ctx, "Disassemble as Thumb"); + thumb = 1; + } + address &= ~1; + } + break; + default: +usage: + command_print(cmd_ctx, + "usage: armv4_5 disassemble
[ ['thumb']]"); return ERROR_OK; } - address = strtoul(args[0], NULL, 0); - count = strtoul(args[1], NULL, 0); - - if (argc >= 3) - if (strcmp(args[2], "thumb") == 0) - thumb = 1; - for (i = 0; i < count; i++) { if (thumb) @@ -453,12 +468,20 @@ int armv4_5_register_commands(struct command_context_s *cmd_ctx) { command_t *armv4_5_cmd; - armv4_5_cmd = register_command(cmd_ctx, NULL, "armv4_5", NULL, COMMAND_ANY, "armv4/5 specific commands"); + armv4_5_cmd = register_command(cmd_ctx, NULL, "armv4_5", + NULL, COMMAND_ANY, + "armv4/5 specific commands"); - register_command(cmd_ctx, armv4_5_cmd, "reg", handle_armv4_5_reg_command, COMMAND_EXEC, "display ARM core registers"); - register_command(cmd_ctx, armv4_5_cmd, "core_state", handle_armv4_5_core_state_command, COMMAND_EXEC, "display/change ARM core state "); + register_command(cmd_ctx, armv4_5_cmd, "reg", + handle_armv4_5_reg_command, COMMAND_EXEC, + "display ARM core registers"); + register_command(cmd_ctx, armv4_5_cmd, "core_state", + handle_armv4_5_core_state_command, COMMAND_EXEC, + "display/change ARM core state "); + register_command(cmd_ctx, armv4_5_cmd, "disassemble", + handle_armv4_5_disassemble_command, COMMAND_EXEC, + "disassemble instructions
[ ['thumb']]"); - register_command(cmd_ctx, armv4_5_cmd, "disassemble", handle_armv4_5_disassemble_command, COMMAND_EXEC, "disassemble instructions
['thumb']"); return ERROR_OK; } @@ -509,7 +532,10 @@ static int armv4_5_run_algorithm_completion(struct target_s *target, uint32_t ex } return ERROR_TARGET_TIMEOUT; } - if (buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) != exit_point) + + /* fast exit: ARMv5+ code can use BKPT */ + if (exit_point && buf_get_u32(armv4_5->core_cache->reg_list[15].value, + 0, 32) != exit_point) { LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)); @@ -547,6 +573,13 @@ int armv4_5_run_algorithm_inner(struct target_s *target, int num_mem_params, mem if (armv4_5_mode_to_number(armv4_5->core_mode)==-1) return ERROR_FAIL; + /* armv5 and later can terminate with BKPT instruction; less overhead */ + if (!exit_point && armv4_5->is_armv4) + { + LOG_ERROR("ARMv4 target needs HW breakpoint location"); + return ERROR_FAIL; + } + for (i = 0; i <= 16; i++) { if (!ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid) @@ -603,9 +636,11 @@ int armv4_5_run_algorithm_inner(struct target_s *target, int num_mem_params, mem armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1; } - if ((retval = breakpoint_add(target, exit_point, exit_breakpoint_size, BKPT_HARD)) != ERROR_OK) + /* terminate using a hardware or (ARMv5+) software breakpoint */ + if (exit_point && (retval = breakpoint_add(target, exit_point, + exit_breakpoint_size, BKPT_HARD)) != ERROR_OK) { - LOG_ERROR("can't add breakpoint to finish algorithm execution"); + LOG_ERROR("can't add HW breakpoint to terminate algorithm"); return ERROR_TARGET_FAILURE; } @@ -616,7 +651,8 @@ int armv4_5_run_algorithm_inner(struct target_s *target, int num_mem_params, mem int retvaltemp; retval = run_it(target, exit_point, timeout_ms, arch_info); - breakpoint_remove(target, exit_point); + if (exit_point) + breakpoint_remove(target, exit_point); if (retval != ERROR_OK) return retval;