change #include "time_support.h" to <helper/time_support.h>
[fw/openocd] / src / target / arm7_9_common.c
index 76c79c3abd2d89f591dc4f9575c4d86fcccfe2ff..255a85f57f8207e3406e3cf68d3eb4549af71531 100644 (file)
 #include "breakpoints.h"
 #include "embeddedice.h"
 #include "target_request.h"
-#include "arm7_9_common.h"
-#include "time_support.h"
+#include "etm.h"
+#include <helper/time_support.h>
 #include "arm_simulator.h"
 #include "algorithm.h"
+#include "register.h"
 
 
 /**
@@ -425,12 +426,6 @@ int arm7_9_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
 {
        struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
 
-       if (target->state != TARGET_HALTED)
-       {
-               LOG_WARNING("target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
        if (arm7_9->breakpoint_count == 0)
        {
                /* make sure we don't have any dangling breakpoints. This is vital upon
@@ -630,12 +625,6 @@ int arm7_9_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
 {
        struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
 
-       if (target->state != TARGET_HALTED)
-       {
-               LOG_WARNING("target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
        if (arm7_9->wp_available < 1)
        {
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
@@ -1039,7 +1028,7 @@ int arm7_9_assert_reset(struct target *target)
        target->state = TARGET_RESET;
        jtag_add_sleep(50000);
 
-       armv4_5_invalidate_core_regs(target);
+       register_cache_invalidate(arm7_9->armv4_5_common.core_cache);
 
        if ((target->reset_halt) && ((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0))
        {
@@ -1159,7 +1148,7 @@ int arm7_9_clear_halt(struct target *target)
 int arm7_9_soft_reset_halt(struct target *target)
 {
        struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
-       struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
+       struct arm *armv4_5 = &arm7_9->armv4_5_common;
        struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
        struct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
        int i;
@@ -1222,34 +1211,33 @@ int arm7_9_soft_reset_halt(struct target *target)
                arm7_9->change_to_arm(target, &r0_thumb, &pc_thumb);
        }
 
+       /* REVISIT likewise for bit 5 -- switch Jazelle-to-ARM */
+
        /* all register content is now invalid */
-       if ((retval = armv4_5_invalidate_core_regs(target)) != ERROR_OK)
-       {
-               return retval;
-       }
+       register_cache_invalidate(armv4_5->core_cache);
 
        /* SVC, ARM state, IRQ and FIQ disabled */
-       buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8, 0xd3);
-       armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
-       armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
+       uint32_t cpsr;
+
+       cpsr = buf_get_u32(armv4_5->cpsr->value, 0, 32);
+       cpsr &= ~0xff;
+       cpsr |= 0xd3;
+       arm_set_cpsr(armv4_5, cpsr);
+       armv4_5->cpsr->dirty = 1;
 
        /* start fetching from 0x0 */
        buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
        armv4_5->core_cache->reg_list[15].dirty = 1;
        armv4_5->core_cache->reg_list[15].valid = 1;
 
-       armv4_5->core_mode = ARMV4_5_MODE_SVC;
-       armv4_5->core_state = ARMV4_5_STATE_ARM;
-
-       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
-               return ERROR_FAIL;
-
        /* reset registers */
        for (i = 0; i <= 14; i++)
        {
-               buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).value, 0, 32, 0xffffffff);
-               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = 1;
-               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid = 1;
+               struct reg *r = arm_reg_current(armv4_5, i);
+
+               buf_set_u32(r->value, 0, 32, 0xffffffff);
+               r->dirty = 1;
+               r->valid = 1;
        }
 
        if ((retval = target_call_event_callbacks(target, TARGET_EVENT_HALTED)) != ERROR_OK)
@@ -1337,10 +1325,10 @@ static int arm7_9_debug_entry(struct target *target)
        uint32_t context[16];
        uint32_t* context_p[16];
        uint32_t r0_thumb, pc_thumb;
-       uint32_t cpsr;
+       uint32_t cpsr, cpsr_mask = 0;
        int retval;
        struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
-       struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
+       struct arm *armv4_5 = &arm7_9->armv4_5_common;
        struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
        struct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
 
@@ -1382,11 +1370,21 @@ static int arm7_9_debug_entry(struct target *target)
                LOG_DEBUG("target entered debug from Thumb state");
                /* Entered debug from Thumb mode */
                armv4_5->core_state = ARMV4_5_STATE_THUMB;
+               cpsr_mask = 1 << 5;
                arm7_9->change_to_arm(target, &r0_thumb, &pc_thumb);
