target: "mcr" and "mrc" are ARM-specific
[openocd.git] / src / target / arm11.c
index d021cbd1c898bf3a22bb7ce7724128b5d7b7f6bf..30dbedb93975cbe2cc84a693617d160a5e5ad62e 100644 (file)
@@ -48,26 +48,6 @@ static bool arm11_config_hardware_step = false;
 
 enum arm11_regtype
 {
-       ARM11_REGISTER_CORE,
-       ARM11_REGISTER_CPSR,
-
-       ARM11_REGISTER_FX,
-       ARM11_REGISTER_FPS,
-
-       ARM11_REGISTER_FIQ,
-       ARM11_REGISTER_SVC,
-       ARM11_REGISTER_ABT,
-       ARM11_REGISTER_IRQ,
-       ARM11_REGISTER_UND,
-       ARM11_REGISTER_MON,
-
-       ARM11_REGISTER_SPSR_FIQ,
-       ARM11_REGISTER_SPSR_SVC,
-       ARM11_REGISTER_SPSR_ABT,
-       ARM11_REGISTER_SPSR_IRQ,
-       ARM11_REGISTER_SPSR_UND,
-       ARM11_REGISTER_SPSR_MON,
-
        /* debug regs */
        ARM11_REGISTER_DSCR,
        ARM11_REGISTER_WDTR,
@@ -86,25 +66,6 @@ struct arm11_reg_defs
 /* update arm11_regcache_ids when changing this */
 static const struct arm11_reg_defs arm11_reg_defs[] =
 {
-       {"r0",  0,      0,      ARM11_REGISTER_CORE},
-       {"r1",  1,      1,      ARM11_REGISTER_CORE},
-       {"r2",  2,      2,      ARM11_REGISTER_CORE},
-       {"r3",  3,      3,      ARM11_REGISTER_CORE},
-       {"r4",  4,      4,      ARM11_REGISTER_CORE},
-       {"r5",  5,      5,      ARM11_REGISTER_CORE},
-       {"r6",  6,      6,      ARM11_REGISTER_CORE},
-       {"r7",  7,      7,      ARM11_REGISTER_CORE},
-       {"r8",  8,      8,      ARM11_REGISTER_CORE},
-       {"r9",  9,      9,      ARM11_REGISTER_CORE},
-       {"r10", 10,     10,     ARM11_REGISTER_CORE},
-       {"r11", 11,     11,     ARM11_REGISTER_CORE},
-       {"r12", 12,     12,     ARM11_REGISTER_CORE},
-       {"sp",  13,     13,     ARM11_REGISTER_CORE},
-       {"lr",  14,     14,     ARM11_REGISTER_CORE},
-       {"pc",  15,     15,     ARM11_REGISTER_CORE},
-
-       {"cpsr",        0,      25,     ARM11_REGISTER_CPSR},
-
        /* Debug Registers */
        {"dscr",        0,      -1,     ARM11_REGISTER_DSCR},
        {"wdtr",        0,      -1,     ARM11_REGISTER_WDTR},
@@ -113,30 +74,6 @@ static const struct arm11_reg_defs arm11_reg_defs[] =
 
 enum arm11_regcache_ids
 {
-       ARM11_RC_R0,
-       ARM11_RC_RX                     = ARM11_RC_R0,
-
-       ARM11_RC_R1,
-       ARM11_RC_R2,
-       ARM11_RC_R3,
-       ARM11_RC_R4,
-       ARM11_RC_R5,
-       ARM11_RC_R6,
-       ARM11_RC_R7,
-       ARM11_RC_R8,
-       ARM11_RC_R9,
-       ARM11_RC_R10,
-       ARM11_RC_R11,
-       ARM11_RC_R12,
-       ARM11_RC_R13,
-       ARM11_RC_SP                     = ARM11_RC_R13,
-       ARM11_RC_R14,
-       ARM11_RC_LR                     = ARM11_RC_R14,
-       ARM11_RC_R15,
-       ARM11_RC_PC                     = ARM11_RC_R15,
-
-       ARM11_RC_CPSR,
-
        ARM11_RC_DSCR,
        ARM11_RC_WDTR,
        ARM11_RC_RDTR,
@@ -229,6 +166,8 @@ static int arm11_on_enter_debug_state(struct arm11_common *arm11)
                arm11->reg_list[i].dirty        = 0;
        }
 
+       /* See e.g. ARM1136 TRM, "14.8.4 Entering Debug state" */
+
        /* Save DSCR */
        CHECK_RETVAL(arm11_read_DSCR(arm11, &R(DSCR)));
 
@@ -254,10 +193,12 @@ static int arm11_on_enter_debug_state(struct arm11_common *arm11)
        }
 
 
-       /* DSCR: set ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE */
-       /* ARM1176 spec says this is needed only for wDTR/rDTR's "ITR mode", but not to issue ITRs
-          ARM1136 seems to require this to issue ITR's as well */
-
+       /* DSCR: set ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE
+        *
+        * ARM1176 spec says this is needed only for wDTR/rDTR's "ITR mode",
+        * but not to issue ITRs. ARM1136 seems to require this to issue
+        * ITR's as well...
+        */
        uint32_t new_dscr = R(DSCR) | ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE;
 
        /* this executes JTAG queue: */
@@ -297,6 +238,11 @@ static int arm11_on_enter_debug_state(struct arm11_common *arm11)
        }
 #endif
 
