target/arm11: Use 'bool' data type
[openocd.git] / src / target / arm11.c
index 348dd8755f61c4e2a049a5605f98638a049a68ed..159c30a8501513f52d93ceb421983e5e5a081fdd 100644 (file)
@@ -6,6 +6,8 @@
  *                                                                         *
  *   Copyright (C) 2008 Georg Acher <acher@in.tum.de>                      *
  *                                                                         *
+ *   Copyright (C) 2009 David Brownell                                     *
+ *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   GNU General Public License for more details.                          *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include "arm11.h"
+#include "etm.h"
+#include "breakpoints.h"
 #include "arm11_dbgtap.h"
-#include "armv4_5.h"
 #include "arm_simulator.h"
-#include "time_support.h"
+#include <helper/time_support.h>
 #include "target_type.h"
-
+#include "algorithm.h"
+#include "register.h"
+#include "arm_opcodes.h"
 
 #if 0
 #define _DEBUG_INSTRUCTION_EXECUTION_
 #endif
 
-#if 0
-#define FNC_INFO       LOG_DEBUG("-")
-#else
-#define FNC_INFO
-#endif
-
-#if 1
-#define FNC_INFO_NOTIMPLEMENTED do { LOG_DEBUG("NOT IMPLEMENTED"); /*exit(-1);*/ } while (0)
-#else
-#define FNC_INFO_NOTIMPLEMENTED
-#endif
-
-static bool arm11_config_memwrite_burst = true;
-static bool arm11_config_memwrite_error_fatal = true;
-static uint32_t arm11_vcr = 0;
-static bool arm11_config_step_irq_enable = false;
-static bool arm11_config_hardware_step = false;
-
-static int arm11_regs_arch_type = -1;
-
-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,
-       ARM11_REGISTER_RDTR,
-};
-
-
-struct arm11_reg_defs
-{
-       char *                                  name;
-       uint32_t                                                num;
-       int                                             gdb_num;
-       enum arm11_regtype              type;
-};
-
-/* 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},
-
-#if ARM11_REGCACHE_FREGS
-       {"f0",  0,      16,     ARM11_REGISTER_FX},
-       {"f1",  1,      17,     ARM11_REGISTER_FX},
-       {"f2",  2,      18,     ARM11_REGISTER_FX},
-       {"f3",  3,      19,     ARM11_REGISTER_FX},
-       {"f4",  4,      20,     ARM11_REGISTER_FX},
-       {"f5",  5,      21,     ARM11_REGISTER_FX},
-       {"f6",  6,      22,     ARM11_REGISTER_FX},
-       {"f7",  7,      23,     ARM11_REGISTER_FX},
-       {"fps", 0,      24,     ARM11_REGISTER_FPS},
-#endif
-
-       {"cpsr",        0,      25,     ARM11_REGISTER_CPSR},
-
-#if ARM11_REGCACHE_MODEREGS
-       {"r8_fiq",      8,      -1,     ARM11_REGISTER_FIQ},
-       {"r9_fiq",      9,      -1,     ARM11_REGISTER_FIQ},
-       {"r10_fiq",     10,     -1,     ARM11_REGISTER_FIQ},
-       {"r11_fiq",     11,     -1,     ARM11_REGISTER_FIQ},
-       {"r12_fiq",     12,     -1,     ARM11_REGISTER_FIQ},
-       {"r13_fiq",     13,     -1,     ARM11_REGISTER_FIQ},
-       {"r14_fiq",     14,     -1,     ARM11_REGISTER_FIQ},
-       {"spsr_fiq", 0, -1,     ARM11_REGISTER_SPSR_FIQ},
-
-       {"r13_svc",     13,     -1,     ARM11_REGISTER_SVC},
-       {"r14_svc",     14,     -1,     ARM11_REGISTER_SVC},
-       {"spsr_svc", 0, -1,     ARM11_REGISTER_SPSR_SVC},
-
-       {"r13_abt",     13,     -1,     ARM11_REGISTER_ABT},
-       {"r14_abt",     14,     -1,     ARM11_REGISTER_ABT},
-       {"spsr_abt", 0, -1,     ARM11_REGISTER_SPSR_ABT},
-
-       {"r13_irq",     13,     -1,     ARM11_REGISTER_IRQ},
-       {"r14_irq",     14,     -1,     ARM11_REGISTER_IRQ},
-       {"spsr_irq", 0, -1,     ARM11_REGISTER_SPSR_IRQ},
-
-       {"r13_und",     13,     -1,     ARM11_REGISTER_UND},
-       {"r14_und",     14,     -1,     ARM11_REGISTER_UND},
-       {"spsr_und", 0, -1,     ARM11_REGISTER_SPSR_UND},
-
-       /* ARM1176 only */
-       {"r13_mon",     13,     -1,     ARM11_REGISTER_MON},
-       {"r14_mon",     14,     -1,     ARM11_REGISTER_MON},
-       {"spsr_mon", 0, -1,     ARM11_REGISTER_SPSR_MON},
-#endif
-
-       /* Debug Registers */
-       {"dscr",        0,      -1,     ARM11_REGISTER_DSCR},
-       {"wdtr",        0,      -1,     ARM11_REGISTER_WDTR},
-       {"rdtr",        0,      -1,     ARM11_REGISTER_RDTR},
-};
-
-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,
-
-#if ARM11_REGCACHE_FREGS
-       ARM11_RC_F0,
-       ARM11_RC_FX                     = ARM11_RC_F0,
-       ARM11_RC_F1,
-       ARM11_RC_F2,
-       ARM11_RC_F3,
-       ARM11_RC_F4,
-       ARM11_RC_F5,
-       ARM11_RC_F6,
-       ARM11_RC_F7,
-       ARM11_RC_FPS,
-#endif
-
-       ARM11_RC_CPSR,
-
-#if ARM11_REGCACHE_MODEREGS
-       ARM11_RC_R8_FIQ,
-       ARM11_RC_R9_FIQ,
-       ARM11_RC_R10_FIQ,
-       ARM11_RC_R11_FIQ,
-       ARM11_RC_R12_FIQ,
-       ARM11_RC_R13_FIQ,
-       ARM11_RC_R14_FIQ,
-       ARM11_RC_SPSR_FIQ,
-
-       ARM11_RC_R13_SVC,
-       ARM11_RC_R14_SVC,
-       ARM11_RC_SPSR_SVC,
-
-       ARM11_RC_R13_ABT,
-       ARM11_RC_R14_ABT,
-       ARM11_RC_SPSR_ABT,
-
-       ARM11_RC_R13_IRQ,
-       ARM11_RC_R14_IRQ,
-       ARM11_RC_SPSR_IRQ,
-
-       ARM11_RC_R13_UND,
-       ARM11_RC_R14_UND,
-       ARM11_RC_SPSR_UND,
-
-       ARM11_RC_R13_MON,
-       ARM11_RC_R14_MON,
-       ARM11_RC_SPSR_MON,
-#endif
-
-       ARM11_RC_DSCR,
-       ARM11_RC_WDTR,
-       ARM11_RC_RDTR,
-
-       ARM11_RC_MAX,
-};
-
-#define ARM11_GDB_REGISTER_COUNT       26
-
-/* FIXME these are *identical* to the ARMv4_5 dummies ...  except
- * for their names, and being static vs global, and having different
- * addresses.  Ditto ARMv7a and ARMv7m dummies.
- */
-
-static uint8_t arm11_gdb_dummy_fp_value[12];
-
-static struct reg arm11_gdb_dummy_fp_reg =
-{
-       .name = "GDB dummy floating-point register",
-       .value = arm11_gdb_dummy_fp_value,
-       .dirty = 0,
-       .valid = 1,
-       .size = 96,
-       .arch_info = NULL,
-       .arch_type = 0,
-};
-
-static uint8_t arm11_gdb_dummy_fps_value[4];
-
-static struct reg arm11_gdb_dummy_fps_reg =
-{
-       .name = "GDB dummy floating-point status register",
-       .value = arm11_gdb_dummy_fps_value,
-       .dirty = 0,
-       .valid = 1,
-       .size = 32,
-       .arch_info = NULL,
-       .arch_type = 0,
-};
-
 
-static int arm11_on_enter_debug_state(struct arm11_common *arm11);
 static int arm11_step(struct target *target, int current,
-               uint32_t address, int handle_breakpoints);
-/* helpers */
-static int arm11_build_reg_cache(struct target *target);
-static int arm11_set_reg(struct reg *reg, uint8_t *buf);
-static int arm11_get_reg(struct reg *reg);
-
-static void arm11_record_register_history(struct arm11_common * arm11);
-static void arm11_dump_reg_changes(struct arm11_common * arm11);
+               target_addr_t address, int handle_breakpoints);
 
 
 /** Check and if necessary take control of the system
  *
  * \param arm11                Target state variable.
- * \param dscr         If the current DSCR content is
- *                                     available a pointer to a word holding the
- *                                     DSCR can be passed. Otherwise use NULL.
  */