-               LOG_DEBUG("r0_thumb: 0x%8.8" PRIx32 ", pc_thumb: 0x%8.8" PRIx32 "", r0_thumb, pc_thumb);
-       }
-       else
-       {
+               LOG_DEBUG("r0_thumb: 0x%8.8" PRIx32
+                       ", pc_thumb: 0x%8.8" PRIx32, r0_thumb, pc_thumb);
+       } else if (buf_get_u32(dbg_stat->value, 5, 1)) {
+               /* \todo Get some vaguely correct handling of Jazelle, if
+                * anyone ever uses it and full info becomes available.
+                * See ARM9EJS TRM B.7.1 for how to switch J->ARM; and
+                * B.7.3 for the reverse.  That'd be the bare minimum...
+                */
+               LOG_DEBUG("target entered debug from Jazelle state");
+               armv4_5->core_state = ARMV4_5_STATE_JAZELLE;
+               cpsr_mask = 1 << 24;
+               LOG_ERROR("Jazelle debug entry -- BROKEN!");
+       } else {
                LOG_DEBUG("target entered debug from ARM state");
                /* Entered debug from ARM mode */
                armv4_5->core_state = ARMV4_5_STATE_ARM;
@@ -1402,24 +1400,20 @@ static int arm7_9_debug_entry(struct target *target)
        if ((retval = jtag_execute_queue()) != ERROR_OK)
                return retval;
 
-       /* if the core has been executing in Thumb state, set the T bit */
-       if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
-               cpsr |= 0x20;
-
-       buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, cpsr);
-       armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 0;
-       armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
-
-       armv4_5->core_mode = cpsr & 0x1f;
+       /* Sync our CPSR copy with J or T bits EICE reported, but
+        * which we then erased by putting the core into ARM mode.
+        */
+       arm_set_cpsr(armv4_5, cpsr | cpsr_mask);
 
-       if (armv4_5_mode_to_number(armv4_5->core_mode) == -1)
+       if (!is_arm_mode(armv4_5->core_mode))
        {
                target->state = TARGET_UNKNOWN;
                LOG_ERROR("cpsr contains invalid mode value - communication failure");
                return ERROR_TARGET_FAILURE;
        }
 
-       LOG_DEBUG("target entered debug state in %s mode", armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)]);
+       LOG_DEBUG("target entered debug state in %s mode",
+                        arm_mode_name(armv4_5->core_mode));
 
        if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
        {
@@ -1437,40 +1431,33 @@ static int arm7_9_debug_entry(struct target *target)
        else
                context[15] -= arm7_9->dbgreq_adjust_pc * ((armv4_5->core_state == ARMV4_5_STATE_ARM) ? 4 : 2);
 
-       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
-               return ERROR_FAIL;
-
        for (i = 0; i <= 15; i++)
        {
+               struct reg *r = arm_reg_current(armv4_5, i);
+
                LOG_DEBUG("r%i: 0x%8.8" PRIx32 "", i, context[i]);
-               buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).value, 0, 32, context[i]);
-               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = 0;
-               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid = 1;
+
+               buf_set_u32(r->value, 0, 32, context[i]);
+               /* r0 and r15 (pc) have to be restored later */
+               r->dirty = (i == 0) || (i == 15);
+               r->valid = 1;
        }
 
        LOG_DEBUG("entered debug state at PC 0x%" PRIx32 "", context[15]);
 
-       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
-               return ERROR_FAIL;
-
        /* exceptions other than USR & SYS have a saved program status register */
-       if ((armv4_5->core_mode != ARMV4_5_MODE_USR) && (armv4_5->core_mode != ARMV4_5_MODE_SYS))
-       {
+       if (armv4_5->spsr) {
                uint32_t spsr;
                arm7_9->read_xpsr(target, &spsr, 1);
                if ((retval = jtag_execute_queue()) != ERROR_OK)
                {
                        return retval;
                }
-               buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32, spsr);
-               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).dirty = 0;
-               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).valid = 1;
+               buf_set_u32(armv4_5->spsr->value, 0, 32, spsr);
+               armv4_5->spsr->dirty = 0;
+               armv4_5->spsr->valid = 1;
        }
 
-       /* r0 and r15 (pc) have to be restored later */
-       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).valid;
-       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15).valid;
-
        if ((retval = jtag_execute_queue()) != ERROR_OK)
                return retval;
 
@@ -1494,7 +1481,7 @@ int arm7_9_full_context(struct target *target)
        int i;
        int retval;
        struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
-       struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
+       struct arm *armv4_5 = &arm7_9->armv4_5_common;
 
        LOG_DEBUG("-");
 
@@ -1504,7 +1491,7 @@ int arm7_9_full_context(struct target *target)
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
+       if (!is_arm_mode(armv4_5->core_mode))
                return ERROR_FAIL;
 
        /* iterate through processor modes (User, FIQ, IRQ, SVC, ABT, UND)
@@ -1530,7 +1517,8 @@ int arm7_9_full_context(struct target *target)
                        uint32_t tmp_cpsr;
 
                        /* change processor mode (and mask T bit) */