+       /* Save registers.
+        *
+        * NOTE:  ARM1136 TRM suggests saving just R0 here now, then
+        * CPSR and PC after the rDTR stuff.  We do it all at once.
+        */
        retval = arm_dpm_read_current_registers(&arm11->dpm);
        if (retval != ERROR_OK)
                LOG_ERROR("DPM REG READ -- fail %d", retval);
@@ -305,19 +251,7 @@ static int arm11_on_enter_debug_state(struct arm11_common *arm11)
        if (retval != ERROR_OK)
                return retval;
 
-       /* save r0 - r14 */
-
-       /** \todo TODO: handle other mode registers */
-
-       for (size_t i = 0; i < 15; i++)
-       {
-               /* MCR p14,0,R?,c0,c5,0 */
-               retval = arm11_run_instr_data_from_core(arm11, 0xEE000E15 | (i << 12), &R(RX + i), 1);
-               if (retval != ERROR_OK)
-                       return retval;
-       }
-
-       /* save rDTR */
+       /* maybe save rDTR */
 
        /* check rDTRfull in DSCR */
 
@@ -333,34 +267,9 @@ static int arm11_on_enter_debug_state(struct arm11_common *arm11)
                arm11->reg_list[ARM11_RC_RDTR].valid    = 0;
        }
 
-       /* save CPSR */
-
-       /* MRS r0,CPSR (move CPSR -> r0 (-> wDTR -> local var)) */
-       retval = arm11_run_instr_data_from_core_via_r0(arm11, 0xE10F0000, &R(CPSR));
-       if (retval != ERROR_OK)
-               return retval;
-
-       /* save PC */
-
-       /* MOV R0,PC (move PC -> r0 (-> wDTR -> local var)) */
-       retval = arm11_run_instr_data_from_core_via_r0(arm11, 0xE1A0000F, &R(PC));
-       if (retval != ERROR_OK)
-               return retval;
-
-       /* adjust PC depending on ARM state */
-
-       if (R(CPSR) & ARM11_CPSR_J)     /* Java state */
-       {
-               arm11->reg_values[ARM11_RC_PC] -= 0;
-       }
-       else if (R(CPSR) & ARM11_CPSR_T)        /* Thumb state */
-       {
-               arm11->reg_values[ARM11_RC_PC] -= 4;
-       }
-       else                                    /* ARM state */
-       {
-               arm11->reg_values[ARM11_RC_PC] -= 8;
-       }
+       /* REVISIT Now that we've saved core state, there's may also
+        * be MMU and cache state to care about ...
+        */
 
        if (arm11->simulate_reset_on_next_halt)
        {
@@ -393,29 +302,16 @@ static int arm11_leave_debug_state(struct arm11_common *arm11)
 {
        int retval;
 
-       retval = arm11_run_instr_data_prepare(arm11);
-       if (retval != ERROR_OK)
-               return retval;
-
-       /** \todo TODO: handle other mode registers */
+       /* See e.g. ARM1136 TRM, "14.8.5 Leaving Debug state" */
 
-       /* restore R1 - R14 */
-
-       for (unsigned i = 1; i < 15; i++)
-       {
-               if (!arm11->reg_list[ARM11_RC_RX + i].dirty)
-                       continue;
-
-               /* MRC p14,0,r?,c0,c5,0 */
-               arm11_run_instr_data_to_core1(arm11,
-                               0xee100e15 | (i << 12), R(RX + i));
-
-               //      LOG_DEBUG("RESTORE R%u %08x", i, R(RX + i));
-       }
+       /* NOTE:  the ARM1136 TRM suggests restoring all registers
+        * except R0/PC/CPSR right now.  Instead, we do them all
+        * at once, just a bit later on.
+        */
 
-       retval = arm11_run_instr_data_finish(arm11);
-       if (retval != ERROR_OK)
-               return retval;
+       /* REVISIT once we start caring about MMU and cache state,
+        * address it here ...
+        */
 
        /* spec says clear wDTR and rDTR; we assume they are clear as
           otherwise our programming would be sloppy */
@@ -438,50 +334,27 @@ static int arm11_leave_debug_state(struct arm11_common *arm11)
                }
        }
 
