target_t -> struct target
[fw/openocd] / src / target / arm11.c
index 7cb24dfb982573bb3ccd354c92264a5f44d1a391..970ffa2c2160f25518037e89f26ad7f51c96f9ff 100644 (file)
@@ -2,7 +2,7 @@
  *   Copyright (C) 2008 digenius technology GmbH.                          *
  *   Michael Bruck                                                         *
  *                                                                         *
- *   Copyright (C) 2008 Oyvind Harboe oyvind.harboe@zylin.com              *
+ *   Copyright (C) 2008,2009 Oyvind Harboe oyvind.harboe@zylin.com         *
  *                                                                         *
  *   Copyright (C) 2008 Georg Acher <acher@in.tum.de>                      *
  *                                                                         *
 #endif
 
 #include "arm11.h"
+#include "arm11_dbgtap.h"
+#include "armv4_5.h"
+#include "arm_simulator.h"
+#include "time_support.h"
 #include "target_type.h"
 
 
 #define FNC_INFO_NOTIMPLEMENTED
 #endif
 
-static int arm11_on_enter_debug_state(arm11_common_t * arm11);
-
-bool   arm11_config_memwrite_burst                             = true;
-bool   arm11_config_memwrite_error_fatal               = true;
-uint32_t               arm11_vcr                                                               = 0;
-bool   arm11_config_memrw_no_increment                 = false;
-bool   arm11_config_step_irq_enable                    = false;
-
-#define ARM11_HANDLER(x)       \
-       .x                              = arm11_##x
-
-target_type_t arm11_target =
-{
-       .name                   = "arm11",
-
-       ARM11_HANDLER(poll),
-       ARM11_HANDLER(arch_state),
-
-       ARM11_HANDLER(target_request_data),
-
-       ARM11_HANDLER(halt),
-       ARM11_HANDLER(resume),
-       ARM11_HANDLER(step),
-
-       ARM11_HANDLER(assert_reset),
-       ARM11_HANDLER(deassert_reset),
-       ARM11_HANDLER(soft_reset_halt),
-
-       ARM11_HANDLER(get_gdb_reg_list),
-
-       ARM11_HANDLER(read_memory),
-       ARM11_HANDLER(write_memory),
-
-       ARM11_HANDLER(bulk_write_memory),
-
-       ARM11_HANDLER(checksum_memory),
-
-       ARM11_HANDLER(add_breakpoint),
-       ARM11_HANDLER(remove_breakpoint),
-       ARM11_HANDLER(add_watchpoint),
-       ARM11_HANDLER(remove_watchpoint),
-
-       ARM11_HANDLER(run_algorithm),
-
-       ARM11_HANDLER(register_commands),
-       ARM11_HANDLER(target_create),
-       ARM11_HANDLER(init_target),
-       ARM11_HANDLER(examine),
-       ARM11_HANDLER(quit),
-};
-
-int arm11_regs_arch_type = -1;
+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
 {
@@ -129,16 +87,16 @@ enum arm11_regtype
 };
 
 
-typedef struct arm11_reg_defs_s
+struct arm11_reg_defs
 {
        char *                                  name;
        uint32_t                                                num;
        int                                             gdb_num;
        enum arm11_regtype              type;
-} arm11_reg_defs_t;
+};
 
 /* update arm11_regcache_ids when changing this */
-static const arm11_reg_defs_t arm11_reg_defs[] =
+static const struct arm11_reg_defs arm11_reg_defs[] =
 {
        {"r0",  0,      0,      ARM11_REGISTER_CORE},
        {"r1",  1,      1,      ARM11_REGISTER_CORE},
@@ -288,21 +246,32 @@ enum arm11_regcache_ids
 
 #define ARM11_GDB_REGISTER_COUNT       26
 
-uint8_t arm11_gdb_dummy_fp_value[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static uint8_t arm11_gdb_dummy_fp_value[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 
-reg_t arm11_gdb_dummy_fp_reg =
+static struct reg arm11_gdb_dummy_fp_reg =
 {
        "GDB dummy floating-point register", arm11_gdb_dummy_fp_value, 0, 1, 96, NULL, 0, NULL, 0
 };
 
-uint8_t arm11_gdb_dummy_fps_value[] = {0, 0, 0, 0};
+static uint8_t arm11_gdb_dummy_fps_value[] = {0, 0, 0, 0};
 
-reg_t arm11_gdb_dummy_fps_reg =
+static struct reg arm11_gdb_dummy_fps_reg =
 {
        "GDB dummy floating-point status register", arm11_gdb_dummy_fps_value, 0, 1, 32, NULL, 0, NULL, 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);
+
 
 /** Check and if necessary take control of the system
  *
@@ -311,7 +280,7 @@ reg_t arm11_gdb_dummy_fps_reg =
  *                                     available a pointer to a word holding the
  *                                     DSCR can be passed. Otherwise use NULL.
  */
-int arm11_check_init(arm11_common_t * arm11, uint32_t * dscr)
+static int arm11_check_init(struct arm11_common *arm11, uint32_t *dscr)
 {
        FNC_INFO;
 
@@ -369,8 +338,9 @@ int arm11_check_init(arm11_common_t * arm11, uint32_t * dscr)
   * or on other occasions that stop the processor.
   *
   */
-static int arm11_on_enter_debug_state(arm11_common_t * arm11)
+static int arm11_on_enter_debug_state(struct arm11_common *arm11)
 {
+       int retval;
        FNC_INFO;
 
        for (size_t i = 0; i < asizeof(arm11->reg_values); i++)
@@ -390,7 +360,7 @@ static int arm11_on_enter_debug_state(arm11_common_t * arm11)
 
                arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);
 
-               scan_field_t    chain5_fields[3];
+               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);
@@ -447,7 +417,9 @@ static int arm11_on_enter_debug_state(arm11_common_t * arm11)
        }
 #endif
 
-       arm11_run_instr_data_prepare(arm11);
+       retval = arm11_run_instr_data_prepare(arm11);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* save r0 - r14 */
 
@@ -456,7 +428,9 @@ static int arm11_on_enter_debug_state(arm11_common_t * arm11)
        for (size_t i = 0; i < 15; i++)
        {
                /* MCR p14,0,R?,c0,c5,0 */
-               arm11_run_instr_data_from_core(arm11, 0xEE000E15 | (i << 12), &R(RX + i), 1);
+               retval = arm11_run_instr_data_from_core(arm11, 0xEE000E15 | (i << 12), &R(RX + i), 1);
+               if (retval != ERROR_OK)
+                       return retval;
        }
 
        /* save rDTR */
@@ -466,7 +440,9 @@ static int arm11_on_enter_debug_state(arm11_common_t * arm11)
        if (R(DSCR) & ARM11_DSCR_RDTR_FULL)
        {
                /* MRC p14,0,R0,c0,c5,0 (move rDTR -> r0 (-> wDTR -> local var)) */
-               arm11_run_instr_data_from_core_via_r0(arm11, 0xEE100E15, &R(RDTR));
+               retval = arm11_run_instr_data_from_core_via_r0(arm11, 0xEE100E15, &R(RDTR));
+               if (retval != ERROR_OK)
+                       return retval;
        }
        else
        {
@@ -476,12 +452,16 @@ static int arm11_on_enter_debug_state(arm11_common_t * arm11)
        /* save CPSR */
 
        /* MRS r0,CPSR (move CPSR -> r0 (-> wDTR -> local var)) */
-       arm11_run_instr_data_from_core_via_r0(arm11, 0xE10F0000, &R(CPSR));
+       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)) */
-       arm11_run_instr_data_from_core_via_r0(arm11, 0xE1A0000F, &R(PC));
+       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 */
 
@@ -507,18 +487,22 @@ static int arm11_on_enter_debug_state(arm11_common_t * arm11)
                /* Write 0 (reset value) to Control register 0 to disable MMU/Cache etc. */
 
                /* MCR p15,0,R0,c1,c0,0 */
-               arm11_run_instr_data_to_core_via_r0(arm11, 0xee010f10, 0);
+               retval = arm11_run_instr_data_to_core_via_r0(arm11, 0xee010f10, 0);
+               if (retval != ERROR_OK)
+                       return retval;
 
        }
 