-                       tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
+                       tmp_cpsr = buf_get_u32(armv4_5->cpsr->value, 0, 8)
+                                       & 0xe0;
                        tmp_cpsr |= armv4_5_number_to_mode(i);
                        tmp_cpsr &= ~0x20;
                        arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
@@ -1561,7 +1549,9 @@ int arm7_9_full_context(struct target *target)
        }
 
        /* restore processor mode (mask T bit) */
-       arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
+       arm7_9->write_xpsr_im8(target,
+                       buf_get_u32(armv4_5->cpsr->value, 0, 8) & ~0x20,
+                       0, 0);
 
        if ((retval = jtag_execute_queue()) != ERROR_OK)
        {
@@ -1585,9 +1575,9 @@ int arm7_9_full_context(struct target *target)
 int arm7_9_restore_context(struct target *target)
 {
        struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
-       struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
+       struct arm *armv4_5 = &arm7_9->armv4_5_common;
        struct reg *reg;
-       struct armv4_5_core_reg *reg_arch_info;
+       struct arm_reg *reg_arch_info;
        enum armv4_5_mode current_mode = armv4_5->core_mode;
        int i, j;
        int dirty;
@@ -1604,7 +1594,7 @@ int arm7_9_restore_context(struct target *target)
        if (arm7_9->pre_restore_context)
                arm7_9->pre_restore_context(target);
 
-       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
+       if (!is_arm_mode(armv4_5->core_mode))
                return ERROR_FAIL;
 
        /* iterate through processor modes (User, FIQ, IRQ, SVC, ABT, UND)
@@ -1612,7 +1602,8 @@ int arm7_9_restore_context(struct target *target)
         */
        for (i = 0; i < 6; i++)
        {
-               LOG_DEBUG("examining %s mode", armv4_5_mode_strings[i]);
+               LOG_DEBUG("examining %s mode",
+                               arm_mode_name(armv4_5->core_mode));
                dirty = 0;
                mode_change = 0;
                /* check if there are dirty registers in the current mode
@@ -1654,7 +1645,8 @@ int arm7_9_restore_context(struct target *target)
                                uint32_t tmp_cpsr;
 
                                /* change processor mode (mask T bit) */
-                               tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
+                               tmp_cpsr = buf_get_u32(armv4_5->cpsr->value,
+                                               0, 8) & 0xe0;
                                tmp_cpsr |= armv4_5_number_to_mode(i);
                                tmp_cpsr &= ~0x20;
                                arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
@@ -1674,7 +1666,10 @@ int arm7_9_restore_context(struct target *target)
                                        num_regs++;
                                        reg->dirty = 0;
                                        reg->valid = 1;
-                                       LOG_DEBUG("writing register %i of mode %s with value 0x%8.8" PRIx32 "", j, armv4_5_mode_strings[i], regs[j]);
+                                       LOG_DEBUG("writing register %i mode %s "
+                                               "with value 0x%8.8" PRIx32, j,
+                                               arm_mode_name(armv4_5->core_mode),
+                                               regs[j]);
                                }
                        }
 
@@ -1693,24 +1688,27 @@ int arm7_9_restore_context(struct target *target)
                }
        }
 
-       if ((armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty == 0) && (armv4_5->core_mode != current_mode))
+       if (!armv4_5->cpsr->dirty && (armv4_5->core_mode != current_mode))
        {
                /* restore processor mode (mask T bit) */
                uint32_t tmp_cpsr;
 
-               tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
+               tmp_cpsr = buf_get_u32(armv4_5->cpsr->value, 0, 8) & 0xE0;
                tmp_cpsr |= armv4_5_number_to_mode(i);
                tmp_cpsr &= ~0x20;
                LOG_DEBUG("writing lower 8 bit of cpsr with value 0x%2.2x", (unsigned)(tmp_cpsr));
                arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
        }
-       else if (armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty == 1)
+       else if (armv4_5->cpsr->dirty)
        {
                /* CPSR has been changed, full restore necessary (mask T bit) */
-               LOG_DEBUG("writing cpsr with value 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
-               arm7_9->write_xpsr(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32) & ~0x20, 0);
-               armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 0;
-               armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
+               LOG_DEBUG("writing cpsr with value 0x%8.8" PRIx32,
+                               buf_get_u32(armv4_5->cpsr->value, 0, 32));
+               arm7_9->write_xpsr(target,
+                               buf_get_u32(armv4_5->cpsr->value, 0, 32)
+                                       & ~0x20, 0);
+               armv4_5->cpsr->dirty = 0;
+               armv4_5->cpsr->valid = 1;
        }
 
        /* restore PC */
