mem_param_t -> struct mem_param
[openocd.git] / src / target / armv4_5.c
index 33f1a5183b20027a92236a9d85435da3008a2054..12509aa8ad02c8246c5ef3de75dc6371f0061aee 100644 (file)
@@ -189,7 +189,7 @@ int armv4_5_set_core_reg(reg_t *reg, uint8_t *buf)
 {
        armv4_5_core_reg_t *armv4_5 = reg->arch_info;
        target_t *target = armv4_5->target;
-       armv4_5_common_t *armv4_5_target = target->arch_info;
+       struct armv4_5_common_s *armv4_5_target = target_to_armv4_5(target);
        uint32_t value = buf_get_u32(buf, 0, 32);
 
        if (target->state != TARGET_HALTED)
@@ -237,7 +237,7 @@ int armv4_5_set_core_reg(reg_t *reg, uint8_t *buf)
 
 int armv4_5_invalidate_core_regs(target_t *target)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
+       struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
        int i;
 
        for (i = 0; i < 37; i++)
@@ -289,7 +289,7 @@ reg_cache_t* armv4_5_build_reg_cache(target_t *target, armv4_5_common_t *armv4_5
 
 int armv4_5_arch_state(struct target_s *target)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
+       struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
 
        if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
        {
@@ -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));
@@ -307,13 +307,13 @@ int armv4_5_arch_state(struct target_s *target)
        return ERROR_OK;
 }
 
-int handle_armv4_5_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+COMMAND_HANDLER(handle_armv4_5_reg_command)
 {
        char output[128];
        int output_len;
        int mode, num;
        target_t *target = get_current_target(cmd_ctx);
-       armv4_5_common_t *armv4_5 = target->arch_info;
+       struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
 
        if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
        {
@@ -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));
                }
@@ -359,10 +359,10 @@ int handle_armv4_5_reg_command(struct command_context_s *cmd_ctx, char *cmd, cha
        return ERROR_OK;
 }
 
-int handle_armv4_5_core_state_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+COMMAND_HANDLER(handle_armv4_5_core_state_command)
 {
        target_t *target = get_current_target(cmd_ctx);
-       armv4_5_common_t *armv4_5 = target->arch_info;
+       struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
 
        if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
        {
@@ -387,13 +387,13 @@ 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)
+COMMAND_HANDLER(handle_armv4_5_disassemble_command)
 {
        int retval = ERROR_OK;
        target_t *target = get_current_target(cmd_ctx);
-       armv4_5_common_t *armv4_5 = target->arch_info;
+       struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
        uint32_t address;
-       int count;
+       int count = 1;
        int i;
        arm_instruction_t cur_instruction;
        uint32_t opcode;
@@ -406,19 +406,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 <address> <count> ['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 <address> [<count> ['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,18 +466,26 @@ 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 <arm|thumb>");
+       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 <arm | thumb>");
+       register_command(cmd_ctx, armv4_5_cmd, "disassemble",
+                       handle_armv4_5_disassemble_command, COMMAND_EXEC,
+                       "disassemble instructions <address> [<count> ['thumb']]");
 
-       register_command(cmd_ctx, armv4_5_cmd, "disassemble", handle_armv4_5_disassemble_command, COMMAND_EXEC, "disassemble instructions <address> <count> ['thumb']");
        return ERROR_OK;
 }
 
 int armv4_5_get_gdb_reg_list(target_t *target, reg_t **reg_list[], int *reg_list_size)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
+       struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
        int i;
 
        if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
@@ -493,7 +514,7 @@ int armv4_5_get_gdb_reg_list(target_t *target, reg_t **reg_list[], int *reg_list
 static int armv4_5_run_algorithm_completion(struct target_s *target, uint32_t exit_point, int timeout_ms, void *arch_info)
 {
        int retval;
-       armv4_5_common_t *armv4_5 = target->arch_info;
+       struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
 
        if ((retval = target_wait_state(target, TARGET_HALTED, timeout_ms)) != ERROR_OK)
        {
@@ -509,7 +530,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));
@@ -519,9 +543,9 @@ static int armv4_5_run_algorithm_completion(struct target_s *target, uint32_t ex
        return ERROR_OK;
 }
 
-int armv4_5_run_algorithm_inner(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_params, reg_param_t *reg_params, uint32_t entry_point, uint32_t exit_point, int timeout_ms, void *arch_info, int (*run_it)(struct target_s *target, uint32_t exit_point, int timeout_ms, void *arch_info))
+int armv4_5_run_algorithm_inner(struct target_s *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, reg_param_t *reg_params, uint32_t entry_point, uint32_t exit_point, int timeout_ms, void *arch_info, int (*run_it)(struct target_s *target, uint32_t exit_point, int timeout_ms, void *arch_info))
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
+       struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
        armv4_5_algorithm_t *armv4_5_algorithm_info = arch_info;
        enum armv4_5_state core_state = armv4_5->core_state;
        enum armv4_5_mode core_mode = armv4_5->core_mode;
@@ -547,6 +571,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 +634,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 +649,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;
@@ -674,7 +708,7 @@ int armv4_5_run_algorithm_inner(struct target_s *target, int num_mem_params, mem
        return retval;
 }
 
-int armv4_5_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_params, reg_param_t *reg_params, uint32_t entry_point, uint32_t exit_point, int timeout_ms, void *arch_info)
+int armv4_5_run_algorithm(struct target_s *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, reg_param_t *reg_params, uint32_t entry_point, uint32_t exit_point, int timeout_ms, void *arch_info)
 {
        return armv4_5_run_algorithm_inner(target, num_mem_params, mem_params, num_reg_params, reg_params, entry_point, exit_point, timeout_ms, arch_info, armv4_5_run_algorithm_completion);
 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)