-       arm11_run_instr_data_finish(arm11);
+       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(arm11_common_t * arm11)
+void arm11_dump_reg_changes(struct arm11_common * arm11)
 {
 
        if (!(debug_level >= LOG_LVL_DEBUG))
@@ -553,11 +537,14 @@ void arm11_dump_reg_changes(arm11_common_t * arm11)
   * This is called in preparation for the RESTART function.
   *
   */
-int arm11_leave_debug_state(arm11_common_t * arm11)
+static int arm11_leave_debug_state(struct arm11_common *arm11)
 {
        FNC_INFO;
+       int retval;
 
-       arm11_run_instr_data_prepare(arm11);
+       retval = arm11_run_instr_data_prepare(arm11);
+       if (retval != ERROR_OK)
+               return retval;
 
        /** \todo TODO: handle other mode registers */
 
@@ -574,7 +561,9 @@ int arm11_leave_debug_state(arm11_common_t * arm11)
                //      LOG_DEBUG("RESTORE R" ZU " %08x", i, R(RX + i));
        }
 
-       arm11_run_instr_data_finish(arm11);
+       retval = arm11_run_instr_data_finish(arm11);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* spec says clear wDTR and rDTR; we assume they are clear as
           otherwise our programming would be sloppy */
@@ -585,36 +574,56 @@ int arm11_leave_debug_state(arm11_common_t * arm11)
 
                if (DSCR & (ARM11_DSCR_RDTR_FULL | ARM11_DSCR_WDTR_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
+                       written into the core. The RDTR FULL/WDTR FULL flag indicates that the
+                       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);
+                       return ERROR_FAIL;
                }
        }
 
-       arm11_run_instr_data_prepare(arm11);
+       retval = arm11_run_instr_data_prepare(arm11);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* restore original wDTR */
 
        if ((R(DSCR) & ARM11_DSCR_WDTR_FULL) || arm11->reg_list[ARM11_RC_WDTR].dirty)
        {
                /* MCR p14,0,R0,c0,c5,0 */
-               arm11_run_instr_data_to_core_via_r0(arm11, 0xee000e15, R(WDTR));
+               retval = arm11_run_instr_data_to_core_via_r0(arm11, 0xee000e15, R(WDTR));
+               if (retval != ERROR_OK)
+                       return retval;
        }
 
        /* restore CPSR */
 
        /* MSR CPSR,R0*/
-       arm11_run_instr_data_to_core_via_r0(arm11, 0xe129f000, R(CPSR));
+       retval = arm11_run_instr_data_to_core_via_r0(arm11, 0xe129f000, R(CPSR));
+       if (retval != ERROR_OK)
+               return retval;
+
 
        /* restore PC */
 
        /* MOV PC,R0 */
-       arm11_run_instr_data_to_core_via_r0(arm11, 0xe1a0f000, R(PC));
+       retval = arm11_run_instr_data_to_core_via_r0(arm11, 0xe1a0f000, R(PC));
+       if (retval != ERROR_OK)
+               return retval;
+
 
        /* restore R0 */
 
        /* MRC p14,0,r0,c0,c5,0 */
        arm11_run_instr_data_to_core1(arm11, 0xee100e15, R(R0));
 
-       arm11_run_instr_data_finish(arm11);
+       retval = arm11_run_instr_data_finish(arm11);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* restore DSCR */
 
@@ -628,7 +637,7 @@ int arm11_leave_debug_state(arm11_common_t * arm11)
 
                arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);
 
-               scan_field_t    chain5_fields[3];
+               struct scan_field       chain5_fields[3];
 
                uint8_t                 Ready           = 0;    /* ignored */
                uint8_t                 Valid           = 0;    /* ignored */
@@ -645,7 +654,7 @@ int arm11_leave_debug_state(arm11_common_t * arm11)
        return ERROR_OK;
 }
 
