arm11 single stepping wip - at least we know the next PC now
[openocd.git] / src / target / arm11.c
index 765846e2c3a96e6efec5be43ecc7758f1983c8b1..0af46d5c1711e60ab79577b3bd3698aba7fe9a36 100644 (file)
@@ -27,6 +27,8 @@
 #endif
 
 #include "arm11.h"
+#include "armv4_5.h"
+#include "arm_simulator.h"
 #include "target_type.h"
 
 
@@ -531,18 +533,18 @@ void arm11_dump_reg_changes(arm11_common_t * arm11)
                if (!arm11->reg_list[i].valid)
                {
                        if (arm11->reg_history[i].valid)
-                               LOG_DEBUG("%8s INVALID   (%08x)", arm11_reg_defs[i].name, arm11->reg_history[i].value);
+                               LOG_DEBUG("%8s INVALID   (%08" PRIx32 ")", arm11_reg_defs[i].name, arm11->reg_history[i].value);
                }
                else
                {
                        if (arm11->reg_history[i].valid)
                        {
                                if (arm11->reg_history[i].value != arm11->reg_values[i])
-                                       LOG_DEBUG("%8s %08x (%08x)", arm11_reg_defs[i].name, arm11->reg_values[i], arm11->reg_history[i].value);
+                                       LOG_DEBUG("%8s %08" PRIx32 " (%08" PRIx32 ")", arm11_reg_defs[i].name, arm11->reg_values[i], arm11->reg_history[i].value);
                        }
                        else
                        {
-                               LOG_DEBUG("%8s %08x (INVALID)", arm11_reg_defs[i].name, arm11->reg_values[i]);
+                               LOG_DEBUG("%8s %08" PRIx32 " (INVALID)", arm11_reg_defs[i].name, arm11->reg_values[i]);
                        }
                }
        }
@@ -585,7 +587,7 @@ int arm11_leave_debug_state(arm11_common_t * arm11)
 
                if (DSCR & (ARM11_DSCR_RDTR_FULL | ARM11_DSCR_WDTR_FULL))
                {
-                       LOG_ERROR("wDTR/rDTR inconsistent (DSCR %08x)", DSCR);
+                       LOG_ERROR("wDTR/rDTR inconsistent (DSCR %08" PRIx32 ")", DSCR);
                }
        }
 
@@ -672,7 +674,7 @@ int arm11_poll(struct target_s *target)
 
        CHECK_RETVAL(arm11_read_DSCR(arm11, &dscr));
 
-       LOG_DEBUG("DSCR %08x", dscr);
+       LOG_DEBUG("DSCR %08" PRIx32 "", dscr);
 
        CHECK_RETVAL(arm11_check_init(arm11, &dscr));
 
@@ -708,8 +710,8 @@ 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.8x pc: 0x%8.8x",
-                        Jim_Nvp_value2name_simple( nvp_target_debug_reason, target->debug_reason )->name,
+       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,
                         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)