-/* DEBUG for now, trust "new" code only for shadowed registers */
-retval = arm_dpm_write_dirty_registers(&arm11->dpm);
-
-       retval = arm11_run_instr_data_prepare(arm11);
-       if (retval != ERROR_OK)
-               return retval;
-
-       /* restore original wDTR */
-
+       /* maybe restore original wDTR */
        if ((R(DSCR) & ARM11_DSCR_WDTR_FULL) || arm11->reg_list[ARM11_RC_WDTR].dirty)
        {
+               retval = arm11_run_instr_data_prepare(arm11);
+               if (retval != ERROR_OK)
+                       return retval;
+
                /* MCR p14,0,R0,c0,c5,0 */
                retval = arm11_run_instr_data_to_core_via_r0(arm11, 0xee000e15, R(WDTR));
                if (retval != ERROR_OK)
                        return retval;
-       }
-
-       /* restore CPSR */
-
-       /* MSR CPSR,R0*/
-       retval = arm11_run_instr_data_to_core_via_r0(arm11, 0xe129f000, R(CPSR));
-       if (retval != ERROR_OK)
-               return retval;
 
+               retval = arm11_run_instr_data_finish(arm11);
+               if (retval != ERROR_OK)
+                       return retval;
+       }
 
-       /* restore PC */
-
-       /* MOV PC,R0 */
-       retval = arm11_run_instr_data_to_core_via_r0(arm11, 0xe1a0f000, R(PC));
-       if (retval != ERROR_OK)
-               return retval;
-
-
-       /* restore R0 */
-
-       /* MRC p14,0,r0,c0,c5,0 */
-       arm11_run_instr_data_to_core1(arm11, 0xee100e15, R(R0));
-
-       retval = arm11_run_instr_data_finish(arm11);
-       if (retval != ERROR_OK)
-               return retval;
-
-/* DEBUG use this when "new" code is really managing core registers */
-// retval = arm_dpm_write_dirty_registers(&arm11->dpm);
+       /* restore CPSR, PC, and R0 ... after flushing any modified
+        * registers.
+        */
+       retval = arm_dpm_write_dirty_registers(&arm11->dpm);
 
        register_cache_invalidate(arm11->arm.core_cache);
 
@@ -489,7 +362,7 @@ retval = arm_dpm_write_dirty_registers(&arm11->dpm);
 
        arm11_write_DSCR(arm11, R(DSCR));
 
-       /* restore rDTR */
+       /* maybe restore rDTR */
 
        if (R(DSCR) & ARM11_DSCR_RDTR_FULL || arm11->reg_list[ARM11_RC_RDTR].dirty)
        {
@@ -509,6 +382,8 @@ retval = arm_dpm_write_dirty_registers(&arm11->dpm);
                arm11_add_dr_scan_vc(ARRAY_SIZE(chain5_fields), chain5_fields, TAP_DRPAUSE);
        }
 
+       /* now processor is ready to RESTART */
+
        return ERROR_OK;
 }
 
@@ -639,6 +514,19 @@ static int arm11_halt(struct target *target)
        return ERROR_OK;
 }
 