-void arm11_record_register_history(arm11_common_t * arm11)
+static void arm11_record_register_history(struct arm11_common *arm11)
 {
        for (size_t i = 0; i < ARM11_REGCACHE_COUNT; i++)
        {
@@ -659,14 +668,12 @@ void arm11_record_register_history(arm11_common_t * arm11)
 
 
 /* poll current target status */
-int arm11_poll(struct target_s *target)
+static int arm11_poll(struct target *target)
 {
        FNC_INFO;
+       int retval;
 
-       arm11_common_t * arm11 = target->arch_info;
-
-       if (arm11->trst_active)
-               return ERROR_OK;
+       struct arm11_common * arm11 = target->arch_info;
 
        uint32_t        dscr;
 
@@ -685,7 +692,9 @@ int arm11_poll(struct target_s *target)
                        LOG_DEBUG("enter TARGET_HALTED");
                        target->state                   = TARGET_HALTED;
                        target->debug_reason    = arm11_get_DSCR_debug_reason(dscr);
-                       arm11_on_enter_debug_state(arm11);
+                       retval = arm11_on_enter_debug_state(arm11);
+                       if (retval != ERROR_OK)
+                               return retval;
 
                        target_call_event_callbacks(target,
                                old_state == TARGET_DEBUG_RUNNING ? TARGET_EVENT_DEBUG_HALTED : TARGET_EVENT_HALTED);
@@ -704,12 +713,12 @@ int arm11_poll(struct target_s *target)
        return ERROR_OK;
 }
 /* architecture specific status reply */
-int arm11_arch_state(struct target_s *target)
+static int arm11_arch_state(struct target *target)
 {
-       arm11_common_t * arm11 = target->arch_info;
+       struct arm11_common * arm11 = target->arch_info;
 
        LOG_USER("target halted due to %s\ncpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "",
-                        Jim_Nvp_value2name_simple( nvp_target_debug_reason, target->debug_reason )->name,
+                        Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name,
                         R(CPSR),
                         R(PC));
 
@@ -717,7 +726,8 @@ int arm11_arch_state(struct target_s *target)
 }
 
 /* target request support */
-int arm11_target_request_data(struct target_s *target, uint32_t size, uint8_t *buffer)
+static int arm11_target_request_data(struct target *target,
+               uint32_t size, uint8_t *buffer)
 {
        FNC_INFO_NOTIMPLEMENTED;
 
@@ -725,14 +735,14 @@ int arm11_target_request_data(struct target_s *target, uint32_t size, uint8_t *b
 }
 
 /* target execution control */
-int arm11_halt(struct target_s *target)
+static int arm11_halt(struct target *target)
 {
        FNC_INFO;
 
-       arm11_common_t * arm11 = target->arch_info;
+       struct arm11_common * arm11 = target->arch_info;
 
        LOG_DEBUG("target->state: %s",
-               Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
+               target_state_name(target));
 
        if (target->state == TARGET_UNKNOWN)
        {
@@ -745,24 +755,35 @@ int arm11_halt(struct target_s *target)
                return ERROR_OK;
        }
 
-       if (arm11->trst_active)
-       {
-               arm11->halt_requested = true;
-               return ERROR_OK;
-       }
-
        arm11_add_IR(arm11, ARM11_HALT, TAP_IDLE);
 
        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)
                        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");
+                               return ERROR_FAIL;
+                       }
+               }
+               i++;
        }
 
        arm11_on_enter_debug_state(arm11);
@@ -779,17 +800,18 @@ int arm11_halt(struct target_s *target)
        return ERROR_OK;
 }
 