@@ -801,7 +803,7 @@ int arm11_resume(struct target_s *target, int current, uint32_t address, int han
        if (!current)
                R(PC) = address;
 
-       LOG_DEBUG("RESUME PC %08x%s", R(PC), !current ? "!" : "");
+       LOG_DEBUG("RESUME PC %08" PRIx32 "%s", R(PC), !current ? "!" : "");
 
        /* clear breakpoints/watchpoints and VCR*/
        arm11_sc7_clear_vbw(arm11);
@@ -817,7 +819,7 @@ int arm11_resume(struct target_s *target, int current, uint32_t address, int han
                {
                        if (bp->address == R(PC))
                        {
-                               LOG_DEBUG("must step over %08x", bp->address);
+                               LOG_DEBUG("must step over %08" PRIx32 "", bp->address);
                                arm11_step(target, 1, 0, 0);
                                break;
                        }
@@ -840,7 +842,7 @@ int arm11_resume(struct target_s *target, int current, uint32_t address, int han
 
                        arm11_sc7_run(arm11, brp, asizeof(brp));
 
-                       LOG_DEBUG("Add BP " ZU " at %08x", brp_num, bp->address);
+                       LOG_DEBUG("Add BP " ZU " at %08" PRIx32 "", brp_num, bp->address);
 
                        brp_num++;
                }
@@ -860,7 +862,7 @@ int arm11_resume(struct target_s *target, int current, uint32_t address, int han
 
                CHECK_RETVAL(arm11_read_DSCR(arm11, &dscr));
 
-               LOG_DEBUG("DSCR %08x", dscr);
+               LOG_DEBUG("DSCR %08" PRIx32 "", dscr);
 
                if (dscr & ARM11_DSCR_CORE_RESTARTED)
                        break;
@@ -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)
        {
@@ -902,7 +992,17 @@ int arm11_step(struct target_s *target, int current, uint32_t address, int handl
        if (!current)
                R(PC) = address;
 
-       LOG_DEBUG("STEP PC %08x%s", R(PC), !current ? "!" : "");
+       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 */
 
@@ -979,7 +1079,7 @@ int arm11_step(struct target_s *target, int current, uint32_t address, int handl
 
                        CHECK_RETVAL(arm11_read_DSCR(arm11, &dscr));
 
-                       LOG_DEBUG("DSCR %08x", dscr);
+                       LOG_DEBUG("DSCR %08" PRIx32 "e", dscr);
 
                        if ((dscr & (ARM11_DSCR_CORE_RESTARTED | ARM11_DSCR_CORE_HALTED)) ==
                                (ARM11_DSCR_CORE_RESTARTED | ARM11_DSCR_CORE_HALTED))
@@ -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 */
@@ -1102,7 +1207,7 @@ int arm11_read_memory(struct target_s *target, uint32_t address, uint32_t size,
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       LOG_DEBUG("ADDR %08x  SIZE %08x  COUNT %08x", address, size, count);
+       LOG_DEBUG("ADDR %08" PRIx32 "  SIZE %08" PRIx32 "  COUNT %08" PRIx32 "", address, size, count);
 
        arm11_common_t * arm11 = target->arch_info;
 
@@ -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;
@@ -1183,7 +1288,7 @@ int arm11_write_memory(struct target_s *target, uint32_t address, uint32_t size,
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       LOG_DEBUG("ADDR %08x  SIZE %08x  COUNT %08x", address, size, count);
+       LOG_DEBUG("ADDR %08" PRIx32 "  SIZE %08" PRIx32 "  COUNT %08" PRIx32 "", address, size, count);
 
        arm11_common_t * arm11 = target->arch_info;
 
@@ -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);
@@ -1267,7 +1372,7 @@ int arm11_write_memory(struct target_s *target, uint32_t address, uint32_t size,
 
                if (address + size * count != r0)
                {
-                       LOG_ERROR("Data transfer failed. (%d)", (r0 - address) - size * count);
+                       LOG_ERROR("Data transfer failed. (%d)", (int)((r0 - address) - size * count));
 
                        if (arm11_config_memwrite_burst)
                                LOG_ERROR("use 'arm11 memwrite burst disable' to disable fast burst mode");
@@ -1396,11 +1501,11 @@ int arm11_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t
        for (size_t i = 0; i < 16; i++)
        {
                context[i] = buf_get_u32((uint8_t*)(&arm11->reg_values[i]),0,32);
-               LOG_DEBUG("Save %zi: 0x%x",i,context[i]);
+               LOG_DEBUG("Save %zi: 0x%" PRIx32 "",i,context[i]);
        }
 
-       cpsr = buf_get_u32((uint8_t*)(arm11->reg_values+ARM11_RC_CPSR),0,32);
-       LOG_DEBUG("Save CPSR: 0x%x", cpsr);
+       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++)
        {
@@ -1479,7 +1584,7 @@ int arm11_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t
 
        if (buf_get_u32(arm11->reg_list[15].value, 0, 32) != exit_point)
        {
-               LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4x",
+               LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4" PRIx32 "",
                        buf_get_u32(arm11->reg_list[15].value, 0, 32));
                retval = ERROR_TARGET_TIMEOUT;
                goto del_breakpoint;
@@ -1519,11 +1624,11 @@ restore:
        // Restore context
        for (size_t i = 0; i < 16; i++)
        {
-               LOG_DEBUG("restoring register %s with value 0x%8.8x",
+               LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32 "",
                         arm11->reg_list[i].name, context[i]);
                arm11_set_reg(&arm11->reg_list[i], (uint8_t*)&context[i]);
        }
-       LOG_DEBUG("restoring CPSR with value 0x%8.8x", cpsr);
+       LOG_DEBUG("restoring CPSR with value 0x%8.8" PRIx32 "", cpsr);
        arm11_set_reg(&arm11->reg_list[ARM11_RC_CPSR], (uint8_t*)&cpsr);
 
 //     arm11->core_state = core_state;
@@ -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)
@@ -1620,9 +1725,9 @@ int arm11_examine(struct target_s *target)
        arm11->free_brps = arm11->brp;
        arm11->free_wrps = arm11->wrp;
 
-       LOG_DEBUG("IDCODE %08x IMPLEMENTOR %02x DIDR %08x",
+       LOG_DEBUG("IDCODE %08" PRIx32 " IMPLEMENTOR %02x DIDR %08" PRIx32 "",
                arm11->device_id,
-               arm11->implementor,
+               (int)(arm11->implementor),
                arm11->didr);
 
        /* as a side-effect this reads DSCR and thus
@@ -1815,7 +1920,7 @@ int arm11_handle_vcr(struct command_context_s *cmd_ctx, char *cmd, char **args,
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
-       LOG_INFO("VCR 0x%08X", arm11_vcr);
+       LOG_INFO("VCR 0x%08" PRIx32 "", arm11_vcr);
        return ERROR_OK;
 }
 
@@ -1887,8 +1992,9 @@ 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 (%d max). %s",
-                               (long)(i + 2), arm11_coproc_instruction_limits[i],
+                       LOG_ERROR("Parameter %ld out of bounds (%" PRId32 " max). %s",
+                                 (long)(i + 2),
+                                 arm11_coproc_instruction_limits[i],
                                read ? arm11_mrc_syntax : arm11_mcr_syntax);
                        return -1;
                }
@@ -1911,17 +2017,21 @@ int arm11_handle_mrc_mcr(struct command_context_s *cmd_ctx, char *cmd, char **ar
                uint32_t result;
                arm11_run_instr_data_from_core_via_r0(arm11, instr, &result);
 
-               LOG_INFO("MRC p%d, %d, R0, c%d, c%d, %d = 0x%08x (%d)",
-                       values[0], values[1], values[2], values[3], values[4], result, 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[4]), result, result);
        }
        else
        {
                arm11_run_instr_data_to_core_via_r0(arm11, instr, values[5]);
 
-               LOG_INFO("MRC p%d, %d, R0 (#0x%08x), c%d, c%d, %d",
-                       values[0], values[1],
-                       values[5],
-                       values[2], values[3], values[4]);
+               LOG_INFO("MRC p%d, %d, R0 (#0x%08" PRIx32 "), c%d, c%d, %d",
+                        (int)(values[0]), (int)(values[1]),
+                        values[5],
+                        (int)(values[2]), (int)(values[3]), (int)(values[4]));
        }
 
        arm11_run_instr_data_finish(arm11);
@@ -1946,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)