@@ -1788,7 +1786,7 @@ void arm7_9_enable_breakpoints(struct target *target)
 int arm7_9_resume(struct target *target, int current, uint32_t address, int handle_breakpoints, int debug_execution)
 {
        struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
-       struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
+       struct arm *armv4_5 = &arm7_9->armv4_5_common;
        struct breakpoint *breakpoint = target->breakpoints;
        struct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
        int err, retval = ERROR_OK;
@@ -1924,7 +1922,7 @@ int arm7_9_resume(struct target *target, int current, uint32_t address, int hand
        if (!debug_execution)
        {
                /* registers are now invalid */
-               armv4_5_invalidate_core_regs(target);
+               register_cache_invalidate(armv4_5->core_cache);
                target->state = TARGET_RUNNING;
                if ((retval = target_call_event_callbacks(target, TARGET_EVENT_RESUMED)) != ERROR_OK)
                {
@@ -1948,7 +1946,7 @@ int arm7_9_resume(struct target *target, int current, uint32_t address, int hand
 void arm7_9_enable_eice_step(struct target *target, uint32_t next_pc)
 {
        struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
-       struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
+       struct arm *armv4_5 = &arm7_9->armv4_5_common;
        uint32_t current_pc;
        current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
 
@@ -2000,7 +1998,7 @@ void arm7_9_disable_eice_step(struct target *target)
 int arm7_9_step(struct target *target, int current, uint32_t address, int handle_breakpoints)
 {
        struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
-       struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
+       struct arm *armv4_5 = &arm7_9->armv4_5_common;
        struct breakpoint *breakpoint = NULL;
        int err, retval;
 
@@ -2067,7 +2065,7 @@ int arm7_9_step(struct target *target, int current, uint32_t address, int handle
        arm7_9->disable_single_step(target);
 
        /* registers are now invalid */
-       armv4_5_invalidate_core_regs(target);
+       register_cache_invalidate(armv4_5->core_cache);
 
        if (err != ERROR_OK)
        {
@@ -2090,30 +2088,29 @@ int arm7_9_step(struct target *target, int current, uint32_t address, int handle
        return err;
 }
 
-int arm7_9_read_core_reg(struct target *target, int num, enum armv4_5_mode mode)
+static int arm7_9_read_core_reg(struct target *target, struct reg *r,
+               int num, enum armv4_5_mode mode)
 {
        uint32_t* reg_p[16];
        uint32_t value;
        int retval;
+       struct arm_reg *areg = r->arch_info;
        struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
-       struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
+       struct arm *armv4_5 = &arm7_9->armv4_5_common;
 
-       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
+       if (!is_arm_mode(armv4_5->core_mode))
                return ERROR_FAIL;
-
-       enum armv4_5_mode reg_mode = ((struct armv4_5_core_reg*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info)->mode;
-
        if ((num < 0) || (num > 16))
                return ERROR_INVALID_ARGUMENTS;
 
        if ((mode != ARMV4_5_MODE_ANY)
                        && (mode != armv4_5->core_mode)
-                       && (reg_mode != ARMV4_5_MODE_ANY))
+                       && (areg->mode != ARMV4_5_MODE_ANY))
        {
                uint32_t tmp_cpsr;
 
                /* change processor mode (mask T bit) */
-               tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
+               tmp_cpsr = buf_get_u32(armv4_5->cpsr->value, 0, 8) & 0xE0;
                tmp_cpsr |= mode;
                tmp_cpsr &= ~0x20;
                arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
@@ -2131,10 +2128,7 @@ int arm7_9_read_core_reg(struct target *target, int num, enum armv4_5_mode mode)
                /* read a program status register
                 * if the register mode is MODE_ANY, we read the cpsr, otherwise a spsr
                 */
-               struct armv4_5_core_reg *arch_info = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info;
-               int spsr = (arch_info->mode == ARMV4_5_MODE_ANY) ? 0 : 1;
-
-               arm7_9->read_xpsr(target, &value, spsr);
+               arm7_9->read_xpsr(target, &value, areg->mode != ARMV4_5_MODE_ANY);
        }
 
        if ((retval = jtag_execute_queue()) != ERROR_OK)
@@ -2142,41 +2136,42 @@ int arm7_9_read_core_reg(struct target *target, int num, enum armv4_5_mode mode)
                return retval;
        }
 
-       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
-       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
-       buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).value, 0, 32, value);
+       r->valid = 1;
+       r->dirty = 0;
+       buf_set_u32(r->value, 0, 32, value);
 
        if ((mode != ARMV4_5_MODE_ANY)
                        && (mode != armv4_5->core_mode)
-                       && (reg_mode != ARMV4_5_MODE_ANY))      {
+                       && (areg->mode != ARMV4_5_MODE_ANY))    {
                /* restore processor mode (mask T bit) */
-               arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
+               arm7_9->write_xpsr_im8(target,
+                               buf_get_u32(armv4_5->cpsr->value, 0, 8)
+                                       & ~0x20, 0, 0);
        }
 
        return ERROR_OK;
 }
 
-int arm7_9_write_core_reg(struct target *target, int num, enum armv4_5_mode mode, uint32_t value)
+static int arm7_9_write_core_reg(struct target *target, struct reg *r,
+               int num, enum armv4_5_mode mode, uint32_t value)
 {
        uint32_t reg[16];
+       struct arm_reg *areg = r->arch_info;
        struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
-       struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
+       struct arm *armv4_5 = &arm7_9->armv4_5_common;
 
-       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
+       if (!is_arm_mode(armv4_5->core_mode))
                return ERROR_FAIL;
-
-       enum armv4_5_mode reg_mode = ((struct armv4_5_core_reg*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info)->mode;
-
        if ((num < 0) || (num > 16))
                return ERROR_INVALID_ARGUMENTS;
 
        if ((mode != ARMV4_5_MODE_ANY)
                        && (mode != armv4_5->core_mode)
-                       && (reg_mode != ARMV4_5_MODE_ANY))      {
+                       && (areg->mode != ARMV4_5_MODE_ANY))    {
                uint32_t tmp_cpsr;
 
                /* change processor mode (mask T bit) */
-               tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
+               tmp_cpsr = buf_get_u32(armv4_5->cpsr->value, 0, 8) & 0xE0;
                tmp_cpsr |= mode;
                tmp_cpsr &= ~0x20;
                arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
@@ -2194,8 +2189,7 @@ int arm7_9_write_core_reg(struct target *target, int num, enum armv4_5_mode mode
                /* write a program status register
                * if the register mode is MODE_ANY, we write the cpsr, otherwise a spsr
                */
-               struct armv4_5_core_reg *arch_info = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info;
-               int spsr = (arch_info->mode == ARMV4_5_MODE_ANY) ? 0 : 1;
+               int spsr = (areg->mode != ARMV4_5_MODE_ANY);
 
                /* if we're writing the CPSR, mask the T bit */
                if (!spsr)
@@ -2204,14 +2198,16 @@ int arm7_9_write_core_reg(struct target *target, int num, enum armv4_5_mode mode
                arm7_9->write_xpsr(target, value, spsr);
        }
 
-       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
-       ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
+       r->valid = 1;
+       r->dirty = 0;
 
        if ((mode != ARMV4_5_MODE_ANY)
                        && (mode != armv4_5->core_mode)
-                       && (reg_mode != ARMV4_5_MODE_ANY))      {
+                       && (areg->mode != ARMV4_5_MODE_ANY))    {
                /* restore processor mode (mask T bit) */
-               arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
+               arm7_9->write_xpsr_im8(target,
+                               buf_get_u32(armv4_5->cpsr->value, 0, 8)
+                                       & ~0x20, 0, 0);
        }
 
        return jtag_execute_queue();
@@ -2220,7 +2216,7 @@ int arm7_9_write_core_reg(struct target *target, int num, enum armv4_5_mode mode
 int arm7_9_read_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
 {
        struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
-       struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
+       struct arm *armv4_5 = &arm7_9->armv4_5_common;
        uint32_t reg[16];
        uint32_t num_accesses = 0;
        int thisrun_accesses;
@@ -2367,11 +2363,14 @@ int arm7_9_read_memory(struct target *target, uint32_t address, uint32_t size, u
                        break;
        }
 
-       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
+       if (!is_arm_mode(armv4_5->core_mode))
                return ERROR_FAIL;
 
-       for (i = 0; i <= last_reg; i++)
-               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid;
+       for (i = 0; i <= last_reg; i++) {
+               struct reg *r = arm_reg_current(armv4_5, i);
+
+               r->dirty = r->valid;
+       }
 
        arm7_9->read_xpsr(target, &cpsr, 0);
        if ((retval = jtag_execute_queue()) != ERROR_OK)
@@ -2384,7 +2383,9 @@ int arm7_9_read_memory(struct target *target, uint32_t address, uint32_t size, u
        {
                LOG_WARNING("memory read caused data abort (address: 0x%8.8" PRIx32 ", size: 0x%" PRIx32 ", count: 0x%" PRIx32 ")", address, size, count);
 
-               arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
+               arm7_9->write_xpsr_im8(target,
+                               buf_get_u32(armv4_5->cpsr->value, 0, 8)
+                                       & ~0x20, 0, 0);
 
                return ERROR_TARGET_DATA_ABORT;
        }
@@ -2395,7 +2396,7 @@ int arm7_9_read_memory(struct target *target, uint32_t address, uint32_t size, u
 int arm7_9_write_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
 {
        struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
-       struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
+       struct arm *armv4_5 = &arm7_9->armv4_5_common;
        struct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
 
        uint32_t reg[16];
@@ -2550,11 +2551,14 @@ int arm7_9_write_memory(struct target *target, uint32_t address, uint32_t size,
        buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1);
        embeddedice_store_reg(dbg_ctrl);
 
-       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
+       if (!is_arm_mode(armv4_5->core_mode))
                return ERROR_FAIL;
 
-       for (i = 0; i <= last_reg; i++)
-               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid;
+       for (i = 0; i <= last_reg; i++) {
+               struct reg *r = arm_reg_current(armv4_5, i);
+
+               r->dirty = r->valid;
+       }
 
        arm7_9->read_xpsr(target, &cpsr, 0);
        if ((retval = jtag_execute_queue()) != ERROR_OK)
@@ -2567,7 +2571,9 @@ int arm7_9_write_memory(struct target *target, uint32_t address, uint32_t size,
        {
                LOG_WARNING("memory write caused data abort (address: 0x%8.8" PRIx32 ", size: 0x%" PRIx32 ", count: 0x%" PRIx32 ")", address, size, count);
 
-               arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
+               arm7_9->write_xpsr_im8(target,
+                               buf_get_u32(armv4_5->cpsr->value, 0, 8)
+                                       & ~0x20, 0, 0);
 
                return ERROR_TARGET_DATA_ABORT;
        }
@@ -2641,7 +2647,13 @@ static const uint32_t dcc_code[] =
        0xeafffff9      /*    b   w                   */
 };
 
-int armv4_5_run_algorithm_inner(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, int (*run_it)(struct target *target, uint32_t exit_point, int timeout_ms, void *arch_info));
+extern int armv4_5_run_algorithm_inner(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,
+       int (*run_it)(struct target *target, uint32_t exit_point,
+                       int timeout_ms, void *arch_info));
 
 int arm7_9_bulk_write_memory(struct target *target, uint32_t address, uint32_t count, uint8_t *buffer)
 {
@@ -2691,7 +2703,9 @@ int arm7_9_bulk_write_memory(struct target *target, uint32_t address, uint32_t c
        dcc_count = count;
        dcc_buffer = buffer;
        retval = armv4_5_run_algorithm_inner(target, 0, NULL, 1, reg_params,
-                       arm7_9->dcc_working_area->address, arm7_9->dcc_working_area->address + 6*4, 20*1000, &armv4_5_info, arm7_9_dcc_completion);
+                       arm7_9->dcc_working_area->address,
+                               arm7_9->dcc_working_area->address + 6*4,
+                       20*1000, &armv4_5_info, arm7_9_dcc_completion);
 
        if (retval == ERROR_OK)
        {
@@ -2743,216 +2757,59 @@ int arm7_9_examine(struct target *target)
        return retval;
 }
 
-
-COMMAND_HANDLER(handle_arm7_9_write_xpsr_command)
-{
-       uint32_t value;
-       int spsr;
-       int retval;
-       struct target *target = get_current_target(cmd_ctx);
-       struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
-
-       if (!is_arm7_9(arm7_9))
-       {
-               command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
-               return ERROR_TARGET_INVALID;
-       }
-
-       if (target->state != TARGET_HALTED)
-       {
-               command_print(cmd_ctx, "can't write registers while running");
-               return ERROR_FAIL;
-       }
-
-       if (argc < 2)
-       {
-               command_print(cmd_ctx, "usage: write_xpsr <value> <not cpsr | spsr>");
-               return ERROR_FAIL;
-       }
-
-       COMMAND_PARSE_NUMBER(u32, args[0], value);
-       COMMAND_PARSE_NUMBER(int, args[1], spsr);
-
-       /* if we're writing the CPSR, mask the T bit */
-       if (!spsr)
-               value &= ~0x20;
-
-       arm7_9->write_xpsr(target, value, spsr);
-       if ((retval = jtag_execute_queue()) != ERROR_OK)
-       {
-               LOG_ERROR("JTAG error while writing to xpsr");
-               return retval;
-       }
-
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_arm7_9_write_xpsr_im8_command)
-{
-       uint32_t value;
-       int rotate;
-       int spsr;
-       int retval;
-       struct target *target = get_current_target(cmd_ctx);
-       struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
-
-       if (!is_arm7_9(arm7_9))
-       {
-               command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
-               return ERROR_TARGET_INVALID;
-       }
-
-       if (target->state != TARGET_HALTED)
-       {
-               command_print(cmd_ctx, "can't write registers while running");
-               return ERROR_FAIL;
-       }
-
-       if (argc < 3)
-       {
-               command_print(cmd_ctx, "usage: write_xpsr_im8 <im8> <rotate> <not cpsr | spsr>");
-               return ERROR_FAIL;
-       }
-
-       COMMAND_PARSE_NUMBER(u32, args[0], value);
-       COMMAND_PARSE_NUMBER(int, args[1], rotate);
-       COMMAND_PARSE_NUMBER(int, args[2], spsr);
-
-       arm7_9->write_xpsr_im8(target, value, rotate, spsr);
-       if ((retval = jtag_execute_queue()) != ERROR_OK)
-       {
-               LOG_ERROR("JTAG error while writing 8-bit immediate to xpsr");
-               return retval;
-       }
-
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_arm7_9_write_core_reg_command)
-{
-       uint32_t value;
-       uint32_t mode;
-       int num;
-       struct target *target = get_current_target(cmd_ctx);
-       struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
-
-       if (!is_arm7_9(arm7_9))
-       {
-               command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
-               return ERROR_TARGET_INVALID;
-       }
-
-       if (target->state != TARGET_HALTED)
-       {
-               command_print(cmd_ctx, "can't write registers while running");
-               return ERROR_FAIL;
-       }
-
-       if (argc < 3)
-       {
-               command_print(cmd_ctx, "usage: write_core_reg <num> <mode> <value>");
-               return ERROR_FAIL;
-       }
-
-       COMMAND_PARSE_NUMBER(int, args[0], num);
-       COMMAND_PARSE_NUMBER(u32, args[1], mode);
-       COMMAND_PARSE_NUMBER(u32, args[2], value);
-
-       return arm7_9_write_core_reg(target, num, mode, value);
-}
-
 COMMAND_HANDLER(handle_arm7_9_dbgrq_command)
 {
-       struct target *target = get_current_target(cmd_ctx);
+       struct target *target = get_current_target(CMD_CTX);
        struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
 
        if (!is_arm7_9(arm7_9))
        {
-               command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
+               command_print(CMD_CTX, "current target isn't an ARM7/ARM9 target");
                return ERROR_TARGET_INVALID;
        }
 
-       if (argc > 0)
-       {
-               if (strcmp("enable", args[0]) == 0)
-               {
-                       arm7_9->use_dbgrq = 1;
-               }
-               else if (strcmp("disable", args[0]) == 0)
-               {
-                       arm7_9->use_dbgrq = 0;
-               }
-               else
-               {
-                       command_print(cmd_ctx, "usage: arm7_9 dbgrq <enable | disable>");
-               }
-       }
+       if (CMD_ARGC > 0)
+               COMMAND_PARSE_ENABLE(CMD_ARGV[0],arm7_9->use_dbgrq);
 
-       command_print(cmd_ctx, "use of EmbeddedICE dbgrq instead of breakpoint for target halt %s", (arm7_9->use_dbgrq) ? "enabled" : "disabled");
+       command_print(CMD_CTX, "use of EmbeddedICE dbgrq instead of breakpoint for target halt %s", (arm7_9->use_dbgrq) ? "enabled" : "disabled");
 
        return ERROR_OK;
 }
 
 COMMAND_HANDLER(handle_arm7_9_fast_memory_access_command)
 {
-       struct target *target = get_current_target(cmd_ctx);
+       struct target *target = get_current_target(CMD_CTX);
        struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
 
        if (!is_arm7_9(arm7_9))
        {
-               command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
+               command_print(CMD_CTX, "current target isn't an ARM7/ARM9 target");
                return ERROR_TARGET_INVALID;
        }
 
-       if (argc > 0)
-       {
-               if (strcmp("enable", args[0]) == 0)
-               {
-                       arm7_9->fast_memory_access = 1;
-               }
-               else if (strcmp("disable", args[0]) == 0)
-               {
-                       arm7_9->fast_memory_access = 0;
-               }
-               else
-               {
-                       command_print(cmd_ctx, "usage: arm7_9 fast_memory_access <enable | disable>");
-               }
-       }
+       if (CMD_ARGC > 0)
+               COMMAND_PARSE_ENABLE(CMD_ARGV[0], arm7_9->fast_memory_access);
 
-       command_print(cmd_ctx, "fast memory access is %s", (arm7_9->fast_memory_access) ? "enabled" : "disabled");
+       command_print(CMD_CTX, "fast memory access is %s", (arm7_9->fast_memory_access) ? "enabled" : "disabled");
 
        return ERROR_OK;
 }
 
 COMMAND_HANDLER(handle_arm7_9_dcc_downloads_command)
 {
-       struct target *target = get_current_target(cmd_ctx);
+       struct target *target = get_current_target(CMD_CTX);
        struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
 
        if (!is_arm7_9(arm7_9))
        {
-               command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
+               command_print(CMD_CTX, "current target isn't an ARM7/ARM9 target");
                return ERROR_TARGET_INVALID;
        }
 
-       if (argc > 0)
-       {
-               if (strcmp("enable", args[0]) == 0)
-               {
-                       arm7_9->dcc_downloads = 1;
-               }
-               else if (strcmp("disable", args[0]) == 0)
-               {
-                       arm7_9->dcc_downloads = 0;
-               }
-               else
-               {
-                       command_print(cmd_ctx, "usage: arm7_9 dcc_downloads <enable | disable>");
-               }
-       }
+       if (CMD_ARGC > 0)
+               COMMAND_PARSE_ENABLE(CMD_ARGV[0], arm7_9->dcc_downloads);
 
-       command_print(cmd_ctx, "dcc downloads are %s", (arm7_9->dcc_downloads) ? "enabled" : "disabled");
+       command_print(CMD_CTX, "dcc downloads are %s", (arm7_9->dcc_downloads) ? "enabled" : "disabled");
 
        return ERROR_OK;
 }
@@ -2971,8 +2828,8 @@ int arm7_9_init_arch_info(struct target *target, struct arm7_9_common *arm7_9)
 
        arm7_9->wp_available_max = 2;
 
-       arm7_9->fast_memory_access = fast_and_dangerous;
-       arm7_9->dcc_downloads = fast_and_dangerous;
+       arm7_9->fast_memory_access = false;
+       arm7_9->dcc_downloads = false;
 
        armv4_5->arch_info = arm7_9;
        armv4_5->read_core_reg = arm7_9_read_core_reg;
@@ -2986,40 +2843,44 @@ int arm7_9_init_arch_info(struct target *target, struct arm7_9_common *arm7_9)
                        1, 1, target);
 }
 
-int arm7_9_register_commands(struct command_context *cmd_ctx)
-{
-       struct command *arm7_9_cmd;
-
-       arm7_9_cmd = register_command(cmd_ctx, NULL, "arm7_9",
-                       NULL, COMMAND_ANY, "arm7/9 specific commands");
-
-       register_command(cmd_ctx, arm7_9_cmd, "write_xpsr",
-                       handle_arm7_9_write_xpsr_command, COMMAND_EXEC,
-                       "write program status register <value> <not cpsr | spsr>");
-       register_command(cmd_ctx, arm7_9_cmd, "write_xpsr_im8",
-                       handle_arm7_9_write_xpsr_im8_command, COMMAND_EXEC,
-                       "write program status register "
-                       "<8bit immediate> <rotate> <not cpsr | spsr>");
-
-       register_command(cmd_ctx, arm7_9_cmd, "write_core_reg",
-                       handle_arm7_9_write_core_reg_command, COMMAND_EXEC,
-                       "write core register <num> <mode> <value>");
-
-       register_command(cmd_ctx, arm7_9_cmd, "dbgrq",
-                       handle_arm7_9_dbgrq_command, COMMAND_ANY,
-                       "use EmbeddedICE dbgrq instead of breakpoint "
-                       "for target halt requests <enable | disable>");
-       register_command(cmd_ctx, arm7_9_cmd, "fast_memory_access",
-                       handle_arm7_9_fast_memory_access_command, COMMAND_ANY,
-                       "use fast memory accesses instead of slower "
-                       "but potentially safer accesses <enable | disable>");
-       register_command(cmd_ctx, arm7_9_cmd, "dcc_downloads",
-                       handle_arm7_9_dcc_downloads_command, COMMAND_ANY,
-                       "use DCC downloads for larger memory writes <enable | disable>");
-
-       armv4_5_register_commands(cmd_ctx);
-
-       etm_register_commands(cmd_ctx);
-
-       return ERROR_OK;
-}
+static const struct command_registration arm7_9_any_command_handlers[] = {
+       {
+               "dbgrq",
+               .handler = &handle_arm7_9_dbgrq_command,
+               .mode = COMMAND_ANY,
+               .usage = "<enable|disable>",
+               .help = "use EmbeddedICE dbgrq instead of breakpoint "
+                       "for target halt requests",
+       },
+       {
+               "fast_memory_access",
+               .handler = &handle_arm7_9_fast_memory_access_command,
+               .mode = COMMAND_ANY,
+               .usage = "<enable|disable>",
+               .help = "use fast memory accesses instead of slower "
+                       "but potentially safer accesses",
+       },
+       {
+               "dcc_downloads",
+               .handler = &handle_arm7_9_dcc_downloads_command,
+               .mode = COMMAND_ANY,
+               .usage = "<enable | disable>",
+               .help = "use DCC downloads for larger memory writes",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+const struct command_registration arm7_9_command_handlers[] = {
+       {
+               .chain = arm_command_handlers,
+       },
+       {
+               .chain = etm_command_handlers,
+       },
+       {
+               .name = "arm7_9",
+               .mode = COMMAND_ANY,
+               .help = "arm7/9 specific commands",
+               .chain = arm7_9_any_command_handlers,
+       },
+       COMMAND_REGISTRATION_DONE
+};