-int arm11_resume(struct target_s *target, int current, uint32_t address, int handle_breakpoints, int debug_execution)
+static int arm11_resume(struct target *target, int current,
+               uint32_t address, int handle_breakpoints, int debug_execution)
 {
        FNC_INFO;
 
        //        LOG_DEBUG("current %d  address %08x  handle_breakpoints %d  debug_execution %d",
        //      current, address, handle_breakpoints, debug_execution);
 
-       arm11_common_t * arm11 = target->arch_info;
+       struct arm11_common * arm11 = target->arch_info;
 
        LOG_DEBUG("target->state: %s",
-               Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
+               target_state_name(target));
 
 
        if (target->state != TARGET_HALTED)
@@ -811,7 +833,7 @@ int arm11_resume(struct target_s *target, int current, uint32_t address, int han
        {
                /* check if one matches PC and step over it if necessary */
 
-               breakpoint_t *  bp;
+               struct breakpoint *     bp;
 
                for (bp = target->breakpoints; bp; bp = bp->next)
                {
@@ -829,7 +851,7 @@ int arm11_resume(struct target_s *target, int current, uint32_t address, int han
 
                for (bp = target->breakpoints; bp; bp = bp->next)
                {
-                       arm11_sc7_action_t      brp[2];
+                       struct arm11_sc7_action brp[2];
 
                        brp[0].write    = 1;
                        brp[0].address  = ARM11_SC7_BVR0 + brp_num;
@@ -854,6 +876,7 @@ int arm11_resume(struct target_s *target, int current, uint32_t address, int han
 
        CHECK_RETVAL(jtag_execute_queue());
 
+       int i = 0;
        while (1)
        {
                uint32_t dscr;
@@ -864,6 +887,22 @@ int arm11_resume(struct target_s *target, int current, uint32_t address, int han
 
                if (dscr & ARM11_DSCR_CORE_RESTARTED)
                        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");
+                               return ERROR_FAIL;
+                       }
+               }
+               i++;
        }
 
        if (!debug_execution)
@@ -884,12 +923,103 @@ int arm11_resume(struct target_s *target, int current, uint32_t address, int han
        return ERROR_OK;
 }
 
-int arm11_step(struct target_s *target, int current, uint32_t address, int handle_breakpoints)
+
+static int armv4_5_to_arm11(int reg)
+{
+       if (reg < 16)
+               return reg;
+       switch (reg)
+       {
+       case ARMV4_5_CPSR:
+               return ARM11_RC_CPSR;
+       case 16:
+               /* FIX!!! handle thumb better! */
+               return ARM11_RC_CPSR;
+       default:
+               LOG_ERROR("BUG: register translation from armv4_5 to arm11 not supported %d", reg);
+               exit(-1);
+       }
+}
+
+
+static uint32_t arm11_sim_get_reg(struct arm_sim_interface *sim, int reg)
+{
+       struct arm11_common * arm11 = (struct arm11_common *)sim->user_data;
+
+       reg=armv4_5_to_arm11(reg);
+
+       return buf_get_u32(arm11->reg_list[reg].value, 0, 32);
+}
+
+static void arm11_sim_set_reg(struct arm_sim_interface *sim,
+               int reg, uint32_t value)
+{
+       struct arm11_common * arm11 = (struct arm11_common *)sim->user_data;
+
+       reg=armv4_5_to_arm11(reg);
+
+       buf_set_u32(arm11->reg_list[reg].value, 0, 32, value);
+}
+
+static uint32_t arm11_sim_get_cpsr(struct arm_sim_interface *sim,
+               int pos, int bits)
+{
+       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",
-               Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
+               target_state_name(target));
 
        if (target->state != TARGET_HALTED)
        {
@@ -897,13 +1027,14 @@ int arm11_step(struct target_s *target, int current, uint32_t address, int handl
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       arm11_common_t * arm11 = target->arch_info;
+       struct arm11_common * arm11 = target->arch_info;
 
        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;
@@ -943,14 +1074,34 @@ int arm11_step(struct target_s *target, int current, uint32_t address, int handl
 
                /* Set up breakpoint for stepping */
 
-               arm11_sc7_action_t      brp[2];
+               struct arm11_sc7_action brp[2];
 
                brp[0].write    = 1;
                brp[0].address  = ARM11_SC7_BVR0;
-               brp[0].value    = R(PC);
                brp[1].write    = 1;
                brp[1].address  = ARM11_SC7_BCR0;
-               brp[1].value    = 0x1 | (3 << 1) | (0x0F << 5) | (0 << 14) | (0 << 16) | (0 << 20) | (2 << 21);
+
+               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
+                        */
+                        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),
+                        */
+                       uint32_t next_pc;
+                       int retval;
+                       retval = arm11_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);
+               }
 
                CHECK_RETVAL(arm11_sc7_run(arm11, brp, asizeof(brp)));
 
@@ -969,10 +1120,8 @@ int arm11_step(struct target_s *target, int current, uint32_t address, int handl
 
                CHECK_RETVAL(jtag_execute_queue());
 
-               /** \todo TODO: add a timeout */
-
                /* wait for halt */
-
+               int i = 0;
                while (1)
                {
                        uint32_t dscr;
@@ -984,6 +1133,21 @@ int arm11_step(struct target_s *target, int current, uint32_t address, int handl
                        if ((dscr & (ARM11_DSCR_CORE_RESTARTED | ARM11_DSCR_CORE_HALTED)) ==
                                (ARM11_DSCR_CORE_RESTARTED | ARM11_DSCR_CORE_HALTED))
                                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");
+                                       return ERROR_FAIL;
+                               }
+                       }
+                       i++;
                }
 
                /* clear breakpoint */
@@ -1005,53 +1169,74 @@ int arm11_step(struct target_s *target, int current, uint32_t address, int handl
        return ERROR_OK;
 }
 
-/* target reset control */
-int arm11_assert_reset(struct target_s *target)
+static int arm11_assert_reset(struct target *target)
 {
        FNC_INFO;
+       int retval;
 
-#if 0
-       /* assert reset lines */
-       /* resets only the DBGTAP, not the ARM */
-
-       jtag_add_reset(1, 0);
-       jtag_add_sleep(5000);
+       struct arm11_common * arm11 = target->arch_info;
+       retval = arm11_check_init(arm11, NULL);
+       if (retval != ERROR_OK)
+               return retval;
 
-       arm11_common_t * arm11 = target->arch_info;
-       arm11->trst_active = true;
-#endif
+       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));
        }
 
-       return ERROR_OK;
-}
 
-int arm11_deassert_reset(struct target_s *target)
-{
-       FNC_INFO;
+       /* 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?
+        */
 
-#if 0
-       LOG_DEBUG("target->state: %s",
-               Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
+       jtag_add_reset(0, 1);
+       jtag_add_reset(0, 0);
 
+       /* How long do we have to wait? */
+       jtag_add_sleep(5000);
 
-       /* deassert reset lines */
-       jtag_add_reset(0, 0);
+       /* un-mess up TAP state */
+       jtag_add_tlr();
 
-       arm11_common_t * arm11 = target->arch_info;
-       arm11->trst_active = false;
+       retval = jtag_execute_queue();
+       if (retval != ERROR_OK)
+       {
+               return retval;
+       }
 
-       if (arm11->halt_requested)
-               return arm11_halt(target);
-#endif
+       return ERROR_OK;
+}
 
+static int arm11_deassert_reset(struct target *target)
+{
        return ERROR_OK;
 }
 
-int arm11_soft_reset_halt(struct target_s *target)
+static int arm11_soft_reset_halt(struct target *target)
 {
        FNC_INFO_NOTIMPLEMENTED;
 
@@ -1059,14 +1244,15 @@ int arm11_soft_reset_halt(struct target_s *target)
 }
 
 /* target register access for gdb */
-int arm11_get_gdb_reg_list(struct target_s *target, struct reg_s **reg_list[], int *reg_list_size)
+static int arm11_get_gdb_reg_list(struct target *target,
+               struct reg **reg_list[], int *reg_list_size)
 {
        FNC_INFO;
 
-       arm11_common_t * arm11 = target->arch_info;
+       struct arm11_common * arm11 = target->arch_info;
 
        *reg_list_size  = ARM11_GDB_REGISTER_COUNT;
-       *reg_list               = malloc(sizeof(reg_t*) * ARM11_GDB_REGISTER_COUNT);
+       *reg_list               = malloc(sizeof(struct reg*) * ARM11_GDB_REGISTER_COUNT);
 
        for (size_t i = 16; i < 24; i++)
        {
@@ -1089,10 +1275,17 @@ int arm11_get_gdb_reg_list(struct target_s *target, struct reg_s **reg_list[], i
 /* target memory access
  * size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit)
  * count: number of items of <size>
+ *
+ * arm11_config_memrw_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.
  */
-int arm11_read_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+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)
 {
        /** \todo TODO: check if buffer cast to uint32_t* and uint16_t* might cause alignment problems */
+       int retval;
 
        FNC_INFO;
 
@@ -1104,12 +1297,16 @@ int arm11_read_memory(struct target_s *target, uint32_t address, uint32_t size,
 
        LOG_DEBUG("ADDR %08" PRIx32 "  SIZE %08" PRIx32 "  COUNT %08" PRIx32 "", address, size, count);
 
-       arm11_common_t * arm11 = target->arch_info;
+       struct arm11_common * arm11 = target->arch_info;
 
-       arm11_run_instr_data_prepare(arm11);
+       retval = arm11_run_instr_data_prepare(arm11);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* MRC p14,0,r0,c0,c5,0 */
-       arm11_run_instr_data_to_core1(arm11, 0xee100e15, address);
+       retval = arm11_run_instr_data_to_core1(arm11, 0xee100e15, address);
+       if (retval != ERROR_OK)
+               return retval;
 
        switch (size)
        {
@@ -1149,7 +1346,7 @@ int arm11_read_memory(struct target_s *target, uint32_t address, uint32_t size,
                                arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1);
 
                                uint16_t svalue = res;
-                               memcpy(buffer + count * sizeof(uint16_t), &svalue, sizeof(uint16_t));
+                               memcpy(buffer + i * sizeof(uint16_t), &svalue, sizeof(uint16_t));
                        }
 
                        break;
@@ -1168,13 +1365,24 @@ int arm11_read_memory(struct target_s *target, uint32_t address, uint32_t size,
                }
        }
 
-       arm11_run_instr_data_finish(arm11);
+       return arm11_run_instr_data_finish(arm11);
+}
 
-       return ERROR_OK;
+static int arm11_read_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+{
+       return arm11_read_memory_inner(target, address, size, count, buffer, false);
 }
 
-int arm11_write_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+/*
+* arm11_config_memrw_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)
 {
+       int retval;
        FNC_INFO;
 
        if (target->state != TARGET_HALTED)
@@ -1185,12 +1393,25 @@ int arm11_write_memory(struct target_s *target, uint32_t address, uint32_t size,
 
        LOG_DEBUG("ADDR %08" PRIx32 "  SIZE %08" PRIx32 "  COUNT %08" PRIx32 "", address, size, count);
 
-       arm11_common_t * arm11 = target->arch_info;
+       struct arm11_common * arm11 = target->arch_info;
 
-       arm11_run_instr_data_prepare(arm11);
+       retval = arm11_run_instr_data_prepare(arm11);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* MRC p14,0,r0,c0,c5,0 */
-       arm11_run_instr_data_to_core1(arm11, 0xee100e15, address);
+       retval = arm11_run_instr_data_to_core1(arm11, 0xee100e15, address);
+       if (retval != ERROR_OK)
+               return retval;
+
+       /* burst writes are not used for single words as those may well be
+        * reset init script writes.
+        *
+        * The other advantage is that as burst writes are default, we'll
+        * now exercise both burst and non-burst code paths with the
+        * default settings, increasing code coverage.
+        */
+       bool burst = arm11_config_memwrite_burst && (count > 1);
 
        switch (size)
        {
@@ -1201,12 +1422,16 @@ int arm11_write_memory(struct target_s *target, uint32_t address, uint32_t size,
                        for (size_t i = 0; i < count; i++)
                        {
                                /* MRC p14,0,r1,c0,c5,0 */
-                               arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buffer++);
+                               retval = arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buffer++);
+                               if (retval != ERROR_OK)
+                                       return retval;
 
                                /* strb    r1, [r0], #1 */
                                /* strb    r1, [r0] */
-                               arm11_run_instr_no_data1(arm11,
+                               retval = arm11_run_instr_no_data1(arm11,
                                        !arm11_config_memrw_no_increment ? 0xe4c01001 : 0xe5c01000);
+                               if (retval != ERROR_OK)
+                                       return retval;
                        }
 
                        break;
@@ -1219,15 +1444,19 @@ int arm11_write_memory(struct target_s *target, uint32_t address, uint32_t size,
                        for (size_t i = 0; i < count; i++)
                        {
                                uint16_t value;
-                               memcpy(&value, buffer + count * sizeof(uint16_t), sizeof(uint16_t));
+                               memcpy(&value, buffer + i * sizeof(uint16_t), sizeof(uint16_t));
 
                                /* MRC p14,0,r1,c0,c5,0 */
-                               arm11_run_instr_data_to_core1(arm11, 0xee101e15, value);
+                               retval = arm11_run_instr_data_to_core1(arm11, 0xee101e15, value);
+                               if (retval != ERROR_OK)
+                                       return retval;
 
                                /* strh    r1, [r0], #2 */
                                /* strh    r1, [r0] */
-                               arm11_run_instr_no_data1(arm11,
+                               retval = arm11_run_instr_no_data1(arm11,
                                        !arm11_config_memrw_no_increment ? 0xe0c010b2 : 0xe1c010b0);
+                               if (retval != ERROR_OK)
+                                       return retval;
                        }
 
                        break;
@@ -1239,53 +1468,64 @@ int arm11_write_memory(struct target_s *target, uint32_t address, uint32_t size,
                /** \todo TODO: buffer cast to uint32_t* causes alignment warnings */
                uint32_t *words = (uint32_t*)buffer;
 
-               if (!arm11_config_memwrite_burst)
+               if (!burst)
                {
                        /* STC p14,c5,[R0],#4 */
                        /* STC p14,c5,[R0]*/
-                       arm11_run_instr_data_to_core(arm11, instr, words, count);
+                       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]*/
-                       arm11_run_instr_data_to_core_noack(arm11, instr, words, count);
+                       retval = arm11_run_instr_data_to_core_noack(arm11, instr, words, count);
+                       if (retval != ERROR_OK)
+                               return retval;
                }
 
                break;
        }
        }
 
-#if 1
        /* r0 verification */
        if (!arm11_config_memrw_no_increment)
        {
                uint32_t r0;
 
                /* MCR p14,0,R0,c0,c5,0 */
-               arm11_run_instr_data_from_core(arm11, 0xEE000E15, &r0, 1);
+               retval = arm11_run_instr_data_from_core(arm11, 0xEE000E15, &r0, 1);
+               if (retval != ERROR_OK)
+                       return retval;
 
                if (address + size * count != r0)
                {
-                       LOG_ERROR("Data transfer failed. (%d)", (int)((r0 - address) - size * count));
+                       LOG_ERROR("Data transfer failed. Expected end "
+                                       "address 0x%08x, got 0x%08x",
+                                       (unsigned) (address + size * count),
+                                       (unsigned) r0);
 
-                       if (arm11_config_memwrite_burst)
+                       if (burst)
                                LOG_ERROR("use 'arm11 memwrite burst disable' to disable fast burst mode");
 
                        if (arm11_config_memwrite_error_fatal)
                                return ERROR_FAIL;
                }
        }
-#endif
-
-       arm11_run_instr_data_finish(arm11);
 
-       return ERROR_OK;
+       return arm11_run_instr_data_finish(arm11);
 }
 
+static int arm11_write_memory(struct target *target,
+               uint32_t address, uint32_t size, uint32_t count, 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 */
-int arm11_bulk_write_memory(struct target_s *target, uint32_t address, uint32_t count, uint8_t *buffer)
+static int arm11_bulk_write_memory(struct target *target,
+               uint32_t address, uint32_t count, uint8_t *buffer)
 {
        FNC_INFO;
 
@@ -1302,7 +1542,8 @@ int arm11_bulk_write_memory(struct target_s *target, uint32_t address, uint32_t
  * fallback code will read data from the target and calculate the CRC on the
  * host.
  */
-int arm11_checksum_memory(struct target_s *target, uint32_t address, uint32_t count, uint32_t* checksum)
+static int arm11_checksum_memory(struct target *target,
+               uint32_t address, uint32_t count, uint32_t* checksum)
 {
        return ERROR_FAIL;
 }
@@ -1310,11 +1551,12 @@ int arm11_checksum_memory(struct target_s *target, uint32_t address, uint32_t co
 /* target break-/watchpoint control
 * rw: 0 = write, 1 = read, 2 = access
 */
-int arm11_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
+static int arm11_add_breakpoint(struct target *target,
+               struct breakpoint *breakpoint)
 {
        FNC_INFO;
 
-       arm11_common_t * arm11 = target->arch_info;
+       struct arm11_common * arm11 = target->arch_info;
 
 #if 0
        if (breakpoint->type == BKPT_SOFT)
@@ -1341,25 +1583,28 @@ int arm11_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
        return ERROR_OK;
 }
 
-int arm11_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
+static int arm11_remove_breakpoint(struct target *target,
+               struct breakpoint *breakpoint)
 {
        FNC_INFO;
 
-       arm11_common_t * arm11 = target->arch_info;
+       struct arm11_common * arm11 = target->arch_info;
 
        arm11->free_brps++;
 
        return ERROR_OK;
 }
 
-int arm11_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
+static int arm11_add_watchpoint(struct target *target,
+               struct watchpoint *watchpoint)
 {
        FNC_INFO_NOTIMPLEMENTED;
 
        return ERROR_OK;
 }
 
-int arm11_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
+static int arm11_remove_watchpoint(struct target *target,
+               struct watchpoint *watchpoint)
 {
        FNC_INFO_NOTIMPLEMENTED;
 
@@ -1368,11 +1613,13 @@ int arm11_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
 
 // HACKHACKHACK - FIXME mode/state
 /* target algorithm support */
-int arm11_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t *mem_params,
-                       int num_reg_params, reg_param_t *reg_params, uint32_t entry_point, uint32_t exit_point,
-                       int timeout_ms, void *arch_info)
+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)
 {
-               arm11_common_t *arm11 = target->arch_info;
+               struct arm11_common *arm11 = target->arch_info;
 //     enum armv4_5_state core_state = arm11->core_state;
 //     enum armv4_5_mode core_mode = arm11->core_mode;
        uint32_t context[16];
@@ -1393,13 +1640,13 @@ int arm11_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t
 //             return ERROR_FAIL;
 
        // Save regs
-       for (size_t i = 0; i < 16; i++)
+       for (unsigned i = 0; i < 16; i++)
        {
                context[i] = buf_get_u32((uint8_t*)(&arm11->reg_values[i]),0,32);
-               LOG_DEBUG("Save %zi: 0x%" PRIx32 "",i,context[i]);
+               LOG_DEBUG("Save %u: 0x%" PRIx32 "", i, context[i]);
        }
 
-       cpsr = buf_get_u32((uint8_t*)(arm11->reg_values+ARM11_RC_CPSR),0,32);
+       cpsr = buf_get_u32((uint8_t*)(arm11->reg_values + ARM11_RC_CPSR),0,32);
        LOG_DEBUG("Save CPSR: 0x%" PRIx32 "", cpsr);
 
        for (int i = 0; i < num_mem_params; i++)
@@ -1410,7 +1657,7 @@ int arm11_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t
        // Set register parameters
        for (int i = 0; i < num_reg_params; i++)
        {
-               reg_t *reg = register_get_by_name(arm11->core_cache, reg_params[i].reg_name, 0);
+               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);
@@ -1495,7 +1742,7 @@ int arm11_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t
        {
                if (reg_params[i].direction != PARAM_OUT)
                {
-                       reg_t *reg = register_get_by_name(arm11->core_cache, reg_params[i].reg_name, 0);
+                       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);
@@ -1532,15 +1779,15 @@ restore:
        return retval;
 }
 
-int arm11_target_create(struct target_s *target, Jim_Interp *interp)
+static int arm11_target_create(struct target *target, Jim_Interp *interp)
 {
        FNC_INFO;
 
-       NEW(arm11_common_t, arm11, 1);
+       NEW(struct arm11_common, arm11, 1);
 
        arm11->target = target;
 
-       if (target->tap==NULL)
+       if (target->tap == NULL)
                return ERROR_FAIL;
 
        if (target->tap->ir_length != 5)
@@ -1554,24 +1801,27 @@ int arm11_target_create(struct target_s *target, Jim_Interp *interp)
        return ERROR_OK;
 }
 
-int arm11_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
+static int arm11_init_target(struct command_context_s *cmd_ctx,
+               struct target *target)
 {
        /* Initialize anything we can set up without talking to the target */
        return arm11_build_reg_cache(target);
 }
 
 /* talk to the target and set things up */
-int arm11_examine(struct target_s *target)
+static int arm11_examine(struct target *target)
 {
+       int retval;
+
        FNC_INFO;
 
-       arm11_common_t * arm11 = target->arch_info;
+       struct arm11_common * arm11 = target->arch_info;
 
        /* check IDCODE */
 
        arm11_add_IR(arm11, ARM11_IDCODE, ARM11_TAP_DEFAULT);
 
-       scan_field_t            idcode_field;
+       struct scan_field               idcode_field;
 
        arm11_setup_field(arm11, 32, NULL, &arm11->device_id, &idcode_field);
 
@@ -1583,7 +1833,7 @@ int arm11_examine(struct target_s *target)
 
        arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);
 
-       scan_field_t            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);
@@ -1630,26 +1880,22 @@ int arm11_examine(struct target_s *target)
         * as suggested by the spec.
         */
 
-       arm11_check_init(arm11, NULL);
+       retval = arm11_check_init(arm11, NULL);
+       if (retval != ERROR_OK)
+               return retval;
 
        target_set_examined(target);
 
        return ERROR_OK;
 }
 
-int arm11_quit(void)
-{
-       FNC_INFO_NOTIMPLEMENTED;
-
-       return ERROR_OK;
-}
 
 /** Load a register that is marked !valid in the register cache */
-int arm11_get_reg(reg_t *reg)
+static int arm11_get_reg(struct reg *reg)
 {
        FNC_INFO;
 
-       target_t * target = ((arm11_reg_state_t *)reg->arch_info)->target;
+       struct target * target = ((struct arm11_reg_state *)reg->arch_info)->target;
 
        if (target->state != TARGET_HALTED)
        {
@@ -1660,36 +1906,36 @@ int arm11_get_reg(reg_t *reg)
        /** \todo TODO: Check this. We assume that all registers are fetched at debug entry. */
 
 #if 0
-       arm11_common_t *arm11 = target->arch_info;
-       const arm11_reg_defs_t * arm11_reg_info = arm11_reg_defs + ((arm11_reg_state_t *)reg->arch_info)->def_index;
+       struct arm11_common *arm11 = target->arch_info;
+       const struct arm11_reg_defs * arm11_reg_info = arm11_reg_defs + ((struct arm11_reg_state *)reg->arch_info)->def_index;
 #endif
 
        return ERROR_OK;
 }
 
 /** Change a value in the register cache */
-int arm11_set_reg(reg_t *reg, uint8_t *buf)
+static int arm11_set_reg(struct reg *reg, uint8_t *buf)
 {
        FNC_INFO;
 
-       target_t * target = ((arm11_reg_state_t *)reg->arch_info)->target;
-       arm11_common_t *arm11 = target->arch_info;
-//       const arm11_reg_defs_t * arm11_reg_info = arm11_reg_defs + ((arm11_reg_state_t *)reg->arch_info)->def_index;
+       struct target * target = ((struct arm11_reg_state *)reg->arch_info)->target;
+       struct arm11_common *arm11 = target->arch_info;
+//       const struct arm11_reg_defs * arm11_reg_info = arm11_reg_defs + ((struct arm11_reg_state *)reg->arch_info)->def_index;
 
-       arm11->reg_values[((arm11_reg_state_t *)reg->arch_info)->def_index] = buf_get_u32(buf, 0, 32);
+       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;
 }
 
-int arm11_build_reg_cache(target_t *target)
+static int arm11_build_reg_cache(struct target *target)
 {
-       arm11_common_t *arm11 = target->arch_info;
+       struct arm11_common *arm11 = target->arch_info;
 
-       NEW(reg_cache_t,                cache,                          1);
-       NEW(reg_t,                              reg_list,                       ARM11_REGCACHE_COUNT);
-       NEW(arm11_reg_state_t,  arm11_reg_states,       ARM11_REGCACHE_COUNT);
+       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);
@@ -1705,7 +1951,7 @@ int arm11_build_reg_cache(target_t *target)
        cache->reg_list = reg_list;
        cache->num_regs = ARM11_REGCACHE_COUNT;
 
-       reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
+       struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
        (*cache_p) = cache;
 
        arm11->core_cache = cache;
@@ -1724,9 +1970,9 @@ int arm11_build_reg_cache(target_t *target)
 
        for (i = 0; i < ARM11_REGCACHE_COUNT; i++)
        {
-               reg_t *                                         r       = reg_list                      + i;
-               const arm11_reg_defs_t *        rd      = arm11_reg_defs        + i;
-               arm11_reg_state_t *                     rs      = arm11_reg_states      + 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;
@@ -1745,7 +1991,7 @@ int arm11_build_reg_cache(target_t *target)
        return ERROR_OK;
 }
 
-int arm11_handle_bool(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, bool * var, char * name)
+static COMMAND_HELPER(arm11_handle_bool, bool *var, char *name)
 {
        if (argc == 0)
        {
@@ -1781,37 +2027,26 @@ int arm11_handle_bool(struct command_context_s *cmd_ctx, char *cmd, char **args,
 }
 
 #define BOOL_WRAPPER(name, print_name) \
-int arm11_handle_bool_##name(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) \
-{ \
-       return arm11_handle_bool(cmd_ctx, cmd, args, argc, &arm11_config_##name, print_name); \
-}
-
-#define RC_TOP(name, descr, more)  \
+COMMAND_HANDLER(arm11_handle_bool_##name) \
 { \
-       command_t * new_cmd = register_command(cmd_ctx, top_cmd, name, NULL, COMMAND_ANY, descr);  \
-       command_t * top_cmd = new_cmd; \
-       more \
+       return CALL_COMMAND_HANDLER(arm11_handle_bool, \
+                       &arm11_config_##name, print_name); \
 }
 
-#define RC_FINAL(name, descr, handler) \
-       register_command(cmd_ctx, top_cmd, name, handler, COMMAND_ANY, descr);
-
-#define RC_FINAL_BOOL(name, descr, var)  \
-       register_command(cmd_ctx, top_cmd, name, arm11_handle_bool_##var, COMMAND_ANY, descr);
-
 BOOL_WRAPPER(memwrite_burst,                   "memory write burst mode")
 BOOL_WRAPPER(memwrite_error_fatal,             "fatal error mode for memory writes")
-BOOL_WRAPPER(memrw_no_increment,               "\"no increment\" mode for memory transfers")
 BOOL_WRAPPER(step_irq_enable,                  "IRQs while stepping")
+BOOL_WRAPPER(hardware_step,                    "hardware single step")
 
-int arm11_handle_vcr(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+COMMAND_HANDLER(arm11_handle_vcr)
 {
-       if (argc == 1)
-       {
-               arm11_vcr = strtoul(args[0], NULL, 0);
-       }
-       else if (argc != 0)
-       {
+       switch (argc) {
+       case 0:
+               break;
+       case 1:
+               COMMAND_PARSE_NUMBER(u32, args[0], arm11_vcr);
+               break;
+       default:
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
@@ -1819,7 +2054,7 @@ int arm11_handle_vcr(struct command_context_s *cmd_ctx, char *cmd, char **args,
        return ERROR_OK;
 }
 
-const uint32_t arm11_coproc_instruction_limits[] =
+static const uint32_t arm11_coproc_instruction_limits[] =
 {
        15,                             /* coprocessor */
        7,                              /* opcode 1 */
@@ -1829,13 +2064,10 @@ const uint32_t arm11_coproc_instruction_limits[] =
        0xFFFFFFFF,             /* value */
 };
 
-const char arm11_mrc_syntax[] = "Syntax: mrc <jtag_target> <coprocessor> <opcode 1> <CRn> <CRm> <opcode 2>. All parameters are numbers only.";
-const char arm11_mcr_syntax[] = "Syntax: mcr <jtag_target> <coprocessor> <opcode 1> <CRn> <CRm> <opcode 2> <32bit value to write>. All parameters are numbers only.";
-
-arm11_common_t * arm11_find_target(const char * arg)
+static struct arm11_common * arm11_find_target(const char * arg)
 {
-       jtag_tap_t *    tap;
-       target_t *              t;
+       struct jtag_tap *       tap;
+       struct target *         t;
 
        tap = jtag_tap_by_string(arg);
 
@@ -1855,128 +2087,202 @@ arm11_common_t * arm11_find_target(const char * arg)
        return 0;
 }
 
-int arm11_handle_mrc_mcr(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, bool read)
+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)
 {
-       if (argc != (read ? 6 : 7))
+       int retval;
+       
+       if (target->state != TARGET_HALTED)
        {
-               LOG_ERROR("Invalid number of arguments. %s", read ? arm11_mrc_syntax : arm11_mcr_syntax);
-               return -1;
+               LOG_ERROR("Target not halted");
+               return ERROR_FAIL;
        }
+               
+       struct arm11_common * arm11 = target->arch_info;
 
-       arm11_common_t * arm11 = arm11_find_target(args[0]);
+       uint32_t instr = 0xEE000010     |
+               (cpnum <<  8) |
+               (op1 << 21) |
+               (CRn << 16) |
+               (CRm <<  0) |
+               (op2 <<  5);
 
-       if (!arm11)
-       {
-               LOG_ERROR("Parameter 1 is not a the JTAG chain position of an ARM11 device. %s",
-                       read ? arm11_mrc_syntax : arm11_mcr_syntax);
+       if (read)
+               instr |= 0x00100000;
 
-               return -1;
-       }
+       retval = arm11_run_instr_data_prepare(arm11);
+       if (retval != ERROR_OK)
+               return retval;
 
-       if (arm11->target->state != TARGET_HALTED)
+       if (read)
        {
-               LOG_WARNING("target was not halted");
-               return ERROR_TARGET_NOT_HALTED;
+               retval = arm11_run_instr_data_from_core_via_r0(arm11, instr, value);
+               if (retval != ERROR_OK)
+                       return retval;
+       }
+       else
+       {
+               retval = arm11_run_instr_data_to_core_via_r0(arm11, instr, *value);
+               if (retval != ERROR_OK)
+                       return retval;
        }
 
-       uint32_t        values[6];
+       return arm11_run_instr_data_finish(arm11);
+}
 
-       for (size_t i = 0; i < (read ? 5 : 6); i++)
-       {
-               values[i] = strtoul(args[i + 1], NULL, 0);
+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);
+}
 
-               if (values[i] > arm11_coproc_instruction_limits[i])
-               {
-                       LOG_ERROR("Parameter %ld out of bounds (%" PRId32 " max). %s",
-                                 (long)(i + 2), 
-                                 arm11_coproc_instruction_limits[i],
-                               read ? arm11_mrc_syntax : arm11_mcr_syntax);
-                       return -1;
-               }
+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 COMMAND_HELPER(arm11_handle_etm_read_write, bool read)
+{
+       if (argc != (read ? 2 : 3))
+       {
+               LOG_ERROR("Invalid number of arguments.");
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
-       uint32_t instr = 0xEE000010     |
-               (values[0] <<  8) |
-               (values[1] << 21) |
-               (values[2] << 16) |
-               (values[3] <<  0) |
-               (values[4] <<  5);
+       struct arm11_common * arm11 = arm11_find_target(args[0]);
 
-       if (read)
-               instr |= 0x00100000;
+       if (!arm11)
+       {
+               LOG_ERROR("Parameter 1 is not the target name of an ARM11 device.");
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
 
-       arm11_run_instr_data_prepare(arm11);
+       uint32_t address;
+       COMMAND_PARSE_NUMBER(u32, args[1], address);
 
-       if (read)
+       if (!read)
        {
-               uint32_t result;
-               arm11_run_instr_data_from_core_via_r0(arm11, instr, &result);
+               uint32_t value;
+               COMMAND_PARSE_NUMBER(u32, args[2], value);
+
+               LOG_INFO("ETM write register 0x%02" PRIx32 " (%" PRId32 ") = 0x%08" PRIx32 " (%" PRId32 ")",
+                 address, address, value, value);
 
-               LOG_INFO("MRC p%d, %d, R0, c%d, c%d, %d = 0x%08" PRIx32 " (%" PRId32 ")",
-                        (int)(values[0]), 
-                        (int)(values[1]), 
-                        (int)(values[2]), 
-                        (int)(values[3]), 
-                        (int)(values[4]), result, result);
+               CHECK_RETVAL(arm11_write_etm(arm11, address, value));
        }
        else
        {
-               arm11_run_instr_data_to_core_via_r0(arm11, instr, values[5]);
+               uint32_t value;
 
-               LOG_INFO("MRC p%d, %d, R0 (#0x%08" PRIx32 "), c%d, c%d, %d",
-                        (int)(values[0]), (int)(values[1]),
-                        values[5],
-                        (int)(values[2]), (int)(values[3]), (int)(values[4]));
-       }
-
-       arm11_run_instr_data_finish(arm11);
+               CHECK_RETVAL(arm11_read_etm(arm11, address, &value));
 
+           LOG_INFO("ETM read register 0x%02" PRIx32 " (%" PRId32 ") = 0x%08" PRIx32 " (%" PRId32 ")",
+                 address, address, value, value);
+       }
 
        return ERROR_OK;
 }
 
-int arm11_handle_mrc(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+COMMAND_HANDLER(arm11_handle_etmr)
 {
-       return arm11_handle_mrc_mcr(cmd_ctx, cmd, args, argc, true);
+       return CALL_COMMAND_HANDLER(arm11_handle_etm_read_write, true);
 }
 
-int arm11_handle_mcr(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+COMMAND_HANDLER(arm11_handle_etmw)
 {
-       return arm11_handle_mrc_mcr(cmd_ctx, cmd, args, argc, false);
+       return CALL_COMMAND_HANDLER(arm11_handle_etm_read_write, false);
 }
 
-int arm11_register_commands(struct command_context_s *cmd_ctx)
-{
-       FNC_INFO;
+#define ARM11_HANDLER(x)       .x = arm11_##x
+
+struct target_type arm11_target = {
+               .name = "arm11",
 
-       command_t * top_cmd = NULL;
+               ARM11_HANDLER(poll),
+               ARM11_HANDLER(arch_state),
 
-       RC_TOP(                         "arm11",                                "arm11 specific commands",
+               ARM11_HANDLER(target_request_data),
 
-       RC_TOP(                         "memwrite",                             "Control memory write transfer mode",
+               ARM11_HANDLER(halt),
+               ARM11_HANDLER(resume),
+               ARM11_HANDLER(step),
 
-               RC_FINAL_BOOL(  "burst",                                "Enable/Disable non-standard but fast burst mode (default: enabled)",
-                                               memwrite_burst)
+               ARM11_HANDLER(assert_reset),
+               ARM11_HANDLER(deassert_reset),
+               ARM11_HANDLER(soft_reset_halt),
 
-               RC_FINAL_BOOL(  "error_fatal",                  "Terminate program if transfer error was found (default: enabled)",
-                                               memwrite_error_fatal)
-       ) /* memwrite */
+               ARM11_HANDLER(get_gdb_reg_list),
 
-       RC_FINAL_BOOL(          "no_increment",                 "Don't increment address on multi-read/-write (default: disabled)",
-                                               memrw_no_increment)
+               ARM11_HANDLER(read_memory),
+               ARM11_HANDLER(write_memory),
 
-       RC_FINAL_BOOL(          "step_irq_enable",              "Enable interrupts while stepping (default: disabled)",
-                                               step_irq_enable)
+               ARM11_HANDLER(bulk_write_memory),
 
-       RC_FINAL(                       "vcr",                                  "Control (Interrupt) Vector Catch Register",
-                                               arm11_handle_vcr)
+               ARM11_HANDLER(checksum_memory),
 
-       RC_FINAL(                       "mrc",                                  "Read Coprocessor register",
-                                               arm11_handle_mrc)
+               ARM11_HANDLER(add_breakpoint),
+               ARM11_HANDLER(remove_breakpoint),
+               ARM11_HANDLER(add_watchpoint),
+               ARM11_HANDLER(remove_watchpoint),
 
-       RC_FINAL(                       "mcr",                                  "Write Coprocessor register",
-                                               arm11_handle_mcr)
-       ) /* arm11 */
+               ARM11_HANDLER(run_algorithm),
+
+               ARM11_HANDLER(register_commands),
+               ARM11_HANDLER(target_create),
+               ARM11_HANDLER(init_target),
+               ARM11_HANDLER(examine),
+
+               ARM11_HANDLER(mrc),
+               ARM11_HANDLER(mcr),
+       };
+
+
+int arm11_register_commands(struct command_context_s *cmd_ctx)
+{
+       FNC_INFO;
+
+       command_t *top_cmd, *mw_cmd;
+
+       top_cmd = register_command(cmd_ctx, NULL, "arm11",
+                       NULL, COMMAND_ANY, NULL);
+
+       register_command(cmd_ctx, top_cmd, "etmr",
+                       arm11_handle_etmr, COMMAND_ANY,
+                       "Read Embedded Trace Macrocell (ETM) register. etmr <jtag_target> <ETM register address>");
+
+       register_command(cmd_ctx, top_cmd, "etmw",
+                       arm11_handle_etmw, COMMAND_ANY,
+                       "Write Embedded Trace Macrocell (ETM) register. etmr <jtag_target> <ETM register address> <value>");
+
+       /* "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 ERROR_OK;
 }