arm11 single stepping wip - at least we know the next PC now
[openocd.git] / src / target / arm11.c
index 7cb24dfb982573bb3ccd354c92264a5f44d1a391..0af46d5c1711e60ab79577b3bd3698aba7fe9a36 100644 (file)
@@ -27,6 +27,8 @@
 #endif
 
 #include "arm11.h"
+#include "armv4_5.h"
+#include "arm_simulator.h"
 #include "target_type.h"
 
 
@@ -709,7 +711,7 @@ int arm11_arch_state(struct target_s *target)
        arm11_common_t * arm11 = target->arch_info;
 
        LOG_USER("target halted due to %s\ncpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "",
-                        Jim_Nvp_value2name_simple( nvp_target_debug_reason, target->debug_reason )->name,
+                        Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name,
                         R(CPSR),
                         R(PC));
 
@@ -732,7 +734,7 @@ int arm11_halt(struct target_s *target)
        arm11_common_t * arm11 = target->arch_info;
 
        LOG_DEBUG("target->state: %s",
-               Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
+               target_state_name(target));
 
        if (target->state == TARGET_UNKNOWN)
        {
@@ -789,7 +791,7 @@ int arm11_resume(struct target_s *target, int current, uint32_t address, int han
        arm11_common_t * arm11 = target->arch_info;
 
        LOG_DEBUG("target->state: %s",
-               Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
+               target_state_name(target));
 
 
        if (target->state != TARGET_HALTED)
@@ -884,12 +886,100 @@ int arm11_resume(struct target_s *target, int current, uint32_t address, int han
        return ERROR_OK;
 }
 
+
+static int armv4_5_to_arm11(int reg)
+{
+       if (reg < 16)
+               return reg;
+       switch (reg)
+       {
+       case ARMV4_5_CPSR:
+               return ARM11_RC_CPSR;
+       case 16:
+               /* FIX!!! handle thumb better! */
+               return ARM11_RC_CPSR;
+       default:
+               LOG_ERROR("BUG: register translation from armv4_5 to arm11 not supported %d", reg);
+               exit(-1);
+       }
+}
+
+
+static uint32_t arm11_sim_get_reg(struct arm_sim_interface *sim, int reg)
+{
+       arm11_common_t * arm11 = (arm11_common_t *)sim->user_data;
+
+       reg=armv4_5_to_arm11(reg);
+
+       return buf_get_u32(arm11->reg_list[reg].value, 0, 32);
+}
+
+static void arm11_sim_set_reg(struct arm_sim_interface *sim, int reg, uint32_t value)
+{
+       arm11_common_t * arm11 = (arm11_common_t *)sim->user_data;
+
+       reg=armv4_5_to_arm11(reg);
+
+       buf_set_u32(arm11->reg_list[reg].value, 0, 32, value);
+}
+
+static uint32_t arm11_sim_get_cpsr(struct arm_sim_interface *sim, int pos, int bits)
+{
+       arm11_common_t * arm11 = (arm11_common_t *)sim->user_data;
+
+       return buf_get_u32(arm11->reg_list[ARM11_RC_CPSR].value, pos, bits);
+}
+
+static enum armv4_5_state arm11_sim_get_state(struct arm_sim_interface *sim)
+{
+//     arm11_common_t * arm11 = (arm11_common_t *)sim->user_data;
+
+       /* FIX!!!! we should implement thumb for arm11 */
+       return ARMV4_5_STATE_ARM;
+}
+
+static void arm11_sim_set_state(struct arm_sim_interface *sim, enum armv4_5_state mode)
+{
+//     arm11_common_t * arm11 = (arm11_common_t *)sim->user_data;
+
+       /* FIX!!!! we should implement thumb for arm11 */
+       LOG_ERROR("Not implemetned!");
+}
+
+
+static enum armv4_5_mode arm11_sim_get_mode(struct arm_sim_interface *sim)
+{
+       //arm11_common_t * arm11 = (arm11_common_t *)sim->user_data;
+
+       /* FIX!!!! we should implement something that returns the current mode here!!! */
+       return ARMV4_5_MODE_USR;
+}
+
+static int arm11_simulate_step(target_t *target, uint32_t *dry_run_pc)
+{
+       struct arm_sim_interface sim;
+
+       sim.user_data=target->arch_info;
+       sim.get_reg=&arm11_sim_get_reg;
+       sim.set_reg=&arm11_sim_set_reg;
+       sim.get_reg_mode=&arm11_sim_get_reg;
+       sim.set_reg_mode=&arm11_sim_set_reg;
+       sim.get_cpsr=&arm11_sim_get_cpsr;
+       sim.get_mode=&arm11_sim_get_mode;
+       sim.get_state=&arm11_sim_get_state;
+       sim.set_state=&arm11_sim_set_state;
+
+       return arm_simulate_step_core(target, dry_run_pc, &sim);
+
+}
+
 int arm11_step(struct target_s *target, int current, uint32_t address, int handle_breakpoints)
 {
        FNC_INFO;
+       int retval;
 
        LOG_DEBUG("target->state: %s",
-               Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
+               target_state_name(target));
 
        if (target->state != TARGET_HALTED)
        {
@@ -904,6 +994,16 @@ int arm11_step(struct target_s *target, int current, uint32_t address, int handl
 
        LOG_DEBUG("STEP PC %08" PRIx32 "%s", R(PC), !current ? "!" : "");
 
+
+       /* TODO: to implement single stepping on arm11 devices that can't
+        * do single stepping in hardware we need to calculate the next
+        * pc and set up breakpoints accordingingly. */
+       uint32_t next_pc;
+       retval = arm11_simulate_step(target, &next_pc);
+       if (retval != ERROR_OK)
+               return retval;
+
+
        /** \todo TODO: Thumb not supported here */
 
        uint32_t        next_instruction;
@@ -1002,6 +1102,11 @@ int arm11_step(struct target_s *target, int current, uint32_t address, int handl
 
        CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED));
 
+       if (R(PC) != next_pc)
+       {
+               LOG_WARNING("next pc != simulated address %08" PRIx32 "!=%08" PRIx32, R(PC), next_pc);
+       }
+
        return ERROR_OK;
 }
 
@@ -1035,7 +1140,7 @@ int arm11_deassert_reset(struct target_s *target)
 
 #if 0
        LOG_DEBUG("target->state: %s",
-               Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
+               target_state_name(target));
 
 
        /* deassert reset lines */
@@ -1149,7 +1254,7 @@ int arm11_read_memory(struct target_s *target, uint32_t address, uint32_t size,
                                arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1);
 
                                uint16_t svalue = res;
-                               memcpy(buffer + count * sizeof(uint16_t), &svalue, sizeof(uint16_t));
+                               memcpy(buffer + i * sizeof(uint16_t), &svalue, sizeof(uint16_t));
                        }
 
                        break;
@@ -1219,7 +1324,7 @@ int arm11_write_memory(struct target_s *target, uint32_t address, uint32_t size,
                        for (size_t i = 0; i < count; i++)
                        {
                                uint16_t value;
-                               memcpy(&value, buffer + count * sizeof(uint16_t), sizeof(uint16_t));
+                               memcpy(&value, buffer + i * sizeof(uint16_t), sizeof(uint16_t));
 
                                /* MRC p14,0,r1,c0,c5,0 */
                                arm11_run_instr_data_to_core1(arm11, 0xee101e15, value);
@@ -1399,7 +1504,7 @@ int arm11_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t
                LOG_DEBUG("Save %zi: 0x%" PRIx32 "",i,context[i]);
        }
 
-       cpsr = buf_get_u32((uint8_t*)(arm11->reg_values+ARM11_RC_CPSR),0,32);
+       cpsr = buf_get_u32((uint8_t*)(arm11->reg_values + ARM11_RC_CPSR),0,32);
        LOG_DEBUG("Save CPSR: 0x%" PRIx32 "", cpsr);
 
        for (int i = 0; i < num_mem_params; i++)
@@ -1540,7 +1645,7 @@ int arm11_target_create(struct target_s *target, Jim_Interp *interp)
 
        arm11->target = target;
 
-       if (target->tap==NULL)
+       if (target->tap == NULL)
                return ERROR_FAIL;
 
        if (target->tap->ir_length != 5)
@@ -1888,7 +1993,7 @@ int arm11_handle_mrc_mcr(struct command_context_s *cmd_ctx, char *cmd, char **ar
                if (values[i] > arm11_coproc_instruction_limits[i])
                {
                        LOG_ERROR("Parameter %ld out of bounds (%" PRId32 " max). %s",
-                                 (long)(i + 2), 
+                                 (long)(i + 2),
                                  arm11_coproc_instruction_limits[i],
                                read ? arm11_mrc_syntax : arm11_mcr_syntax);
                        return -1;
@@ -1913,10 +2018,10 @@ int arm11_handle_mrc_mcr(struct command_context_s *cmd_ctx, char *cmd, char **ar
                arm11_run_instr_data_from_core_via_r0(arm11, instr, &result);
 
                LOG_INFO("MRC p%d, %d, R0, c%d, c%d, %d = 0x%08" PRIx32 " (%" PRId32 ")",
-                        (int)(values[0]), 
-                        (int)(values[1]), 
-                        (int)(values[2]), 
-                        (int)(values[3]), 
+                        (int)(values[0]),
+                        (int)(values[1]),
+                        (int)(values[2]),
+                        (int)(values[3]),
                         (int)(values[4]), result, result);
        }
        else
@@ -1951,32 +2056,32 @@ int arm11_register_commands(struct command_context_s *cmd_ctx)
 
        command_t * top_cmd = NULL;
 
-       RC_TOP(                         "arm11",                                "arm11 specific commands",
+       RC_TOP("arm11",                         "arm11 specific commands",
 
-       RC_TOP(                         "memwrite",                             "Control memory write transfer mode",
+       RC_TOP("memwrite",                              "Control memory write transfer mode",
 
-               RC_FINAL_BOOL(  "burst",                                "Enable/Disable non-standard but fast burst mode (default: enabled)",
+               RC_FINAL_BOOL("burst",                          "Enable/Disable non-standard but fast burst mode (default: enabled)",
                                                memwrite_burst)
 
-               RC_FINAL_BOOL(  "error_fatal",                  "Terminate program if transfer error was found (default: enabled)",
+               RC_FINAL_BOOL("error_fatal",                    "Terminate program if transfer error was found (default: enabled)",
                                                memwrite_error_fatal)
-       ) /* memwrite */
+) /* memwrite */
 
-       RC_FINAL_BOOL(          "no_increment",                 "Don't increment address on multi-read/-write (default: disabled)",
+       RC_FINAL_BOOL("no_increment",                   "Don't increment address on multi-read/-write (default: disabled)",
                                                memrw_no_increment)
 
-       RC_FINAL_BOOL(          "step_irq_enable",              "Enable interrupts while stepping (default: disabled)",
+       RC_FINAL_BOOL("step_irq_enable",                "Enable interrupts while stepping (default: disabled)",
                                                step_irq_enable)
 
-       RC_FINAL(                       "vcr",                                  "Control (Interrupt) Vector Catch Register",
+       RC_FINAL("vcr",                                 "Control (Interrupt) Vector Catch Register",
                                                arm11_handle_vcr)
 
-       RC_FINAL(                       "mrc",                                  "Read Coprocessor register",
+       RC_FINAL("mrc",                                 "Read Coprocessor register",
                                                arm11_handle_mrc)
 
-       RC_FINAL(                       "mcr",                                  "Write Coprocessor register",
+       RC_FINAL("mcr",                                 "Write Coprocessor register",
                                                arm11_handle_mcr)
-       ) /* arm11 */
+) /* arm11 */
 
        return ERROR_OK;
 }

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)