-static int arm11_check_init(struct arm11_common *arm11, uint32_t *dscr)
+static int arm11_check_init(struct arm11_common *arm11)
 {
-       FNC_INFO;
-
-       uint32_t                        dscr_local_tmp_copy;
-
-       if (!dscr)
-       {
-               dscr = &dscr_local_tmp_copy;
-
-               CHECK_RETVAL(arm11_read_DSCR(arm11, dscr));
-       }
+       CHECK_RETVAL(arm11_read_DSCR(arm11));
 
-       if (!(*dscr & ARM11_DSCR_MODE_SELECT))
-       {
+       if (!(arm11->dscr & DSCR_HALT_DBG_MODE)) {
+               LOG_DEBUG("DSCR %08x", (unsigned) arm11->dscr);
                LOG_DEBUG("Bringing target into debug mode");
 
-               *dscr |= ARM11_DSCR_MODE_SELECT;                /* Halt debug-mode */
-               arm11_write_DSCR(arm11, *dscr);
+               arm11->dscr |= DSCR_HALT_DBG_MODE;
+               CHECK_RETVAL(arm11_write_DSCR(arm11, arm11->dscr));
 
                /* add further reset initialization here */
 
                arm11->simulate_reset_on_next_halt = true;
 
-               if (*dscr & ARM11_DSCR_CORE_HALTED)
-               {
+               if (arm11->dscr & DSCR_CORE_HALTED) {
                        /** \todo TODO: this needs further scrutiny because
-                         * arm11_on_enter_debug_state() never gets properly called.
+                         * arm11_debug_entry() never gets called.  (WHY NOT?)
                          * As a result we don't read the actual register states from
                          * the target.
                          */
 
-                       arm11->target->state    = TARGET_HALTED;
-                       arm11->target->debug_reason     = arm11_get_DSCR_debug_reason(*dscr);
-               }
-               else
-               {
-                       arm11->target->state    = TARGET_RUNNING;
-                       arm11->target->debug_reason     = DBG_REASON_NOTHALTED;
+                       arm11->arm.target->state = TARGET_HALTED;
+                       arm_dpm_report_dscr(arm11->arm.dpm, arm11->dscr);
+               } else {
+                       arm11->arm.target->state = TARGET_RUNNING;
+                       arm11->arm.target->debug_reason = DBG_REASON_NOTHALTED;
                }
 
-               arm11_sc7_clear_vbw(arm11);
+               CHECK_RETVAL(arm11_sc7_clear_vbw(arm11));
        }
 
        return ERROR_OK;
 }
 
-
-
-#define R(x) \
-       (arm11->reg_values[ARM11_RC_##x])
-
-/** Save processor state.
-  *
-  * This is called when the HALT instruction has succeeded
-  * or on other occasions that stop the processor.
-  *
-  */
-static int arm11_on_enter_debug_state(struct arm11_common *arm11)
+/**
+ * Save processor state.  This is called after a HALT instruction
+ * succeeds, and on other occasions the processor enters debug mode
+ * (breakpoint, watchpoint, etc).  Caller has updated arm11->dscr.
+ */
+static int arm11_debug_entry(struct arm11_common *arm11)
 {
        int retval;
-       FNC_INFO;
 
-       for (size_t i = 0; i < asizeof(arm11->reg_values); i++)
-       {
-               arm11->reg_list[i].valid        = 1;
-               arm11->reg_list[i].dirty        = 0;
-       }
+       arm11->arm.target->state = TARGET_HALTED;
+       arm_dpm_report_dscr(arm11->arm.dpm, arm11->dscr);
 
-       /* Save DSCR */
-       CHECK_RETVAL(arm11_read_DSCR(arm11, &R(DSCR)));
+       /* REVISIT entire cache should already be invalid !!! */
+       register_cache_invalidate(arm11->arm.core_cache);
 
-       /* Save wDTR */
+       /* See e.g. ARM1136 TRM, "14.8.4 Entering Debug state" */
 
-       if (R(DSCR) & ARM11_DSCR_WDTR_FULL)
-       {
+       /* maybe save wDTR (pending DCC write to debug SW, e.g. libdcc) */
+       arm11->is_wdtr_saved = !!(arm11->dscr & DSCR_DTR_TX_FULL);
+       if (arm11->is_wdtr_saved) {
                arm11_add_debug_SCAN_N(arm11, 0x05, ARM11_TAP_DEFAULT);
 
                arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);
 
-               struct scan_field       chain5_fields[3];
-
-               arm11_setup_field(arm11, 32, NULL, &R(WDTR),    chain5_fields + 0);
-               arm11_setup_field(arm11,  1, NULL, NULL,                chain5_fields + 1);
-               arm11_setup_field(arm11,  1, NULL, NULL,                chain5_fields + 2);
-
-               arm11_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_DRPAUSE);
-       }
-       else
-       {
-               arm11->reg_list[ARM11_RC_WDTR].valid    = 0;
-       }
-
+               struct scan_field chain5_fields[3];
 
-       /* 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 */
+               arm11_setup_field(arm11, 32, NULL,
+                       &arm11->saved_wdtr, chain5_fields + 0);
+               arm11_setup_field(arm11,  1, NULL, NULL, chain5_fields + 1);
+               arm11_setup_field(arm11,  1, NULL, NULL, chain5_fields + 2);
 
-       uint32_t new_dscr = R(DSCR) | ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE;
+               arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(
+                               chain5_fields), chain5_fields, TAP_DRPAUSE);
 
-       /* this executes JTAG queue: */
+       }
 
-       arm11_write_DSCR(arm11, new_dscr);
+       /* DSCR: set the Execute ARM instruction enable bit.
+        *
+        * ARM1176 spec says this is needed only for wDTR/rDTR's "ITR mode",
+        * but not to issue ITRs(?).  The ARMv7 arch spec says it's required
+        * for executing instructions via ITR.
+        */
+       CHECK_RETVAL(arm11_write_DSCR(arm11, DSCR_ITR_EN | arm11->dscr));
 
 
        /* From the spec:
@@ -409,10 +136,9 @@ static int arm11_on_enter_debug_state(struct arm11_common *arm11)
        /** \todo TODO: Test drain write buffer. */
 
 #if 0
-       while (1)
-       {
+       while (1) {
                /* MRC p14,0,R0,c5,c10,0 */
-               //      arm11_run_instr_no_data1(arm11, /*0xee150e1a*/0xe320f000);
+               /*      arm11_run_instr_no_data1(arm11, / *0xee150e1a* /0xe320f000); */
 
                /* mcr     15, 0, r0, cr7, cr10, {4} */
                arm11_run_instr_no_data1(arm11, 0xee070f9a);
@@ -421,8 +147,7 @@ static int arm11_on_enter_debug_state(struct arm11_common *arm11)
 
                LOG_DEBUG("DRAIN, DSCR %08x", dscr);
 
-               if (dscr & ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT)
-               {
+               if (dscr & ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT) {
                        arm11_run_instr_no_data1(arm11, 0xe320f000);
 
                        dscr = arm11_read_DSCR(arm11);
@@ -434,69 +159,34 @@ 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");
+
        retval = arm11_run_instr_data_prepare(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 */
-
-       /* check rDTRfull in DSCR */
-
-       if (R(DSCR) & ARM11_DSCR_RDTR_FULL)
-       {
+       /* maybe save rDTR (pending DCC read from debug SW, e.g. libdcc) */
+       arm11->is_rdtr_saved = !!(arm11->dscr & DSCR_DTR_RX_FULL);
+       if (arm11->is_rdtr_saved) {
                /* MRC p14,0,R0,c0,c5,0 (move rDTR -> r0 (-> wDTR -> local var)) */
-               retval = arm11_run_instr_data_from_core_via_r0(arm11, 0xEE100E15, &R(RDTR));
+               retval = arm11_run_instr_data_from_core_via_r0(arm11,
+                               0xEE100E15, &arm11->saved_rdtr);
                if (retval != ERROR_OK)
                        return retval;
        }
-       else
-       {
-               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)
-       {
+       if (arm11->simulate_reset_on_next_halt) {
                arm11->simulate_reset_on_next_halt = false;
 
                LOG_DEBUG("Reset c1 Control Register");
@@ -510,87 +200,51 @@ static int arm11_on_enter_debug_state(struct arm11_common *arm11)
 
        }
 
+       if (arm11->arm.target->debug_reason == DBG_REASON_WATCHPOINT) {
+               uint32_t wfar;
+
+               /* MRC p15, 0, <Rd>, c6, c0, 1 ; Read WFAR */
+               retval = arm11_run_instr_data_from_core_via_r0(arm11,
+                               ARMV4_5_MRC(15, 0, 0, 6, 0, 1),
+                               &wfar);
+               if (retval != ERROR_OK)
+                       return retval;
+               arm_dpm_report_wfar(arm11->arm.dpm, wfar);
+       }
+
+
        retval = arm11_run_instr_data_finish(arm11);
        if (retval != ERROR_OK)
                return retval;
 
-       arm11_dump_reg_changes(arm11);
-
        return ERROR_OK;
 }
 
-void arm11_dump_reg_changes(struct arm11_common * arm11)
-{
-
-       if (!(debug_level >= LOG_LVL_DEBUG))
-       {
-               return;
-       }
-
-       for (size_t i = 0; i < ARM11_REGCACHE_COUNT; i++)
-       {
-               if (!arm11->reg_list[i].valid)
-               {
-                       if (arm11->reg_history[i].valid)
-                               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 %08" PRIx32 " (%08" PRIx32 ")", arm11_reg_defs[i].name, arm11->reg_values[i], arm11->reg_history[i].value);
-                       }
-                       else
-                       {
-                               LOG_DEBUG("%8s %08" PRIx32 " (INVALID)", arm11_reg_defs[i].name, arm11->reg_values[i]);
-                       }
-               }
-       }
-}
-
-/** Restore processor state
-  *
-  * This is called in preparation for the RESTART function.
-  *
-  */
-static int arm11_leave_debug_state(struct arm11_common *arm11)
+/**
+ * Restore processor state.  This is called in preparation for
+ * the RESTART function.
+ */
+static int arm11_leave_debug_state(struct arm11_common *arm11, bool bpwp)
 {
-       FNC_INFO;
        int retval;
 
-       retval = arm11_run_instr_data_prepare(arm11);
-       if (retval != ERROR_OK)
-               return retval;
-
-       /** \todo TODO: handle other mode registers */
-
-       /* restore R1 - R14 */
+       /* See e.g. ARM1136 TRM, "14.8.5 Leaving Debug state" */
 
-       for (size_t 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" ZU " %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 */
        {
-               uint32_t DSCR;
-
-               CHECK_RETVAL(arm11_read_DSCR(arm11, &DSCR));
+               CHECK_RETVAL(arm11_read_DSCR(arm11));
 
-               if (DSCR & (ARM11_DSCR_RDTR_FULL | ARM11_DSCR_WDTR_FULL))
-               {
+               if (arm11->dscr & (DSCR_DTR_RX_FULL | DSCR_DTR_TX_FULL)) {
                        /*
                        The wDTR/rDTR two registers that are used to send/receive data to/from
                        the core in tandem with corresponding instruction codes that are
@@ -598,130 +252,93 @@ static int arm11_leave_debug_state(struct arm11_common *arm11)
                        registers hold data that was written by one side (CPU or JTAG) and not
                        read out by the other side.
                        */
-                       LOG_ERROR("wDTR/rDTR inconsistent (DSCR %08" PRIx32 ")", DSCR);
+                       LOG_ERROR("wDTR/rDTR inconsistent (DSCR %08x)",
+                               (unsigned) arm11->dscr);
                        return ERROR_FAIL;
                }
        }
 
-       retval = arm11_run_instr_data_prepare(arm11);
-       if (retval != ERROR_OK)
-               return retval;
-
-       /* restore original wDTR */
+       /* maybe restore original wDTR */
+       if (arm11->is_wdtr_saved) {
+               retval = arm11_run_instr_data_prepare(arm11);
+               if (retval != ERROR_OK)
+                       return retval;
 
-       if ((R(DSCR) & ARM11_DSCR_WDTR_FULL) || arm11->reg_list[ARM11_RC_WDTR].dirty)
-       {
                /* MCR p14,0,R0,c0,c5,0 */
-               retval = arm11_run_instr_data_to_core_via_r0(arm11, 0xee000e15, R(WDTR));
+               retval = arm11_run_instr_data_to_core_via_r0(arm11,
+                               0xee000e15, arm11->saved_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;
-
-
-       /* restore PC */
-
-       /* MOV PC,R0 */
-       retval = arm11_run_instr_data_to_core_via_r0(arm11, 0xe1a0f000, R(PC));
-       if (retval != ERROR_OK)
-               return retval;
 
+               retval = arm11_run_instr_data_finish(arm11);
+               if (retval != ERROR_OK)
+                       return retval;
+       }
 
-       /* restore R0 */
+       /* restore CPSR, PC, and R0 ... after flushing any modified
+        * registers.
+        */
+       CHECK_RETVAL(arm_dpm_write_dirty_registers(&arm11->dpm, bpwp));
 
-       /* MRC p14,0,r0,c0,c5,0 */
-       arm11_run_instr_data_to_core1(arm11, 0xee100e15, R(R0));
+       CHECK_RETVAL(arm11_bpwp_flush(arm11));
 
-       retval = arm11_run_instr_data_finish(arm11);
-       if (retval != ERROR_OK)
-               return retval;
+       register_cache_invalidate(arm11->arm.core_cache);
 
        /* restore DSCR */
+       CHECK_RETVAL(arm11_write_DSCR(arm11, arm11->dscr));
 
-       arm11_write_DSCR(arm11, R(DSCR));
-
-       /* restore rDTR */
-
-       if (R(DSCR) & ARM11_DSCR_RDTR_FULL || arm11->reg_list[ARM11_RC_RDTR].dirty)
-       {
+       /* maybe restore rDTR */
+       if (arm11->is_rdtr_saved) {
                arm11_add_debug_SCAN_N(arm11, 0x05, ARM11_TAP_DEFAULT);
 
                arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);
 
-               struct scan_field       chain5_fields[3];
+               struct scan_field chain5_fields[3];
 
-               uint8_t                 Ready           = 0;    /* ignored */
-               uint8_t                 Valid           = 0;    /* ignored */
+               uint8_t Ready           = 0;                    /* ignored */
+               uint8_t Valid           = 0;                    /* ignored */
 
-               arm11_setup_field(arm11, 32, &R(RDTR),  NULL, chain5_fields + 0);
-               arm11_setup_field(arm11,  1, &Ready,    NULL, chain5_fields + 1);
-               arm11_setup_field(arm11,  1, &Valid,    NULL, chain5_fields + 2);
+               arm11_setup_field(arm11, 32, &arm11->saved_rdtr,
+                       NULL, chain5_fields + 0);
+               arm11_setup_field(arm11,  1, &Ready,    NULL, chain5_fields + 1);
+               arm11_setup_field(arm11,  1, &Valid,    NULL, chain5_fields + 2);
 
-               arm11_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_DRPAUSE);
+               arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(
+                               chain5_fields), chain5_fields, TAP_DRPAUSE);
        }
 
-       arm11_record_register_history(arm11);
+       /* now processor is ready to RESTART */
 
        return ERROR_OK;
 }
 
-static void arm11_record_register_history(struct arm11_common *arm11)
-{
-       for (size_t i = 0; i < ARM11_REGCACHE_COUNT; i++)
-       {
-               arm11->reg_history[i].value     = arm11->reg_values[i];
-               arm11->reg_history[i].valid     = arm11->reg_list[i].valid;
-
-               arm11->reg_list[i].valid        = 0;
-               arm11->reg_list[i].dirty        = 0;
-       }
-}
-
-
 /* poll current target status */
 static int arm11_poll(struct target *target)
 {
-       FNC_INFO;
        int retval;
        struct arm11_common *arm11 = target_to_arm11(target);
-       uint32_t        dscr;
-
-       CHECK_RETVAL(arm11_read_DSCR(arm11, &dscr));
-
-       LOG_DEBUG("DSCR %08" PRIx32 "", dscr);
 
-       CHECK_RETVAL(arm11_check_init(arm11, &dscr));
+       CHECK_RETVAL(arm11_check_init(arm11));
 
-       if (dscr & ARM11_DSCR_CORE_HALTED)
-       {
-               if (target->state != TARGET_HALTED)
-               {
+       if (arm11->dscr & DSCR_CORE_HALTED) {
+               if (target->state != TARGET_HALTED) {
                        enum target_state old_state = target->state;
 
                        LOG_DEBUG("enter TARGET_HALTED");
-                       target->state                   = TARGET_HALTED;
-                       target->debug_reason    = arm11_get_DSCR_debug_reason(dscr);
-                       retval = arm11_on_enter_debug_state(arm11);
+                       retval = arm11_debug_entry(arm11);
                        if (retval != ERROR_OK)
                                return retval;
 
                        target_call_event_callbacks(target,
-                               old_state == TARGET_DEBUG_RUNNING ? TARGET_EVENT_DEBUG_HALTED : TARGET_EVENT_HALTED);
+                               (old_state == TARGET_DEBUG_RUNNING)
+                               ? TARGET_EVENT_DEBUG_HALTED
+                               : TARGET_EVENT_HALTED);
                }
-       }
-       else
-       {
-               if (target->state != TARGET_RUNNING && target->state != TARGET_DEBUG_RUNNING)
-               {
+       } else {
+               if (target->state != TARGET_RUNNING && target->state != TARGET_DEBUG_RUNNING) {
                        LOG_DEBUG("enter TARGET_RUNNING");
-                       target->state                   = TARGET_RUNNING;
-                       target->debug_reason    = DBG_REASON_NOTHALTED;
+                       target->state                   = TARGET_RUNNING;
+                       target->debug_reason    = DBG_REASON_NOTHALTED;
                }
        }
 
@@ -731,40 +348,31 @@ static int arm11_poll(struct target *target)
 static int arm11_arch_state(struct target *target)
 {
        struct arm11_common *arm11 = target_to_arm11(target);
+       int retval;
 
-       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));
+       retval = arm_arch_state(target);
 
-       return ERROR_OK;
-}
+       /* REVISIT also display ARM11-specific MMU and cache status ... */
 
-/* target request support */
-static int arm11_target_request_data(struct target *target,
-               uint32_t size, uint8_t *buffer)
-{
-       FNC_INFO_NOTIMPLEMENTED;
+       if (target->debug_reason == DBG_REASON_WATCHPOINT)
+               LOG_USER("Watchpoint triggered at PC %#08x",
+                       (unsigned) arm11->dpm.wp_pc);
 
-       return ERROR_OK;
+       return retval;
 }
 
 /* target execution control */
 static int arm11_halt(struct target *target)
 {
-       FNC_INFO;
        struct arm11_common *arm11 = target_to_arm11(target);
 
        LOG_DEBUG("target->state: %s",
                target_state_name(target));
 
        if (target->state == TARGET_UNKNOWN)
-       {
                arm11->simulate_reset_on_next_halt = true;
-       }
 
-       if (target->state == TARGET_HALTED)
-       {
+       if (target->state == TARGET_HALTED) {
                LOG_DEBUG("target was already halted");
                return ERROR_OK;
        }
@@ -773,26 +381,20 @@ static int arm11_halt(struct target *target)
 
        CHECK_RETVAL(jtag_execute_queue());
 
-       uint32_t dscr;
-
        int i = 0;
-       while (1)
-       {
-               CHECK_RETVAL(arm11_read_DSCR(arm11, &dscr));
 
-               if (dscr & ARM11_DSCR_CORE_HALTED)
+       while (1) {
+               CHECK_RETVAL(arm11_read_DSCR(arm11));
+
+               if (arm11->dscr & DSCR_CORE_HALTED)
                        break;
 
 
-               long long then = 0;
+               int64_t then = 0;
                if (i == 1000)
-               {
                        then = timeval_ms();
-               }
-               if (i >= 1000)
-               {
-                       if ((timeval_ms()-then) > 1000)
-                       {
+               if (i >= 1000) {
+                       if ((timeval_ms()-then) > 1000) {
                                LOG_WARNING("Timeout (1000ms) waiting for instructions to complete");
                                return ERROR_FAIL;
                        }
@@ -800,27 +402,57 @@ static int arm11_halt(struct target *target)
                i++;
        }
 
-       arm11_on_enter_debug_state(arm11);
-
-       enum target_state old_state     = target->state;
+       enum target_state old_state     = target->state;
 
-       target->state           = TARGET_HALTED;
-       target->debug_reason    = arm11_get_DSCR_debug_reason(dscr);
+       CHECK_RETVAL(arm11_debug_entry(arm11));
 
        CHECK_RETVAL(
                target_call_event_callbacks(target,
-                       old_state == TARGET_DEBUG_RUNNING ? TARGET_EVENT_DEBUG_HALTED : TARGET_EVENT_HALTED));
+                       old_state ==
+                       TARGET_DEBUG_RUNNING ? TARGET_EVENT_DEBUG_HALTED : TARGET_EVENT_HALTED));
 
        return ERROR_OK;
 }
 
-static int arm11_resume(struct target *target, int current,
-               uint32_t address, int handle_breakpoints, int debug_execution)
+static uint32_t arm11_nextpc(struct arm11_common *arm11, int current, uint32_t address)
 {
-       FNC_INFO;
+       void *value = arm11->arm.pc->value;
+
+       /* use the current program counter */
+       if (current)
+               address = buf_get_u32(value, 0, 32);
 
-       //        LOG_DEBUG("current %d  address %08x  handle_breakpoints %d  debug_execution %d",
-       //      current, address, handle_breakpoints, debug_execution);
+       /* Make sure that the gdb thumb fixup does not
+        * kill the return address
+        */
+       switch (arm11->arm.core_state) {
+               case ARM_STATE_ARM:
+                       address &= 0xFFFFFFFC;
+                       break;
+               case ARM_STATE_THUMB:
+                       /* When the return address is loaded into PC
+                        * bit 0 must be 1 to stay in Thumb state
+                        */
+                       address |= 0x1;
+                       break;
+
+               /* catch-all for JAZELLE and THUMB_EE */
+               default:
+                       break;
+       }
+
+       buf_set_u32(value, 0, 32, address);
+       arm11->arm.pc->dirty = true;
+       arm11->arm.pc->valid = true;
+
+       return address;
+}
+
+static int arm11_resume(struct target *target, int current,
+       target_addr_t address, int handle_breakpoints, int debug_execution)
+{
+       /*        LOG_DEBUG("current %d  address %08x  handle_breakpoints %d  debug_execution %d", */
+       /*      current, address, handle_breakpoints, debug_execution); */
 
        struct arm11_common *arm11 = target_to_arm11(target);
 
@@ -828,90 +460,85 @@ static int arm11_resume(struct target *target, int current,
                target_state_name(target));
 
 
-       if (target->state != TARGET_HALTED)
-       {
+       if (target->state != TARGET_HALTED) {
                LOG_ERROR("Target not halted");
                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" TARGET_PRIxADDR "%s", address, !current ? "!" : "");
 
        /* clear breakpoints/watchpoints and VCR*/
-       arm11_sc7_clear_vbw(arm11);
+       CHECK_RETVAL(arm11_sc7_clear_vbw(arm11));
 
-       /* Set up breakpoints */
        if (!debug_execution)
-       {
-               /* check if one matches PC and step over it if necessary */
+               target_free_all_working_areas(target);
 
-               struct breakpoint *     bp;
+       /* Should we skip over breakpoints matching the PC? */
+       if (handle_breakpoints) {
+               struct breakpoint *bp;
 
-               for (bp = target->breakpoints; bp; bp = bp->next)
-               {
-                       if (bp->address == R(PC))
-                       {
-                               LOG_DEBUG("must step over %08" PRIx32 "", bp->address);
+               for (bp = target->breakpoints; bp; bp = bp->next) {
+                       if (bp->address == address) {
+                               LOG_DEBUG("must step over %08" TARGET_PRIxADDR "", bp->address);
                                arm11_step(target, 1, 0, 0);
                                break;
                        }
                }
+       }
 
-               /* set all breakpoints */
-
-               size_t          brp_num = 0;
+       /* activate all breakpoints */
+       if (true) {
+               struct breakpoint *bp;
+               unsigned brp_num = 0;
 
-               for (bp = target->breakpoints; bp; bp = bp->next)
-               {
-                       struct arm11_sc7_action brp[2];
+               for (bp = target->breakpoints; bp; bp = bp->next) {
+                       struct arm11_sc7_action brp[2];
 
-                       brp[0].write    = 1;
-                       brp[0].address  = ARM11_SC7_BVR0 + brp_num;
-                       brp[0].value    = bp->address;
-                       brp[1].write    = 1;
-                       brp[1].address  = ARM11_SC7_BCR0 + brp_num;
-                       brp[1].value    = 0x1 | (3 << 1) | (0x0F << 5) | (0 << 14) | (0 << 16) | (0 << 20) | (0 << 21);
+                       brp[0].write    = 1;
+                       brp[0].address  = ARM11_SC7_BVR0 + brp_num;
+                       brp[0].value    = bp->address;
+                       brp[1].write    = 1;
+                       brp[1].address  = ARM11_SC7_BCR0 + brp_num;
+                       brp[1].value    = 0x1 |
+                               (3 <<
+                                1) | (0x0F << 5) | (0 << 14) | (0 << 16) | (0 << 20) | (0 << 21);
 
-                       arm11_sc7_run(arm11, brp, asizeof(brp));
+                       CHECK_RETVAL(arm11_sc7_run(arm11, brp, ARRAY_SIZE(brp)));
 
-                       LOG_DEBUG("Add BP " ZU " at %08" PRIx32 "", brp_num, bp->address);
+                       LOG_DEBUG("Add BP %d at %08" TARGET_PRIxADDR, brp_num,
+                               bp->address);
 
                        brp_num++;
                }
 
-               arm11_sc7_set_vcr(arm11, arm11_vcr);
+               if (arm11->vcr)
+                       CHECK_RETVAL(arm11_sc7_set_vcr(arm11, arm11->vcr));
        }
 
-       arm11_leave_debug_state(arm11);
+       /* activate all watchpoints and breakpoints */
+       CHECK_RETVAL(arm11_leave_debug_state(arm11, true));
 
        arm11_add_IR(arm11, ARM11_RESTART, TAP_IDLE);
 
        CHECK_RETVAL(jtag_execute_queue());
 
        int i = 0;
-       while (1)
-       {
-               uint32_t dscr;
+       while (1) {
+               CHECK_RETVAL(arm11_read_DSCR(arm11));
 
-               CHECK_RETVAL(arm11_read_DSCR(arm11, &dscr));
+               LOG_DEBUG("DSCR %08x", (unsigned) arm11->dscr);
 
-               LOG_DEBUG("DSCR %08" PRIx32 "", dscr);
-
-               if (dscr & ARM11_DSCR_CORE_RESTARTED)
+               if (arm11->dscr & DSCR_CORE_RESTARTED)
                        break;
 
 
-               long long then = 0;
+               int64_t then = 0;
                if (i == 1000)
-               {
                        then = timeval_ms();
-               }
-               if (i >= 1000)
-               {
-                       if ((timeval_ms()-then) > 1000)
-                       {
+               if (i >= 1000) {
+                       if ((timeval_ms()-then) > 1000) {
                                LOG_WARNING("Timeout (1000ms) waiting for instructions to complete");
                                return ERROR_FAIL;
                        }
@@ -919,166 +546,55 @@ static int arm11_resume(struct target *target, int current,
                i++;
        }
 
+       target->debug_reason = DBG_REASON_NOTHALTED;
        if (!debug_execution)
-       {
-               target->state                   = TARGET_RUNNING;
-               target->debug_reason    = DBG_REASON_NOTHALTED;
-
-               CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED));
-       }
+               target->state = TARGET_RUNNING;
        else
-       {
-               target->state                   = TARGET_DEBUG_RUNNING;
-               target->debug_reason    = DBG_REASON_NOTHALTED;
-
-               CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED));
-       }
+               target->state = TARGET_DEBUG_RUNNING;
+       CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED));
 
        return ERROR_OK;
 }
 
-
-static int armv4_5_to_arm11(int reg)
+static int arm11_step(struct target *target, int current,
+       target_addr_t address, int handle_breakpoints)
 {
-       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);
-       }
-}
+       LOG_DEBUG("target->state: %s",
+               target_state_name(target));
 
+       if (target->state != TARGET_HALTED) {
+               LOG_WARNING("target was not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
 
-static uint32_t arm11_sim_get_reg(struct arm_sim_interface *sim, int reg)
-{
-       struct arm11_common * arm11 = (struct arm11_common *)sim->user_data;
+       struct arm11_common *arm11 = target_to_arm11(target);
 
-       reg=armv4_5_to_arm11(reg);
+       address = arm11_nextpc(arm11, current, address);
 
-       return buf_get_u32(arm11->reg_list[reg].value, 0, 32);
-}
+       LOG_DEBUG("STEP PC %08" TARGET_PRIxADDR "%s", address, !current ? "!" : "");
 
-static void arm11_sim_set_reg(struct arm_sim_interface *sim,
-               int reg, uint32_t value)
-{
-       struct arm11_common * arm11 = (struct arm11_common *)sim->user_data;
 
-       reg=armv4_5_to_arm11(reg);
+       /** \todo TODO: Thumb not supported here */
 
-       buf_set_u32(arm11->reg_list[reg].value, 0, 32, value);
-}
+       uint32_t next_instruction;
 
-static uint32_t arm11_sim_get_cpsr(struct arm_sim_interface *sim,
-               int pos, int bits)
-{
-       struct arm11_common * arm11 = (struct arm11_common *)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)
-{
-//     struct arm11_common * arm11 = (struct arm11_common *)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)
-{
-//     struct arm11_common * arm11 = (struct arm11_common *)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)
-{
-       //struct arm11_common * arm11 = (struct arm11_common *)sim->user_data;
-
-       /* FIX!!!! we should implement something that returns the current mode here!!! */
-       return ARMV4_5_MODE_USR;
-}
-
-static int arm11_simulate_step(struct target *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);
-
-}
-
-static int arm11_step(struct target *target, int current,
-               uint32_t address, int handle_breakpoints)
-{
-       FNC_INFO;
-
-       LOG_DEBUG("target->state: %s",
-               target_state_name(target));
-
-       if (target->state != TARGET_HALTED)
-       {
-               LOG_WARNING("target was not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
-       struct arm11_common *arm11 = target_to_arm11(target);
-
-       if (!current)
-               R(PC) = address;
-
-       LOG_DEBUG("STEP PC %08" PRIx32 "%s", R(PC), !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;
-               LOG_DEBUG("Skipping BKPT");
+       if ((next_instruction & 0xFFF00070) == 0xe1200070) {
+               address = arm11_nextpc(arm11, 0, address + 4);
+               LOG_DEBUG("Skipping BKPT %08" TARGET_PRIxADDR, address);
        }
-       /* 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;
-               LOG_DEBUG("Skipping WFI");
+       /* skip over Wait for interrupt / Standby
+        * mcr  15, 0, r?, cr7, cr0, {4} */
+       else if ((next_instruction & 0xFFFF0FFF) == 0xee070f90) {
+               address = arm11_nextpc(arm11, 0, address + 4);
+               LOG_DEBUG("Skipping WFI %08" TARGET_PRIxADDR, address);
        }
        /* ignore B to self */
        else if ((next_instruction & 0xFEFFFFFF) == 0xeafffffe)
-       {
                LOG_DEBUG("Not stepping jump to self");
-       }
-       else
-       {
+       else {
                /** \todo TODO: check if break-/watchpoints make any sense at all in combination
                * with this. */
 
@@ -1088,47 +604,63 @@ static int arm11_step(struct target *target, int current,
 
                /* Set up breakpoint for stepping */
 
-               struct arm11_sc7_action brp[2];
-
-               brp[0].write    = 1;
-               brp[0].address  = ARM11_SC7_BVR0;
-               brp[1].write    = 1;
-               brp[1].address  = ARM11_SC7_BCR0;
-
-               if (arm11_config_hardware_step)
-               {
-                       /* hardware single stepping be used if possible or is it better to
-                        * always use the same code path? Hardware single stepping is not supported
-                        * on all hardware
+               struct arm11_sc7_action brp[2];
+
+               brp[0].write    = 1;
+               brp[0].address  = ARM11_SC7_BVR0;
+               brp[1].write    = 1;
+               brp[1].address  = ARM11_SC7_BCR0;
+
+               if (arm11->hardware_step) {
+                       /* Hardware single stepping ("instruction address
+                        * mismatch") is used if enabled.  It's not quite
+                        * exactly "run one instruction"; "branch to here"
+                        * loops won't break, neither will some other cases,
+                        * but it's probably the best default.
+                        *
+                        * Hardware single stepping isn't supported on v6
+                        * debug modules.  ARM1176 and v7 can support it...
+                        *
+                        * FIXME Thumb stepping likely needs to use 0x03
+                        * or 0xc0 byte masks, not 0x0f.
                         */
-                        brp[0].value   = R(PC);
-                        brp[1].value   = 0x1 | (3 << 1) | (0x0F << 5) | (0 << 14) | (0 << 16) | (0 << 20) | (2 << 21);
-               } else
-               {
-                       /* sets a breakpoint on the next PC(calculated by simulation),
+                       brp[0].value   = address;
+                       brp[1].value   = 0x1 | (3 << 1) | (0x0F << 5)
+                               | (0 << 14) | (0 << 16) | (0 << 20)
+                               | (2 << 21);
+               } else {
+                       /* Sets a breakpoint on the next PC, as calculated
+                        * by instruction set simulation.
+                        *
+                        * REVISIT stepping Thumb on ARM1156 requires Thumb2
+                        * support from the simulator.
                         */
                        uint32_t next_pc;
                        int retval;
-                       retval = arm11_simulate_step(target, &next_pc);
+
+                       retval = arm_simulate_step(target, &next_pc);
                        if (retval != ERROR_OK)
                                return retval;
 
-                       brp[0].value    = next_pc;
-                       brp[1].value    = 0x1 | (3 << 1) | (0x0F << 5) | (0 << 14) | (0 << 16) | (0 << 20) | (0 << 21);
+                       brp[0].value    = next_pc;
+                       brp[1].value    = 0x1 | (3 << 1) | (0x0F << 5)
+                               | (0 << 14) | (0 << 16) | (0 << 20)
+                               | (0 << 21);
                }
 
-               CHECK_RETVAL(arm11_sc7_run(arm11, brp, asizeof(brp)));
+               CHECK_RETVAL(arm11_sc7_run(arm11, brp, ARRAY_SIZE(brp)));
 
                /* resume */
 
 
-               if (arm11_config_step_irq_enable)
-                       R(DSCR) &= ~ARM11_DSCR_INTERRUPTS_DISABLE;              /* should be redundant */
+               if (arm11->step_irq_enable)
+                       /* this disable should be redundant ... */
+                       arm11->dscr &= ~DSCR_INT_DIS;
                else
-                       R(DSCR) |= ARM11_DSCR_INTERRUPTS_DISABLE;
+                       arm11->dscr |= DSCR_INT_DIS;
 
 
-               CHECK_RETVAL(arm11_leave_debug_state(arm11));
+               CHECK_RETVAL(arm11_leave_debug_state(arm11, handle_breakpoints));
 
                arm11_add_IR(arm11, ARM11_RESTART, TAP_IDLE);
 
@@ -1136,28 +668,24 @@ static int arm11_step(struct target *target, int current,
 
                /* wait for halt */
                int i = 0;
-               while (1)
-               {
-                       uint32_t dscr;
 
-                       CHECK_RETVAL(arm11_read_DSCR(arm11, &dscr));
+               while (1) {
+                       const uint32_t mask = DSCR_CORE_RESTARTED
+                               | DSCR_CORE_HALTED;
 
-                       LOG_DEBUG("DSCR %08" PRIx32 "e", dscr);
+                       CHECK_RETVAL(arm11_read_DSCR(arm11));
+                       LOG_DEBUG("DSCR %08x e", (unsigned) arm11->dscr);
 
-                       if ((dscr & (ARM11_DSCR_CORE_RESTARTED | ARM11_DSCR_CORE_HALTED)) ==
-                               (ARM11_DSCR_CORE_RESTARTED | ARM11_DSCR_CORE_HALTED))
+                       if ((arm11->dscr & mask) == mask)
                                break;
 
                        long long then = 0;
                        if (i == 1000)
-                       {
                                then = timeval_ms();
-                       }
-                       if (i >= 1000)
-                       {
-                               if ((timeval_ms()-then) > 1000)
-                               {
-                                       LOG_WARNING("Timeout (1000ms) waiting for instructions to complete");
+                       if (i >= 1000) {
+                               if ((timeval_ms()-then) > 1000) {
+                                       LOG_WARNING(
+                                               "Timeout (1000ms) waiting for instructions to complete");
                                        return ERROR_FAIL;
                                }
                        }
@@ -1165,18 +693,17 @@ static int arm11_step(struct target *target, int current,
                }
 
                /* clear breakpoint */
-               arm11_sc7_clear_vbw(arm11);
+               CHECK_RETVAL(arm11_sc7_clear_vbw(arm11));
 
                /* save state */
-               CHECK_RETVAL(arm11_on_enter_debug_state(arm11));
+               CHECK_RETVAL(arm11_debug_entry(arm11));
 
-           /* restore default state */
-               R(DSCR) &= ~ARM11_DSCR_INTERRUPTS_DISABLE;
+               /* restore default state */
+               arm11->dscr &= ~DSCR_INT_DIS;
 
        }
 
-       //        target->state         = TARGET_HALTED;
-       target->debug_reason    = DBG_REASON_SINGLESTEP;
+       target->debug_reason = DBG_REASON_SINGLESTEP;
 
        CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED));
 
@@ -1185,103 +712,84 @@ static int arm11_step(struct target *target, int current,
 
 static int arm11_assert_reset(struct target *target)
 {
-       FNC_INFO;
-       int retval;
        struct arm11_common *arm11 = target_to_arm11(target);
 
-       retval = arm11_check_init(arm11, NULL);
-       if (retval != ERROR_OK)
-               return retval;
-
-       target->state = TARGET_UNKNOWN;
-
-       /* we would very much like to reset into the halted, state,
-        * but resetting and halting is second best... */
-       if (target->reset_halt)
-       {
-               CHECK_RETVAL(target_halt(target));
+       if (!(target_was_examined(target))) {
+               if (jtag_get_reset_config() & RESET_HAS_SRST)
+                       jtag_add_reset(0, 1);
+               else {
+                       LOG_WARNING("Reset is not asserted because the target is not examined.");
+                       LOG_WARNING("Use a reset button or power cycle the target.");
+                       return ERROR_TARGET_NOT_EXAMINED;
+               }
+       } else {
+
+               /* optionally catch reset vector */
+               if (target->reset_halt && !(arm11->vcr & 1))
+                       CHECK_RETVAL(arm11_sc7_set_vcr(arm11, arm11->vcr | 1));
+
+               /* Issue some kind of warm reset. */
+               if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT))
+                       target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
+               else if (jtag_get_reset_config() & RESET_HAS_SRST) {
+                       /* REVISIT handle "pulls" cases, if there's
+                        * hardware that needs them to work.
+                        */
+                       jtag_add_reset(0, 1);
+               } else {
+                       LOG_ERROR("%s: how to reset?", target_name(target));
+                       return ERROR_FAIL;
+               }
        }
 
+       /* registers are now invalid */
+       register_cache_invalidate(arm11->arm.core_cache);
 
-       /* srst is funny. We can not do *anything* else while it's asserted
-        * and it has unkonwn side effects. Make sure no other code runs
-        * meanwhile.
-        *
-        * Code below assumes srst:
-        *
-        * - Causes power-on-reset (but of what parts of the system?). Bug
-        * in arm11?
-        *
-        * - Messes us TAP state without asserting trst.
-        *
-        * - There is another bug in the arm11 core. When you generate an access to
-        * external logic (for example ddr controller via AHB bus) and that block
-        * is not configured (perhaps it is still held in reset), that transaction
-        * will never complete. This will hang arm11 core but it will also hang
-        * JTAG controller. Nothing, short of srst assertion will bring it out of
-        * this.
-        *
-        * Mysteries:
-        *
-        * - What should the PC be after an srst reset when starting in the halted
-        * state?
-        */
-
-       jtag_add_reset(0, 1);
-       jtag_add_reset(0, 0);
-
-       /* How long do we have to wait? */
-       jtag_add_sleep(5000);
-
-       /* un-mess up TAP state */
-       jtag_add_tlr();
-
-       retval = jtag_execute_queue();
-       if (retval != ERROR_OK)
-       {
-               return retval;
-       }
-
-       return ERROR_OK;
-}
+       target->state = TARGET_RESET;
 
-static int arm11_deassert_reset(struct target *target)
-{
        return ERROR_OK;
 }
 
-static int arm11_soft_reset_halt(struct target *target)
-{
-       FNC_INFO_NOTIMPLEMENTED;
-
-       return ERROR_OK;
-}
+/*
+ * - There is another bug in the arm11 core.  (iMX31 specific again?)
+ *   When you generate an access to external logic (for example DDR
+ *   controller via AHB bus) and that block is not configured (perhaps
+ *   it is still held in reset), that transaction will never complete.
+ *   This will hang arm11 core but it will also hang JTAG controller.
+ *   Nothing short of srst assertion will bring it out of this.
+ */
 
-/* target register access for gdb */
-static int arm11_get_gdb_reg_list(struct target *target,
-               struct reg **reg_list[], int *reg_list_size)
+static int arm11_deassert_reset(struct target *target)
 {
-       FNC_INFO;
        struct arm11_common *arm11 = target_to_arm11(target);
+       int retval;
 
-       *reg_list_size  = ARM11_GDB_REGISTER_COUNT;
-       *reg_list               = malloc(sizeof(struct reg*) * ARM11_GDB_REGISTER_COUNT);
-
-       for (size_t i = 16; i < 24; i++)
-       {
-               (*reg_list)[i] = &arm11_gdb_dummy_fp_reg;
-       }
+       /* be certain SRST is off */
+       jtag_add_reset(0, 0);
 
-       (*reg_list)[24] = &arm11_gdb_dummy_fps_reg;
+       /* WORKAROUND i.MX31 problems:  SRST goofs the TAP, and resets
+        * at least DSCR.  OMAP24xx doesn't show that problem, though
+        * SRST-only reset seems to be problematic for other reasons.
+        * (Secure boot sequences being one likelihood!)
+        */
+       jtag_add_tlr();
 
-       for (size_t i = 0; i < ARM11_REGCACHE_COUNT; i++)
-       {
-               if (arm11_reg_defs[i].gdb_num == -1)
-                       continue;
+       CHECK_RETVAL(arm11_poll(target));
 
-               (*reg_list)[arm11_reg_defs[i].gdb_num] = arm11->reg_list + i;
+       if (target->reset_halt) {
+               if (target->state != TARGET_HALTED) {
+                       LOG_WARNING("%s: ran after reset and before halt ...",
+                               target_name(target));
+                       retval = target_halt(target);
+                       if (retval != ERROR_OK)
+                               return retval;
+               }
        }
 
+       /* maybe restore vector catch config */
+       if (target->reset_halt && !(arm11->vcr & 1))
+               CHECK_RETVAL(arm11_sc7_set_vcr(arm11, arm11->vcr));
+
        return ERROR_OK;
 }
 
@@ -1294,21 +802,22 @@ static int arm11_get_gdb_reg_list(struct target *target,
  * read memory address for some peripheral.
  */
 static int arm11_read_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 arm11_config_memrw_no_increment)
 {
-       /** \todo TODO: check if buffer cast to uint32_t* and uint16_t* might cause alignment problems */
+       /** \todo TODO: check if buffer cast to uint32_t* and uint16_t* might cause alignment
+        *problems */
        int retval;
 
-       FNC_INFO;
-
-       if (target->state != TARGET_HALTED)
-       {
+       if (target->state != TARGET_HALTED) {
                LOG_WARNING("target was not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       LOG_DEBUG("ADDR %08" PRIx32 "  SIZE %08" PRIx32 "  COUNT %08" PRIx32 "", address, size, count);
+       LOG_DEBUG("ADDR %08" PRIx32 "  SIZE %08" PRIx32 "  COUNT %08" PRIx32 "",
+               address,
+               size,
+               count);
 
        struct arm11_common *arm11 = target_to_arm11(target);
 
@@ -1321,42 +830,38 @@ static int arm11_read_memory_inner(struct target *target,
        if (retval != ERROR_OK)
                return retval;
 
-       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;
+       switch (size) {
+               case 1:
+                       arm11->arm.core_cache->reg_list[1].dirty = true;
 
-               for (size_t i = 0; i < count; i++)
-               {
-                       /* ldrb    r1, [r0], #1 */
-                       /* ldrb    r1, [r0] */
-                       arm11_run_instr_no_data1(arm11,
-                                       !arm11_config_memrw_no_increment ? 0xe4d01001 : 0xe5d01000);
+                       for (size_t i = 0; i < count; i++) {
+                               /* ldrb    r1, [r0], #1 */
+                               /* ldrb    r1, [r0] */
+                               CHECK_RETVAL(arm11_run_instr_no_data1(arm11,
+                                               !arm11_config_memrw_no_increment ? 0xe4d01001 : 0xe5d01000));
 
-                       uint32_t res;
-                       /* MCR p14,0,R1,c0,c5,0 */
-                       arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1);
+                               uint32_t res;
+                               /* MCR p14,0,R1,c0,c5,0 */
+                               CHECK_RETVAL(arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1));
 
-                       *buffer++ = res;
-               }
+                               *buffer++ = res;
+                       }
 
-               break;
+                       break;
 
-       case 2:
+               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++)
-                       {
+                       for (size_t i = 0; i < count; i++) {
                                /* ldrh    r1, [r0], #2 */
-                               arm11_run_instr_no_data1(arm11,
-                                       !arm11_config_memrw_no_increment ? 0xe0d010b2 : 0xe1d010b0);
+                               CHECK_RETVAL(arm11_run_instr_no_data1(arm11,
+                                               !arm11_config_memrw_no_increment ? 0xe0d010b2 : 0xe1d010b0));
 
                                uint32_t res;
 
                                /* MCR p14,0,R1,c0,c5,0 */
-                               arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1);
+                               CHECK_RETVAL(arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1));
 
                                uint16_t svalue = res;
                                memcpy(buffer + i * sizeof(uint16_t), &svalue, sizeof(uint16_t));
@@ -1365,46 +870,52 @@ static int arm11_read_memory_inner(struct target *target,
                        break;
                }
 
-       case 4:
+               case 4:
                {
-               uint32_t instr = !arm11_config_memrw_no_increment ? 0xecb05e01 : 0xed905e00;
-               /** \todo TODO: buffer cast to uint32_t* causes alignment warnings */
-               uint32_t *words = (uint32_t *)buffer;
-
-               /* LDC p14,c5,[R0],#4 */
-               /* LDC p14,c5,[R0] */
-               arm11_run_instr_data_from_core(arm11, instr, words, count);
-               break;
+                       uint32_t instr = !arm11_config_memrw_no_increment ? 0xecb05e01 : 0xed905e00;
+                       /** \todo TODO: buffer cast to uint32_t* causes alignment warnings */
+                       uint32_t *words = (uint32_t *)(void *)buffer;
+
+                       /* LDC p14,c5,[R0],#4 */
+                       /* LDC p14,c5,[R0] */
+                       CHECK_RETVAL(arm11_run_instr_data_from_core(arm11, instr, words, count));
+                       break;
                }
        }
 
        return arm11_run_instr_data_finish(arm11);
 }
 
-static int arm11_read_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+static int arm11_read_memory(struct target *target,
+       target_addr_t address,
+       uint32_t size,
+       uint32_t count,
+       uint8_t *buffer)
 {
        return arm11_read_memory_inner(target, address, size, count, buffer, false);
 }
 
 /*
-* 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, const uint8_t *buffer,
+       bool no_increment)
 {
        int retval;
-       FNC_INFO;
 
-       if (target->state != TARGET_HALTED)
-       {
+       if (target->state != TARGET_HALTED) {
                LOG_WARNING("target was not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       LOG_DEBUG("ADDR %08" PRIx32 "  SIZE %08" PRIx32 "  COUNT %08" PRIx32 "", address, size, count);
+       LOG_DEBUG("ADDR %08" PRIx32 "  SIZE %08" PRIx32 "  COUNT %08" PRIx32 "",
+               address,
+               size,
+               count);
 
        struct arm11_common *arm11 = target_to_arm11(target);
 
@@ -1412,7 +923,8 @@ static int arm11_write_memory_inner(struct target *target,
        if (retval != ERROR_OK)
                return retval;
 
-       /* MRC p14,0,r0,c0,c5,0 */
+       /* load r0 with buffer address
+        * MRC p14,0,r0,c0,c5,0 */
        retval = arm11_run_instr_data_to_core1(arm11, 0xee100e15, address);
        if (retval != ERROR_OK)
                return retval;
@@ -1424,25 +936,25 @@ static int arm11_write_memory_inner(struct target *target,
         * now exercise both burst and non-burst code paths with the
         * default settings, increasing code coverage.
         */
-       bool burst = arm11_config_memwrite_burst && (count > 1);
+       bool burst = arm11->memwrite_burst && (count > 1);
 
-       switch (size)
-       {
-       case 1:
+       switch (size) {
+               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++)
-                       {
+                       for (size_t i = 0; i < count; i++) {
+                               /* load r1 from DCC with byte data */
                                /* MRC p14,0,r1,c0,c5,0 */
                                retval = arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buffer++);
                                if (retval != ERROR_OK)
                                        return retval;
 
+                               /* write r1 to memory */
                                /* 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;
                        }
@@ -1450,24 +962,25 @@ static int arm11_write_memory_inner(struct target *target,
                        break;
                }
 
-       case 2:
+               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++)
-                       {
+                       for (size_t i = 0; i < count; i++) {
                                uint16_t value;
                                memcpy(&value, buffer + i * sizeof(uint16_t), sizeof(uint16_t));
 
+                               /* load r1 from DCC with halfword data */
                                /* MRC p14,0,r1,c0,c5,0 */
                                retval = arm11_run_instr_data_to_core1(arm11, 0xee101e15, value);
                                if (retval != ERROR_OK)
                                        return retval;
 
+                               /* write r1 to memory */
                                /* 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;
                        }
@@ -1475,36 +988,34 @@ static int arm11_write_memory_inner(struct target *target,
                        break;
                }
 
-       case 4: {
-               uint32_t instr = !arm11_config_memrw_no_increment ? 0xeca05e01 : 0xed805e00;
+               case 4: {
+                       /* stream word data through DCC directly to memory */
+                       /* increment:           STC p14,c5,[R0],#4 */
+                       /* no increment:        STC p14,c5,[R0]*/
+                       uint32_t instr = !no_increment ? 0xeca05e01 : 0xed805e00;
 
-               /** \todo TODO: buffer cast to uint32_t* causes alignment warnings */
-               uint32_t *words = (uint32_t*)buffer;
+                       /** \todo TODO: buffer cast to uint32_t* causes alignment warnings */
+                       uint32_t *words = (uint32_t *)(void *)buffer;
 
-               if (!burst)
-               {
-                       /* STC p14,c5,[R0],#4 */
-                       /* STC p14,c5,[R0]*/
-                       retval = arm11_run_instr_data_to_core(arm11, instr, words, count);
-                       if (retval != ERROR_OK)
-                               return retval;
-               }
-               else
-               {
-                       /* STC p14,c5,[R0],#4 */
-                       /* STC p14,c5,[R0]*/
-                       retval = arm11_run_instr_data_to_core_noack(arm11, instr, words, count);
+                       /* "burst" here just means trusting each instruction executes
+                        * fully before we run the next one:  per-word roundtrips, to
+                        * check the Ready flag, are not used.
+                        */
+                       if (!burst)
+                               retval = arm11_run_instr_data_to_core(arm11,
+                                               instr, words, count);
+                       else
+                               retval = arm11_run_instr_data_to_core_noack(arm11,
+                                               instr, words, count);
                        if (retval != ERROR_OK)
                                return retval;
-               }
 
-               break;
-       }
+                       break;
+               }
        }
 
        /* r0 verification */
-       if (!arm11_config_memrw_no_increment)
-       {
+       if (!no_increment) {
                uint32_t r0;
 
                /* MCR p14,0,R0,c0,c5,0 */
@@ -1512,17 +1023,18 @@ static int arm11_write_memory_inner(struct target *target,
                if (retval != ERROR_OK)
                        return retval;
 
-               if (address + size * count != r0)
-               {
+               if (address + size * count != r0) {
                        LOG_ERROR("Data transfer failed. Expected end "
-                                       "address 0x%08x, got 0x%08x",
-                                       (unsigned) (address + size * count),
-                                       (unsigned) r0);
+                               "address 0x%08x, got 0x%08x",
+                               (unsigned) (address + size * count),
+                               (unsigned) r0);
 
                        if (burst)
-                               LOG_ERROR("use 'arm11 memwrite burst disable' to disable fast burst mode");
+                               LOG_ERROR(
+                                       "use 'arm11 memwrite burst disable' to disable fast burst mode");
+
 
-                       if (arm11_config_memwrite_error_fatal)
+                       if (arm11->memwrite_error_fatal)
                                return ERROR_FAIL;
                }
        }
@@ -1531,51 +1043,37 @@ 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)
+       target_addr_t address, uint32_t size,
+       uint32_t count, const uint8_t *buffer)
 {
-       return arm11_write_memory_inner(target, address, size, count, buffer, false);
-}
-
-/* write target memory in multiples of 4 byte, optimized for writing large quantities of data */
-static int arm11_bulk_write_memory(struct target *target,
-               uint32_t address, uint32_t count, uint8_t *buffer)
-{
-       FNC_INFO;
-
-       if (target->state != TARGET_HALTED)
-       {
-               LOG_WARNING("target was not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
-       return arm11_write_memory(target, address, 4, count, buffer);
+       /* 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);
 }
 
 /* target break-/watchpoint control
 * rw: 0 = write, 1 = read, 2 = access
 */
 static int arm11_add_breakpoint(struct target *target,
-               struct breakpoint *breakpoint)
+       struct breakpoint *breakpoint)
 {
-       FNC_INFO;
        struct arm11_common *arm11 = target_to_arm11(target);
 
 #if 0
-       if (breakpoint->type == BKPT_SOFT)
-       {
+       if (breakpoint->type == BKPT_SOFT) {
                LOG_INFO("sw breakpoint requested, but software breakpoints not enabled");
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
 #endif
 
-       if (!arm11->free_brps)
-       {
+       if (!arm11->free_brps) {
                LOG_DEBUG("no breakpoint unit available for hardware breakpoint");
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
 
-       if (breakpoint->length != 4)
-       {
+       if (breakpoint->length != 4) {
                LOG_DEBUG("only breakpoints of four bytes length supported");
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
@@ -1586,9 +1084,8 @@ static int arm11_add_breakpoint(struct target *target,
 }
 
 static int arm11_remove_breakpoint(struct target *target,
-               struct breakpoint *breakpoint)
+       struct breakpoint *breakpoint)
 {
-       FNC_INFO;
        struct arm11_common *arm11 = target_to_arm11(target);
 
        arm11->free_brps++;
@@ -1596,242 +1093,64 @@ static int arm11_remove_breakpoint(struct target *target,
        return ERROR_OK;
 }
 
-static int arm11_add_watchpoint(struct target *target,
-               struct watchpoint *watchpoint)
-{
-       FNC_INFO_NOTIMPLEMENTED;
-
-       return ERROR_OK;
-}
-
-static int arm11_remove_watchpoint(struct target *target,
-               struct watchpoint *watchpoint)
-{
-       FNC_INFO_NOTIMPLEMENTED;
-
-       return ERROR_OK;
-}
-
-// 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 (armv4_5_mode_to_number(arm11->core_mode)==-1)
-//             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);
-                       exit(-1);
-               }
-
-               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);
-                       exit(-1);
-               }
-               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);
-                               exit(-1);
-                       }
-
-                       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);
-                               exit(-1);
-                       }
-
-                       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_target_create(struct target *target, Jim_Interp *interp)
 {
-       FNC_INFO;
-
-       NEW(struct arm11_common, arm11, 1);
-
-       arm11->target = target;
+       struct arm11_common *arm11;
 
        if (target->tap == NULL)
                return ERROR_FAIL;
 
-       if (target->tap->ir_length != 5)
-       {
+       if (target->tap->ir_length != 5) {
                LOG_ERROR("'target arm11' expects IR LENGTH = 5");
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
-       armv4_5_init_arch_info(target, &arm11->arm);
+       arm11 = calloc(1, sizeof *arm11);
+       if (!arm11)
+               return ERROR_FAIL;
+
+       arm11->arm.core_type = ARM_MODE_ANY;
+       arm_init_arch_info(target, &arm11->arm);
 
        arm11->jtag_info.tap = target->tap;
        arm11->jtag_info.scann_size = 5;
        arm11->jtag_info.scann_instr = ARM11_SCAN_N;
-       /* cur_scan_chain == 0 */
+       arm11->jtag_info.cur_scan_chain = ~0;   /* invalid/unknown */
        arm11->jtag_info.intest_instr = ARM11_INTEST;
 
+       arm11->memwrite_burst = true;
+       arm11->memwrite_error_fatal = true;
+
        return ERROR_OK;
 }
 
 static int arm11_init_target(struct command_context *cmd_ctx,
-               struct target *target)
+       struct target *target)
 {
        /* Initialize anything we can set up without talking to the target */
-       return arm11_build_reg_cache(target);
+       return ERROR_OK;
 }
 
 /* talk to the target and set things up */
 static int arm11_examine(struct target *target)
 {
        int retval;
-
-       FNC_INFO;
+       char *type;
        struct arm11_common *arm11 = target_to_arm11(target);
+       uint32_t didr, device_id;
+       uint8_t implementor;
+
+       /* FIXME split into do-first-time and do-every-time logic ... */
 
        /* check IDCODE */
 
        arm11_add_IR(arm11, ARM11_IDCODE, ARM11_TAP_DEFAULT);
 
-       struct scan_field               idcode_field;
+       struct scan_field idcode_field;
 
-       arm11_setup_field(arm11, 32, NULL, &arm11->device_id, &idcode_field);
+       arm11_setup_field(arm11, 32, NULL, &device_id, &idcode_field);
 
-       arm11_add_dr_scan_vc(1, &idcode_field, TAP_DRPAUSE);
+       arm11_add_dr_scan_vc(arm11->arm.target->tap, 1, &idcode_field, TAP_DRPAUSE);
 
        /* check DIDR */
 
@@ -1839,52 +1158,68 @@ static int arm11_examine(struct target *target)
 
        arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);
 
-       struct scan_field               chain0_fields[2];
+       struct scan_field chain0_fields[2];
 
-       arm11_setup_field(arm11, 32, NULL,      &arm11->didr,           chain0_fields + 0);
-       arm11_setup_field(arm11,  8, NULL,      &arm11->implementor,    chain0_fields + 1);
+       arm11_setup_field(arm11, 32, NULL, &didr, chain0_fields + 0);
+       arm11_setup_field(arm11,  8, NULL, &implementor, chain0_fields + 1);
 
-       arm11_add_dr_scan_vc(asizeof(chain0_fields), chain0_fields, TAP_IDLE);
+       arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(
+                       chain0_fields), chain0_fields, TAP_IDLE);
 
        CHECK_RETVAL(jtag_execute_queue());
 
-       switch (arm11->device_id & 0x0FFFF000)
-       {
-       case 0x07B36000:        LOG_INFO("found ARM1136"); break;
-       case 0x07B56000:        LOG_INFO("found ARM1156"); break;
-       case 0x07B76000:        LOG_INFO("found ARM1176"); break;
-       default:
-               LOG_ERROR("'target arm11' expects IDCODE 0x*7B*7****");
-               return ERROR_FAIL;
+       /* assume the manufacturer id is ok; check the part # */
+       switch ((device_id >> 12) & 0xFFFF) {
+               case 0x7B36:
+                       type = "ARM1136";
+                       break;
+               case 0x7B37:
+                       type = "ARM11 MPCore";
+                       break;
+               case 0x7B56:
+                       type = "ARM1156";
+                       break;
+               case 0x7B76:
+                       arm11->arm.core_type = ARM_MODE_MON;
+                       /* NOTE: could default arm11->hardware_step to true */
+                       type = "ARM1176";
+                       break;
+               default:
+                       LOG_ERROR("unexpected ARM11 ID code");
+                       return ERROR_FAIL;
        }
+       LOG_INFO("found %s", type);
 
-       arm11->debug_version = (arm11->didr >> 16) & 0x0F;
-
-       if (arm11->debug_version != ARM11_DEBUG_V6 &&
-               arm11->debug_version != ARM11_DEBUG_V61)
-       {
-               LOG_ERROR("Only ARMv6 v6 and v6.1 architectures supported.");
-               return ERROR_FAIL;
+       /* unlikely this could ever fail, but ... */
+       switch ((didr >> 16) & 0x0F) {
+               case ARM11_DEBUG_V6:
+               case ARM11_DEBUG_V61:   /* supports security extensions */
+                       break;
+               default:
+                       LOG_ERROR("Only ARM v6 and v6.1 debug supported.");
+                       return ERROR_FAIL;
        }
 
-       arm11->brp      = ((arm11->didr >> 24) & 0x0F) + 1;
-       arm11->wrp      = ((arm11->didr >> 28) & 0x0F) + 1;
+       arm11->brp = ((didr >> 24) & 0x0F) + 1;
 
        /** \todo TODO: reserve one brp slot if we allow breakpoints during step */
        arm11->free_brps = arm11->brp;
-       arm11->free_wrps = arm11->wrp;
 
-       LOG_DEBUG("IDCODE %08" PRIx32 " IMPLEMENTOR %02x DIDR %08" PRIx32 "",
-               arm11->device_id,
-               (int)(arm11->implementor),
-               arm11->didr);
+       LOG_DEBUG("IDCODE %08" PRIx32 " IMPLEMENTOR %02x DIDR %08" PRIx32,
+               device_id, implementor, didr);
+
+       /* Build register cache "late", after target_init(), since we
+        * want to know if this core supports Secure Monitor mode.
+        */
+       if (!target_was_examined(target))
+               CHECK_RETVAL(arm11_dpm_init(arm11, didr));
 
        /* as a side-effect this reads DSCR and thus
         * clears the ARM11_DSCR_STICKY_PRECISE_DATA_ABORT / Sticky Precise Data Abort Flag
         * as suggested by the spec.
         */
 
-       retval = arm11_check_init(arm11, NULL);
+       retval = arm11_check_init(arm11);
        if (retval != ERROR_OK)
                return retval;
 
@@ -1892,8 +1227,8 @@ static int arm11_examine(struct target *target)
        if (arm11->arm.etm && !target_was_examined(target)) {
                *register_get_last_cache_p(&target->reg_cache) =
                        etm_build_reg_cache(target, &arm11->jtag_info,
-                                       arm11->arm.etm);
-               retval = etm_setup(target);
+                               arm11->arm.etm);
+               CHECK_RETVAL(etm_setup(target));
        }
 
        target_set_examined(target);
@@ -1901,313 +1236,148 @@ static int arm11_examine(struct target *target)
        return ERROR_OK;
 }
 
-
-/** Load a register that is marked !valid in the register cache */
-static int arm11_get_reg(struct reg *reg)
-{
-       FNC_INFO;
-
-       struct target * target = ((struct arm11_reg_state *)reg->arch_info)->target;
-
-       if (target->state != TARGET_HALTED)
-       {
-               LOG_WARNING("target was not halted");
-               return ERROR_TARGET_NOT_HALTED;
+#define ARM11_BOOL_WRAPPER(name, print_name)   \
+       COMMAND_HANDLER(arm11_handle_bool_ ## name) \
+       { \
+               struct target *target = get_current_target(CMD_CTX); \
+               struct arm11_common *arm11 = target_to_arm11(target); \
+               \
+               return CALL_COMMAND_HANDLER(handle_command_parse_bool, \
+                       &arm11->name, print_name); \
        }
 
-       /** \todo TODO: Check this. We assume that all registers are fetched at debug entry. */
-
-#if 0
-       struct arm11_common *arm11 = target_to_arm11(target);
-       const struct arm11_reg_defs *arm11_reg_info = arm11_reg_defs + ((struct arm11_reg_state *)reg->arch_info)->def_index;
-#endif
+ARM11_BOOL_WRAPPER(memwrite_burst, "memory write burst mode")
+ARM11_BOOL_WRAPPER(memwrite_error_fatal, "fatal error mode for memory writes")
+ARM11_BOOL_WRAPPER(step_irq_enable, "IRQs while stepping")
+ARM11_BOOL_WRAPPER(hardware_step, "hardware single step")
 
-       return ERROR_OK;
-}
-
-/** Change a value in the register cache */
-static int arm11_set_reg(struct reg *reg, uint8_t *buf)
-{
-       FNC_INFO;
-
-       struct target *target = ((struct arm11_reg_state *)reg->arch_info)->target;
-       struct arm11_common *arm11 = target_to_arm11(target);
-//     const struct arm11_reg_defs *arm11_reg_info = arm11_reg_defs + ((struct arm11_reg_state *)reg->arch_info)->def_index;
-
-       arm11->reg_values[((struct arm11_reg_state *)reg->arch_info)->def_index] = buf_get_u32(buf, 0, 32);
-       reg->valid      = 1;
-       reg->dirty      = 1;
-
-       return ERROR_OK;
-}
+/* REVISIT handle the VCR bits like other ARMs:  use symbols for
+ * input and output values.
+ */
 
-static int arm11_build_reg_cache(struct target *target)
+COMMAND_HANDLER(arm11_handle_vcr)
 {
+       struct target *target = get_current_target(CMD_CTX);
        struct arm11_common *arm11 = target_to_arm11(target);
 
-       NEW(struct reg_cache,           cache,                          1);
-       NEW(struct reg,                         reg_list,                       ARM11_REGCACHE_COUNT);
-       NEW(struct arm11_reg_state,     arm11_reg_states,       ARM11_REGCACHE_COUNT);
-
-       if (arm11_regs_arch_type == -1)
-               arm11_regs_arch_type = register_reg_arch_type(arm11_get_reg, arm11_set_reg);
-
-       register_init_dummy(&arm11_gdb_dummy_fp_reg);
-       register_init_dummy(&arm11_gdb_dummy_fps_reg);
-
-       arm11->reg_list = reg_list;
-
-       /* Build the process context cache */
-       cache->name             = "arm11 registers";
-       cache->next             = NULL;
-       cache->reg_list = reg_list;
-       cache->num_regs = ARM11_REGCACHE_COUNT;
-
-       struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
-       (*cache_p) = cache;
-
-       arm11->core_cache = cache;
-//       armv7m->process_context = cache;
-
-       size_t i;
-
-       /* Not very elegant assertion */
-       if (ARM11_REGCACHE_COUNT != asizeof(arm11->reg_values) ||
-               ARM11_REGCACHE_COUNT != asizeof(arm11_reg_defs) ||
-               ARM11_REGCACHE_COUNT != ARM11_RC_MAX)
-       {
-               LOG_ERROR("BUG: arm11->reg_values inconsistent (%d " ZU " " ZU " %d)", ARM11_REGCACHE_COUNT, asizeof(arm11->reg_values), asizeof(arm11_reg_defs), ARM11_RC_MAX);
-               exit(-1);
-       }
-
-       for (i = 0; i < ARM11_REGCACHE_COUNT; i++)
-       {
-               struct reg *                                            r       = reg_list                      + i;
-               const struct arm11_reg_defs *   rd      = arm11_reg_defs        + i;
-               struct arm11_reg_state *                        rs      = arm11_reg_states      + i;
-
-               r->name                         = rd->name;
-               r->size                         = 32;
-               r->value                        = (uint8_t *)(arm11->reg_values + i);
-               r->dirty                        = 0;
-               r->valid                        = 0;
-               r->arch_type            = arm11_regs_arch_type;
-               r->arch_info            = rs;
-
-               rs->def_index           = i;
-               rs->target                      = target;
-       }
-
-       return ERROR_OK;
-}
-
-static COMMAND_HELPER(arm11_handle_bool, bool *var, char *name)
-{
-       if (argc == 0)
-       {
-               LOG_INFO("%s is %s.", name, *var ? "enabled" : "disabled");
-               return ERROR_OK;
-       }
-
-       if (argc != 1)
-               return ERROR_COMMAND_SYNTAX_ERROR;
-
-       switch (args[0][0])
-       {
-       case '0':       /* 0 */
-       case 'f':       /* false */
-       case 'F':
-       case 'd':       /* disable */
-       case 'D':
-               *var = false;
-               break;
-
-       case '1':       /* 1 */
-       case 't':       /* true */
-       case 'T':
-       case 'e':       /* enable */
-       case 'E':
-               *var = true;
-               break;
-       }
-
-       LOG_INFO("%s %s.", *var ? "Enabled" : "Disabled", name);
-
-       return ERROR_OK;
-}
-
-#define BOOL_WRAPPER(name, print_name) \
-COMMAND_HANDLER(arm11_handle_bool_##name) \
-{ \
-       return CALL_COMMAND_HANDLER(arm11_handle_bool, \
-                       &arm11_config_##name, print_name); \
-}
-
-BOOL_WRAPPER(memwrite_burst,                   "memory write burst mode")
-BOOL_WRAPPER(memwrite_error_fatal,             "fatal error mode for memory writes")
-BOOL_WRAPPER(step_irq_enable,                  "IRQs while stepping")
-BOOL_WRAPPER(hardware_step,                    "hardware single step")
-
-COMMAND_HANDLER(arm11_handle_vcr)
-{
-       switch (argc) {
-       case 0:
-               break;
-       case 1:
-               COMMAND_PARSE_NUMBER(u32, args[0], arm11_vcr);
-               break;
-       default:
-               return ERROR_COMMAND_SYNTAX_ERROR;
+       switch (CMD_ARGC) {
+               case 0:
+                       break;
+               case 1:
+                       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], arm11->vcr);
+                       break;
+               default:
+                       return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
-       LOG_INFO("VCR 0x%08" PRIx32 "", arm11_vcr);
+       LOG_INFO("VCR 0x%08" PRIx32 "", arm11->vcr);
        return ERROR_OK;
 }
 
-static const uint32_t arm11_coproc_instruction_limits[] =
-{
-       15,                             /* coprocessor */
-       7,                              /* opcode 1 */
-       15,                             /* CRn */
-       15,                             /* CRm */
-       7,                              /* opcode 2 */
-       0xFFFFFFFF,             /* value */
+static const struct command_registration arm11_mw_command_handlers[] = {
+       {
+               .name = "burst",
+               .handler = arm11_handle_bool_memwrite_burst,
+               .mode = COMMAND_ANY,
+               .help = "Display or modify flag controlling potentially "
+                       "risky fast burst mode (default: enabled)",
+               .usage = "['enable'|'disable']",
+       },
+       {
+               .name = "error_fatal",
+               .handler = arm11_handle_bool_memwrite_error_fatal,
+               .mode = COMMAND_ANY,
+               .help = "Display or modify flag controlling transfer "
+                       "termination on transfer errors"
+                       " (default: enabled)",
+               .usage = "['enable'|'disable']",
+       },
+       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",
+               .usage = "",
+               .chain = arm11_mw_command_handlers,
+       },
+       {
+               .name = "step_irq_enable",
+               .handler = arm11_handle_bool_step_irq_enable,
+               .mode = COMMAND_ANY,
+               .help = "Display or modify flag controlling interrupt "
+                       "enable while stepping (default: disabled)",
+               .usage = "['enable'|'disable']",
+       },
+       {
+               .name = "vcr",
+               .handler = arm11_handle_vcr,
+               .mode = COMMAND_ANY,
+               .help = "Display or modify Vector Catch Register",
+               .usage = "[value]",
+       },
+       COMMAND_REGISTRATION_DONE
 };
 
-static int arm11_mrc_inner(struct target *target, int cpnum,
-               uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm,
-               uint32_t *value, bool read)
-{
-       int retval;
-       struct arm11_common *arm11 = target_to_arm11(target);
-
-       if (target->state != TARGET_HALTED)
+static const struct command_registration arm11_command_handlers[] = {
        {
-               LOG_ERROR("Target not halted");
-               return ERROR_FAIL;
-       }
-
-       uint32_t instr = 0xEE000010     |
-               (cpnum <<  8) |
-               (op1 << 21) |
-               (CRn << 16) |
-               (CRm <<  0) |
-               (op2 <<  5);
-
-       if (read)
-               instr |= 0x00100000;
-
-       retval = arm11_run_instr_data_prepare(arm11);
-       if (retval != ERROR_OK)
-               return retval;
-
-       if (read)
+               .chain = arm_command_handlers,
+       },
        {
-               retval = arm11_run_instr_data_from_core_via_r0(arm11, instr, value);
-               if (retval != ERROR_OK)
-                       return retval;
-       }
-       else
+               .chain = etm_command_handlers,
+       },
        {
-               retval = arm11_run_instr_data_to_core_via_r0(arm11, instr, *value);
-               if (retval != ERROR_OK)
-                       return retval;
-       }
-
-       return arm11_run_instr_data_finish(arm11);
-}
-
-static int arm11_mrc(struct target *target, int cpnum,
-               uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value)
-{
-       return arm11_mrc_inner(target, cpnum, op1, op2, CRn, CRm, value, true);
-}
-
-static int arm11_mcr(struct target *target, int cpnum,
-               uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value)
-{
-       return arm11_mrc_inner(target, cpnum, op1, op2, CRn, CRm, &value, false);
-}
-
-static int arm11_register_commands(struct command_context *cmd_ctx)
-{
-       FNC_INFO;
-
-       struct command *top_cmd, *mw_cmd;
-
-       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);
-}
+               .name = "arm11",
+               .mode = COMMAND_ANY,
+               .help = "ARM11 command group",
+               .usage = "",
+               .chain = arm11_any_command_handlers,
+       },
+       COMMAND_REGISTRATION_DONE
+};
 
 /** Holds methods for ARM11xx targets. */
 struct target_type arm11_target = {
-       .name =                 "arm11",
-
-       .poll =                 arm11_poll,
-       .arch_state =           arm11_arch_state,
-
-       .target_request_data =  arm11_target_request_data,
-
-       .halt =                 arm11_halt,
-       .resume =               arm11_resume,
-       .step =                 arm11_step,
+       .name = "arm11",
 
-       .assert_reset =         arm11_assert_reset,
-       .deassert_reset =       arm11_deassert_reset,
-       .soft_reset_halt =      arm11_soft_reset_halt,
+       .poll = arm11_poll,
+       .arch_state = arm11_arch_state,
 
-       .get_gdb_reg_list =     arm11_get_gdb_reg_list,
+       .halt = arm11_halt,
+       .resume = arm11_resume,
+       .step = arm11_step,
 
-       .read_memory =          arm11_read_memory,
-       .write_memory =         arm11_write_memory,
+       .assert_reset = arm11_assert_reset,
+       .deassert_reset = arm11_deassert_reset,
 
-       .bulk_write_memory =    arm11_bulk_write_memory,
+       .get_gdb_arch = arm_get_gdb_arch,
+       .get_gdb_reg_list = arm_get_gdb_reg_list,
 
-       .checksum_memory =      arm_checksum_memory,
-       .blank_check_memory =   arm_blank_check_memory,
+       .read_memory = arm11_read_memory,
+       .write_memory = arm11_write_memory,
 
-       .add_breakpoint =       arm11_add_breakpoint,
-       .remove_breakpoint =    arm11_remove_breakpoint,
-       .add_watchpoint =       arm11_add_watchpoint,
-       .remove_watchpoint =    arm11_remove_watchpoint,
+       .checksum_memory = arm_checksum_memory,
+       .blank_check_memory = arm_blank_check_memory,
 
-       .run_algorithm =        arm11_run_algorithm,
+       .add_breakpoint = arm11_add_breakpoint,
+       .remove_breakpoint = arm11_remove_breakpoint,
 
-       .register_commands =    arm11_register_commands,
-       .target_create =        arm11_target_create,
-       .init_target =          arm11_init_target,
-       .examine =              arm11_examine,
+       .run_algorithm = armv4_5_run_algorithm,
 
-       .mrc =                  arm11_mrc,
-       .mcr =                  arm11_mcr,
+       .commands = arm11_command_handlers,
+       .target_create = arm11_target_create,
+       .init_target = arm11_init_target,
+       .examine = arm11_examine,
 };

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)