+static uint32_t
+arm11_nextpc(struct arm11_common *arm11, int current, uint32_t address)
+{
+       void *value = arm11->arm.core_cache->reg_list[15].value;
+
+       if (!current)
+               buf_set_u32(value, 0, 32, address);
+       else
+               address = buf_get_u32(value, 0, 32);
+
+       return address;
+}
+
 static int arm11_resume(struct target *target, int current,
                uint32_t address, int handle_breakpoints, int debug_execution)
 {
@@ -657,16 +545,18 @@ static int arm11_resume(struct target *target, int current,
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       if (!current)
-               R(PC) = address;
+       address = arm11_nextpc(arm11, current, address);
 
-       LOG_DEBUG("RESUME PC %08" PRIx32 "%s", R(PC), !current ? "!" : "");
+       LOG_DEBUG("RESUME PC %08" PRIx32 "%s", address, !current ? "!" : "");
 
        /* clear breakpoints/watchpoints and VCR*/
        arm11_sc7_clear_vbw(arm11);
 
-       /* Set up breakpoints */
        if (!debug_execution)
+               target_free_all_working_areas(target);
+
+       /* Set up breakpoints */
+       if (handle_breakpoints)
        {
                /* check if one matches PC and step over it if necessary */
 
@@ -674,7 +564,7 @@ static int arm11_resume(struct target *target, int current,
 
                for (bp = target->breakpoints; bp; bp = bp->next)
                {
-                       if (bp->address == R(PC))
+                       if (bp->address == address)
                        {
                                LOG_DEBUG("must step over %08" PRIx32 "", bp->address);
                                arm11_step(target, 1, 0, 0);
@@ -775,33 +665,28 @@ static int arm11_step(struct target *target, int current,
 
        struct arm11_common *arm11 = target_to_arm11(target);
 
-       if (!current)
-               R(PC) = address;
+       address = arm11_nextpc(arm11, current, address);
 
-       LOG_DEBUG("STEP PC %08" PRIx32 "%s", R(PC), !current ? "!" : "");
+       LOG_DEBUG("STEP PC %08" PRIx32 "%s", address, !current ? "!" : "");
 
 
        /** \todo TODO: Thumb not supported here */
 
        uint32_t        next_instruction;
 
-       CHECK_RETVAL(arm11_read_memory_word(arm11, R(PC), &next_instruction));
+       CHECK_RETVAL(arm11_read_memory_word(arm11, address, &next_instruction));
 
        /* skip over BKPT */
        if ((next_instruction & 0xFFF00070) == 0xe1200070)
        {
-               R(PC) += 4;
-               arm11->reg_list[ARM11_RC_PC].valid = 1;
-               arm11->reg_list[ARM11_RC_PC].dirty = 0;
+               address = arm11_nextpc(arm11, 0, address + 4);
                LOG_DEBUG("Skipping BKPT");
        }
        /* skip over Wait for interrupt / Standby */
        /* mcr  15, 0, r?, cr7, cr0, {4} */
        else if ((next_instruction & 0xFFFF0FFF) == 0xee070f90)
        {
-               R(PC) += 4;
-               arm11->reg_list[ARM11_RC_PC].valid = 1;
-               arm11->reg_list[ARM11_RC_PC].dirty = 0;
+               address = arm11_nextpc(arm11, 0, address + 4);
                LOG_DEBUG("Skipping WFI");
        }
        /* ignore B to self */
@@ -841,7 +726,7 @@ static int arm11_step(struct target *target, int current,
                         * FIXME Thumb stepping likely needs to use 0x03
                         * or 0xc0 byte masks, not 0x0f.
                         */
-                        brp[0].value   = R(PC);
+                        brp[0].value   = address;
                         brp[1].value   = 0x1 | (3 << 1) | (0x0F << 5)
                                        | (0 << 14) | (0 << 16) | (0 << 20)
                                        | (2 << 21);
@@ -1042,8 +927,7 @@ static int arm11_read_memory_inner(struct target *target,
        switch (size)
        {
        case 1:
-               /** \todo TODO: check if dirty is the right choice to force a rewrite on arm11_resume() */
-               arm11->reg_list[ARM11_RC_R1].dirty = 1;
+               arm11->arm.core_cache->reg_list[1].dirty = true;
 
                for (size_t i = 0; i < count; i++)
                {
@@ -1063,7 +947,7 @@ static int arm11_read_memory_inner(struct target *target,
 
        case 2:
                {
-                       arm11->reg_list[ARM11_RC_R1].dirty = 1;
+                       arm11->arm.core_cache->reg_list[1].dirty = true;
 
                        for (size_t i = 0; i < count; i++)
                        {
@@ -1105,13 +989,14 @@ static int arm11_read_memory(struct target *target, uint32_t address, uint32_t s
 }
 
 /*
-* arm11_config_memrw_no_increment - in the future we may want to be able
+* no_increment - in the future we may want to be able
 * to read/write a range of data to a "port". a "port" is an action on
 * read memory address for some peripheral.
 */
 static int arm11_write_memory_inner(struct target *target,
-               uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer,
-               bool arm11_config_memrw_no_increment)
+               uint32_t address, uint32_t size,
+               uint32_t count, uint8_t *buffer,
+               bool no_increment)
 {
        int retval;
 
@@ -1147,7 +1032,7 @@ static int arm11_write_memory_inner(struct target *target,
        {
        case 1:
                {
-                       arm11->reg_list[ARM11_RC_R1].dirty = 1;
+                       arm11->arm.core_cache->reg_list[1].dirty = true;
 
                        for (size_t i = 0; i < count; i++)
                        {
@@ -1159,7 +1044,9 @@ static int arm11_write_memory_inner(struct target *target,
                                /* strb    r1, [r0], #1 */
                                /* strb    r1, [r0] */
                                retval = arm11_run_instr_no_data1(arm11,
-                                       !arm11_config_memrw_no_increment ? 0xe4c01001 : 0xe5c01000);
+                                       !no_increment
+                                               ? 0xe4c01001
+                                               : 0xe5c01000);
                                if (retval != ERROR_OK)
                                        return retval;
                        }
@@ -1169,7 +1056,7 @@ static int arm11_write_memory_inner(struct target *target,
 
        case 2:
                {
-                       arm11->reg_list[ARM11_RC_R1].dirty = 1;
+                       arm11->arm.core_cache->reg_list[1].dirty = true;
 
                        for (size_t i = 0; i < count; i++)
                        {
@@ -1184,7 +1071,9 @@ static int arm11_write_memory_inner(struct target *target,
                                /* strh    r1, [r0], #2 */
                                /* strh    r1, [r0] */
                                retval = arm11_run_instr_no_data1(arm11,
-                                       !arm11_config_memrw_no_increment ? 0xe0c010b2 : 0xe1c010b0);
+                                       !no_increment
+                                               ? 0xe0c010b2
+                                               : 0xe1c010b0);
                                if (retval != ERROR_OK)
                                        return retval;
                        }
@@ -1193,7 +1082,7 @@ static int arm11_write_memory_inner(struct target *target,
                }
 
        case 4: {
-               uint32_t instr = !arm11_config_memrw_no_increment ? 0xeca05e01 : 0xed805e00;
+               uint32_t instr = !no_increment ? 0xeca05e01 : 0xed805e00;
 
                /** \todo TODO: buffer cast to uint32_t* causes alignment warnings */
                uint32_t *words = (uint32_t*)buffer;
@@ -1220,7 +1109,7 @@ static int arm11_write_memory_inner(struct target *target,
        }
 
        /* r0 verification */
-       if (!arm11_config_memrw_no_increment)
+       if (!no_increment)
        {
                uint32_t r0;
 
@@ -1248,9 +1137,14 @@ static int arm11_write_memory_inner(struct target *target,
 }
 
 static int arm11_write_memory(struct target *target,
-               uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+               uint32_t address, uint32_t size,
+               uint32_t count, uint8_t *buffer)
 {
-       return arm11_write_memory_inner(target, address, size, count, buffer, false);
+       /* pointer increment matters only for multi-unit writes ...
+        * not e.g. to a "reset the chip" controller.
+        */
+       return arm11_write_memory_inner(target, address, size,
+                       count, buffer, count == 1);
 }
 
 /* write target memory in multiples of 4 byte, optimized for writing large quantities of data */
@@ -1325,175 +1219,12 @@ static int arm11_remove_watchpoint(struct target *target,
        return ERROR_FAIL;
 }
 
-// HACKHACKHACK - FIXME mode/state
-/* target algorithm support */
-static int arm11_run_algorithm(struct target *target,
-               int num_mem_params, struct mem_param *mem_params,
-               int num_reg_params, struct reg_param *reg_params,
-               uint32_t entry_point, uint32_t exit_point,
-               int timeout_ms, void *arch_info)
-{
-       struct arm11_common *arm11 = target_to_arm11(target);
-//     enum armv4_5_state core_state = arm11->core_state;
-//     enum armv4_5_mode core_mode = arm11->core_mode;
-       uint32_t context[16];
-       uint32_t cpsr;
-       int exit_breakpoint_size = 0;
-       int retval = ERROR_OK;
-               LOG_DEBUG("Running algorithm");
-
-
-       if (target->state != TARGET_HALTED)
-       {
-               LOG_WARNING("target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
-       // FIXME
-//     if (!is_arm_mode(arm11->core_mode))
-//             return ERROR_FAIL;
-
-       // Save regs
-       for (unsigned i = 0; i < 16; i++)
-       {
-               context[i] = buf_get_u32((uint8_t*)(&arm11->reg_values[i]),0,32);
-               LOG_DEBUG("Save %u: 0x%" PRIx32 "", i, context[i]);
-       }
-
-       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++)
-       {
-               target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value);
-       }
-
-       // Set register parameters
-       for (int i = 0; i < num_reg_params; i++)
-       {
-               struct reg *reg = register_get_by_name(arm11->core_cache, reg_params[i].reg_name, 0);
-               if (!reg)
-               {
-                       LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
-                       return ERROR_INVALID_ARGUMENTS;
-               }
-
-               if (reg->size != reg_params[i].size)
-               {
-                       LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
-                       return ERROR_INVALID_ARGUMENTS;
-               }
-               arm11_set_reg(reg,reg_params[i].value);
-//             printf("%i: Set %s =%08x\n", i, reg_params[i].reg_name,val);
-       }
-
-       exit_breakpoint_size = 4;
-
-/*     arm11->core_state = arm11_algorithm_info->core_state;
-       if (arm11->core_state == ARMV4_5_STATE_ARM)
-                               exit_breakpoint_size = 4;
-       else if (arm11->core_state == ARMV4_5_STATE_THUMB)
-               exit_breakpoint_size = 2;
-       else
-       {
-               LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state");
-               exit(-1);
-       }
-*/
-
-
-/* arm11 at this point only supports ARM not THUMB mode
-   however if this test needs to be reactivated the current state can be read back
-   from CPSR */
-#if 0
-       if (arm11_algorithm_info->core_mode != ARMV4_5_MODE_ANY)
-       {
-               LOG_DEBUG("setting core_mode: 0x%2.2x", arm11_algorithm_info->core_mode);
-               buf_set_u32(arm11->reg_list[ARM11_RC_CPSR].value, 0, 5, arm11_algorithm_info->core_mode);
-               arm11->reg_list[ARM11_RC_CPSR].dirty = 1;
-               arm11->reg_list[ARM11_RC_CPSR].valid = 1;
-       }
-#endif
-
-       if ((retval = breakpoint_add(target, exit_point, exit_breakpoint_size, BKPT_HARD)) != ERROR_OK)
-       {
-               LOG_ERROR("can't add breakpoint to finish algorithm execution");
-               retval = ERROR_TARGET_FAILURE;
-               goto restore;
-       }
-
-       // no debug, otherwise breakpoint is not set
-       CHECK_RETVAL(target_resume(target, 0, entry_point, 1, 0));
-
-       CHECK_RETVAL(target_wait_state(target, TARGET_HALTED, timeout_ms));
-
-       if (target->state != TARGET_HALTED)
-       {
-               CHECK_RETVAL(target_halt(target));
-
-               CHECK_RETVAL(target_wait_state(target, TARGET_HALTED, 500));
-
-               retval = ERROR_TARGET_TIMEOUT;
-
-               goto del_breakpoint;
-       }
-
-       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.4" PRIx32 "",
-                       buf_get_u32(arm11->reg_list[15].value, 0, 32));
-               retval = ERROR_TARGET_TIMEOUT;
-               goto del_breakpoint;
-       }
-
-       for (int i = 0; i < num_mem_params; i++)
-       {
-               if (mem_params[i].direction != PARAM_OUT)
-                       target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value);
-       }
-
-       for (int i = 0; i < num_reg_params; i++)
-       {
-               if (reg_params[i].direction != PARAM_OUT)
-               {
-                       struct reg *reg = register_get_by_name(arm11->core_cache, reg_params[i].reg_name, 0);
-                       if (!reg)
-                       {
-                               LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
-                               retval = ERROR_INVALID_ARGUMENTS;
-                               goto del_breakpoint;
-                       }
-
-                       if (reg->size != reg_params[i].size)
-                       {
-                               LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
-                               retval = ERROR_INVALID_ARGUMENTS;
-                               goto del_breakpoint;
-                       }
-
-                       buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
-               }
-       }
-
-del_breakpoint:
-       breakpoint_remove(target, exit_point);
-
-restore:
-       // Restore context
-       for (size_t i = 0; i < 16; i++)
-       {
-               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.8" PRIx32 "", cpsr);
-       arm11_set_reg(&arm11->reg_list[ARM11_RC_CPSR], (uint8_t*)&cpsr);
-
-//     arm11->core_state = core_state;
-//     arm11->core_mode = core_mode;
-
-       return retval;
-}
+static int arm11_mrc(struct target *target, int cpnum,
+               uint32_t op1, uint32_t op2,
+               uint32_t CRn, uint32_t CRm, uint32_t *value);
+static int arm11_mcr(struct target *target, int cpnum,
+               uint32_t op1, uint32_t op2, uint32_t CRn,
+               uint32_t CRm, uint32_t value);
 
 static int arm11_target_create(struct target *target, Jim_Interp *interp)
 {
@@ -1514,6 +1245,9 @@ static int arm11_target_create(struct target *target, Jim_Interp *interp)
 
        armv4_5_init_arch_info(target, &arm11->arm);
 
+       arm11->arm.mrc = arm11_mrc;
+       arm11->arm.mcr = arm11_mcr;
+
        arm11->target = target;
 
        arm11->jtag_info.tap = target->tap;
@@ -1530,9 +1264,9 @@ static int arm11_init_target(struct command_context *cmd_ctx,
 {
        /* Initialize anything we can set up without talking to the target */
 
-       /* FIXME Switch to use the standard build_reg_cache() not custom
-        * code.  Do it from examine(), after we check whether we're
-        * an arm1176 and thus support the Secure Monitor mode.
+       /* REVISIT do we really want such a debug-registers-only cache?
+        * If we do, it should probably be handled purely by the DPM code,
+        * so it works identically on the v7a/v7r cores.
         */
        return arm11_build_reg_cache(target);
 }
@@ -1702,9 +1436,8 @@ static int arm11_build_reg_cache(struct target *target)
 
        arm11->reg_list = reg_list;
 
-       /* Build the process context cache */
-       cache->name             = "arm11 registers";
-       cache->next             = NULL;
+       /* build cache for some of the debug registers */
+       cache->name = "arm11 debug registers";
        cache->reg_list = reg_list;
        cache->num_regs = ARM11_REGCACHE_COUNT;
 
@@ -1712,7 +1445,6 @@ static int arm11_build_reg_cache(struct target *target)
        (*cache_p) = cache;
 
        arm11->core_cache = cache;
-//       armv7m->process_context = cache;
 
        size_t i;
 
@@ -1853,45 +1585,71 @@ static int arm11_mcr(struct target *target, int cpnum,
        return arm11_mrc_inner(target, cpnum, op1, op2, CRn, CRm, &value, false);
 }
 
-static int arm11_register_commands(struct command_context *cmd_ctx)
-{
-       struct command *top_cmd, *mw_cmd;
-
-       armv4_5_register_commands(cmd_ctx);
-
-       top_cmd = register_command(cmd_ctx, NULL, "arm11",
-                       NULL, COMMAND_ANY, NULL);
-
-       /* "hardware_step" is only here to check if the default
-        * simulate + breakpoint implementation is broken.
-        * TEMPORARY! NOT DOCUMENTED!
-        */
-       register_command(cmd_ctx, top_cmd, "hardware_step",
-                       arm11_handle_bool_hardware_step, COMMAND_ANY,
-                       "DEBUG ONLY - Hardware single stepping"
-                               " (default: disabled)");
-
-       mw_cmd = register_command(cmd_ctx, top_cmd, "memwrite",
-                       NULL, COMMAND_ANY, NULL);
-       register_command(cmd_ctx, mw_cmd, "burst",
-                       arm11_handle_bool_memwrite_burst, COMMAND_ANY,
-                       "Enable/Disable non-standard but fast burst mode"
-                               " (default: enabled)");
-       register_command(cmd_ctx, mw_cmd, "error_fatal",
-                       arm11_handle_bool_memwrite_error_fatal, COMMAND_ANY,
-                       "Terminate program if transfer error was found"
-                               " (default: enabled)");
-
-       register_command(cmd_ctx, top_cmd, "step_irq_enable",
-                       arm11_handle_bool_step_irq_enable, COMMAND_ANY,
-                       "Enable interrupts while stepping"
-                               " (default: disabled)");
-       register_command(cmd_ctx, top_cmd, "vcr",
-                       arm11_handle_vcr, COMMAND_ANY,
-                       "Control (Interrupt) Vector Catch Register");
-
-       return etm_register_commands(cmd_ctx);
-}
+static const struct command_registration arm11_mw_command_handlers[] = {
+       {
+               .name = "burst",
+               .handler = &arm11_handle_bool_memwrite_burst,
+               .mode = COMMAND_ANY,
+               .help = "Enable/Disable non-standard but fast burst mode"
+                       " (default: enabled)",
+       },
+       {
+               .name = "error_fatal",
+               .handler = &arm11_handle_bool_memwrite_error_fatal,
+               .mode = COMMAND_ANY,
+               .help = "Terminate program if transfer error was found"
+                       " (default: enabled)",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+static const struct command_registration arm11_any_command_handlers[] = {
+       {
+               /* "hardware_step" is only here to check if the default
+                * simulate + breakpoint implementation is broken.
+                * TEMPORARY! NOT DOCUMENTED! */
+               .name = "hardware_step",
+               .handler = &arm11_handle_bool_hardware_step,
+               .mode = COMMAND_ANY,
+               .help = "DEBUG ONLY - Hardware single stepping"
+                       " (default: disabled)",
+               .usage = "(enable|disable)",
+       },
+       {
+               .name = "memwrite",
+               .mode = COMMAND_ANY,
+               .help = "memwrite command group",
+               .chain = arm11_mw_command_handlers,
+       },
+       {
+               .name = "step_irq_enable",
+               .handler = &arm11_handle_bool_step_irq_enable,
+               .mode = COMMAND_ANY,
+               .help = "Enable interrupts while stepping"
+                       " (default: disabled)",
+       },
+       {
+               .name = "vcr",
+               .handler = &arm11_handle_vcr,
+               .mode = COMMAND_ANY,
+               .help = "Control (Interrupt) Vector Catch Register",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+static const struct command_registration arm11_command_handlers[] = {
+       {
+               .chain = arm_command_handlers,
+       },
+       {
+               .chain = etm_command_handlers,
+       },
+       {
+               .name = "arm11",
+               .mode = COMMAND_ANY,
+               .help = "ARM11 command group",
+               .chain = arm11_any_command_handlers,
+       },
+       COMMAND_REGISTRATION_DONE
+};
 
 /** Holds methods for ARM11xx targets. */
 struct target_type arm11_target = {
@@ -1925,13 +1683,10 @@ struct target_type arm11_target = {
        .add_watchpoint =       arm11_add_watchpoint,
        .remove_watchpoint =    arm11_remove_watchpoint,
 
-       .run_algorithm =        arm11_run_algorithm,
+       .run_algorithm =        armv4_5_run_algorithm,
 
-       .register_commands =    arm11_register_commands,
+       .commands =             arm11_command_handlers,
        .target_create =        arm11_target_create,
        .init_target =          arm11_init_target,
        .examine =              arm11_examine,
-
-       .mrc =                  arm11_mrc,
-       .mcr =                  arm11_mcr,
 };

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)