target: create/use register_cache_invalidate()
[openocd.git] / src / target / xscale.c
index 705c2f0a42e84709825da260f3f5eae8a7e11fd5..f13366ac0b95f331c32d86531b7742b2db0bea71 100644 (file)
 #include "config.h"
 #endif
 
+#include "breakpoints.h"
 #include "xscale.h"
 #include "target_type.h"
-#include "arm7_9_common.h"
+#include "arm_jtag.h"
 #include "arm_simulator.h"
 #include "arm_disassembler.h"
 #include "time_support.h"
+#include "register.h"
 #include "image.h"
 
 
@@ -42,7 +44,7 @@
  *  Intel XScale® Core Developer’s Manual, January 2004
  *             Order Number: 273473-002
  *     This has a chapter detailing debug facilities, and punts some
- *     details to chip-specific microarchitecture documentats.
+ *     details to chip-specific microarchitecture documents.
  *
  *  Hot-Debug for Intel XScale® Core Debug White Paper, May 2005
  *             Document Number: 273539-005
 
 
 /* forward declarations */
-static int xscale_resume(struct target_s *, int current,
+static int xscale_resume(struct target *, int current,
        uint32_t address, int handle_breakpoints, int debug_execution);
-static int xscale_debug_entry(target_t *);
-static int xscale_restore_context(target_t *);
-static int xscale_get_reg(reg_t *reg);
-static int xscale_set_reg(reg_t *reg, uint8_t *buf);
-static int xscale_set_breakpoint(struct target_s *, breakpoint_t *);
-static int xscale_set_watchpoint(struct target_s *, watchpoint_t *);
-static int xscale_unset_breakpoint(struct target_s *, breakpoint_t *);
-static int xscale_read_trace(target_t *);
-
+static int xscale_debug_entry(struct target *);
+static int xscale_restore_context(struct target *);
+static int xscale_get_reg(struct reg *reg);
+static int xscale_set_reg(struct reg *reg, uint8_t *buf);
+static int xscale_set_breakpoint(struct target *, struct breakpoint *);
+static int xscale_set_watchpoint(struct target *, struct watchpoint *);
+static int xscale_unset_breakpoint(struct target *, struct breakpoint *);
+static int xscale_read_trace(struct target *);
+
+
+/* This XScale "debug handler" is loaded into the processor's
+ * mini-ICache, which is 2K of code writable only via JTAG.
+ *
+ * FIXME  the OpenOCD "bin2char" utility currently doesn't handle
+ * binary files cleanly.  It's string oriented, and terminates them
+ * with a NUL character.  Better would be to generate the constants
+ * and let other code decide names, scoping, and other housekeeping.
+ */
+static /* unsigned const char xscale_debug_handler[] = ... */
+#include "xscale_debug.h"
 
 static char *const xscale_reg_list[] =
 {
@@ -95,7 +108,7 @@ static char *const xscale_reg_list[] =
        "XSCALE_TXRXCTRL",
 };
 
-static const xscale_reg_t xscale_reg_arch_info[] =
+static const struct xscale_reg xscale_reg_arch_info[] =
 {
        {XSCALE_MAINID, NULL},
        {XSCALE_CACHETYPE, NULL},
@@ -121,10 +134,8 @@ static const xscale_reg_t xscale_reg_arch_info[] =
        {-1, NULL}, /* TXRXCTRL implicit access via JTAG */
 };
 
-static int xscale_reg_arch_type = -1;
-
 /* convenience wrapper to access XScale specific registers */
-static int xscale_set_reg_u32(reg_t *reg, uint32_t value)
+static int xscale_set_reg_u32(struct reg *reg, uint32_t value)
 {
        uint8_t buf[4];
 
@@ -133,67 +144,45 @@ static int xscale_set_reg_u32(reg_t *reg, uint32_t value)
        return xscale_set_reg(reg, buf);
 }
 
+static const char xscale_not[] = "target is not an XScale";
 
-static int xscale_get_arch_pointers(target_t *target,
-               armv4_5_common_t **armv4_5_p, xscale_common_t **xscale_p)
+static int xscale_verify_pointer(struct command_context *cmd_ctx,
+               struct xscale_common *xscale)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
-
-       if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
-       {
-               LOG_ERROR("target isn't an XScale target");
-               return -1;
-       }
-
-       if (xscale->common_magic != XSCALE_COMMON_MAGIC)
-       {
-               LOG_ERROR("target isn't an XScale target");
-               return -1;
+       if (xscale->common_magic != XSCALE_COMMON_MAGIC) {
+               command_print(cmd_ctx, xscale_not);
+               return ERROR_TARGET_INVALID;
        }
-
-       *armv4_5_p = armv4_5;
-       *xscale_p = xscale;
-
        return ERROR_OK;
 }
 
-static int xscale_jtag_set_instr(jtag_tap_t *tap, uint32_t new_instr)
+static int xscale_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr)
 {
        if (tap == NULL)
                return ERROR_FAIL;
 
        if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr)
        {
-               scan_field_t field;
+               struct scan_field field;
+               uint8_t scratch[4];
 
+               memset(&field, 0, sizeof field);
                field.tap = tap;
                field.num_bits = tap->ir_length;
-               field.out_value = calloc(CEIL(field.num_bits, 8), 1);
+               field.out_value = scratch;
                buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
 
-               uint8_t tmp[4];
-               field.in_value = tmp;
-
                jtag_add_ir_scan(1, &field, jtag_get_end_state());
-
-               /* FIX!!!! isn't this check superfluous? verify_ircapture handles this? */
-               jtag_check_value_mask(&field, tap->expected, tap->expected_mask);
-
-               free(field.out_value);
        }
 
        return ERROR_OK;
 }
 
-static int xscale_read_dcsr(target_t *target)
+static int xscale_read_dcsr(struct target *target)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
-
+       struct xscale_common *xscale = target_to_xscale(target);
        int retval;
-
-       scan_field_t fields[3];
+       struct scan_field fields[3];
        uint8_t field0 = 0x0;
        uint8_t field0_check_value = 0x2;
        uint8_t field0_check_mask = 0x7;
@@ -202,23 +191,24 @@ static int xscale_read_dcsr(target_t *target)
        uint8_t field2_check_mask = 0x1;
 
        jtag_set_end_state(TAP_DRPAUSE);
-       xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dcsr);
+       xscale_jtag_set_instr(target->tap, XSCALE_SELDCSR);
 
        buf_set_u32(&field0, 1, 1, xscale->hold_rst);
        buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
 
-       fields[0].tap = xscale->jtag_info.tap;
+       memset(&fields, 0, sizeof fields);
+
+       fields[0].tap = target->tap;
        fields[0].num_bits = 3;
        fields[0].out_value = &field0;
        uint8_t tmp;
        fields[0].in_value = &tmp;
 
-       fields[1].tap = xscale->jtag_info.tap;
+       fields[1].tap = target->tap;
        fields[1].num_bits = 32;
-       fields[1].out_value = NULL;
        fields[1].in_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
 
-       fields[2].tap = xscale->jtag_info.tap;
+       fields[2].tap = target->tap;
        fields[2].num_bits = 1;
        fields[2].out_value = &field2;
        uint8_t tmp2;
@@ -261,18 +251,14 @@ static void xscale_getbuf(jtag_callback_data_t arg)
        *((uint32_t *)in) = buf_get_u32(in, 0, 32);
 }
 
-static int xscale_receive(target_t *target, uint32_t *buffer, int num_words)
+static int xscale_receive(struct target *target, uint32_t *buffer, int num_words)
 {
        if (num_words == 0)
                return ERROR_INVALID_ARGUMENTS;
 
        int retval = ERROR_OK;
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
-
        tap_state_t path[3];
-       scan_field_t fields[3];
-
+       struct scan_field fields[3];
        uint8_t *field0 = malloc(num_words * 1);
        uint8_t field0_check_value = 0x2;
        uint8_t field0_check_mask = 0x6;
@@ -281,35 +267,29 @@ static int xscale_receive(target_t *target, uint32_t *buffer, int num_words)
        uint8_t field2_check_mask = 0x1;
        int words_done = 0;
        int words_scheduled = 0;
-
        int i;
 
        path[0] = TAP_DRSELECT;
        path[1] = TAP_DRCAPTURE;
        path[2] = TAP_DRSHIFT;
 
-       fields[0].tap = xscale->jtag_info.tap;
+       memset(&fields, 0, sizeof fields);
+
+       fields[0].tap = target->tap;
        fields[0].num_bits = 3;
-       fields[0].out_value = NULL;
-       fields[0].in_value = NULL;
        fields[0].check_value = &field0_check_value;
        fields[0].check_mask = &field0_check_mask;
 
-       fields[1].tap = xscale->jtag_info.tap;
+       fields[1].tap = target->tap;
        fields[1].num_bits = 32;
-       fields[1].out_value = NULL;
-       fields[1].check_value = NULL;
-       fields[1].check_mask = NULL;
 
-       fields[2].tap = xscale->jtag_info.tap;
+       fields[2].tap = target->tap;
        fields[2].num_bits = 1;
-       fields[2].out_value = NULL;
-       fields[2].in_value = NULL;
        fields[2].check_value = &field2_check_value;
        fields[2].check_mask = &field2_check_mask;
 
        jtag_set_end_state(TAP_IDLE);
-       xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dbgtx);
+       xscale_jtag_set_instr(target->tap, XSCALE_DBGTX);
        jtag_add_runtest(1, jtag_get_end_state()); /* ensures that we're in the TAP_IDLE state as the above could be a no-op */
 
        /* repeat until all words have been collected */
@@ -375,17 +355,14 @@ static int xscale_receive(target_t *target, uint32_t *buffer, int num_words)
        return retval;
 }
 
-static int xscale_read_tx(target_t *target, int consume)
+static int xscale_read_tx(struct target *target, int consume)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
        tap_state_t path[3];
        tap_state_t noconsume_path[6];
-
        int retval;
        struct timeval timeout, now;
-
-       scan_field_t fields[3];
+       struct scan_field fields[3];
        uint8_t field0_in = 0x0;
        uint8_t field0_check_value = 0x2;
        uint8_t field0_check_mask = 0x6;
@@ -394,7 +371,7 @@ static int xscale_read_tx(target_t *target, int consume)
 
        jtag_set_end_state(TAP_IDLE);
 
-       xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dbgtx);
+       xscale_jtag_set_instr(target->tap, XSCALE_DBGTX);
 
        path[0] = TAP_DRSELECT;
        path[1] = TAP_DRCAPTURE;
@@ -407,19 +384,18 @@ static int xscale_read_tx(target_t *target, int consume)
        noconsume_path[4] = TAP_DREXIT2;
        noconsume_path[5] = TAP_DRSHIFT;
 
-       fields[0].tap = xscale->jtag_info.tap;
+       memset(&fields, 0, sizeof fields);
+
+       fields[0].tap = target->tap;
        fields[0].num_bits = 3;
-       fields[0].out_value = NULL;
        fields[0].in_value = &field0_in;
 
-       fields[1].tap = xscale->jtag_info.tap;
+       fields[1].tap = target->tap;
        fields[1].num_bits = 32;
-       fields[1].out_value = NULL;
        fields[1].in_value = xscale->reg_cache->reg_list[XSCALE_TX].value;
 
-       fields[2].tap = xscale->jtag_info.tap;
+       fields[2].tap = target->tap;
        fields[2].num_bits = 1;
-       fields[2].out_value = NULL;
        uint8_t tmp;
        fields[2].in_value = &tmp;
 
@@ -477,15 +453,12 @@ static int xscale_read_tx(target_t *target, int consume)
        return ERROR_OK;
 }
 
-static int xscale_write_rx(target_t *target)
+static int xscale_write_rx(struct target *target)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
-
+       struct xscale_common *xscale = target_to_xscale(target);
        int retval;
        struct timeval timeout, now;
-
-       scan_field_t fields[3];
+       struct scan_field fields[3];
        uint8_t field0_out = 0x0;
        uint8_t field0_in = 0x0;
        uint8_t field0_check_value = 0x2;
@@ -496,19 +469,20 @@ static int xscale_write_rx(target_t *target)
 
        jtag_set_end_state(TAP_IDLE);
 
-       xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dbgrx);
+       xscale_jtag_set_instr(target->tap, XSCALE_DBGRX);
 
-       fields[0].tap = xscale->jtag_info.tap;
+       memset(&fields, 0, sizeof fields);
+
+       fields[0].tap = target->tap;
        fields[0].num_bits = 3;
        fields[0].out_value = &field0_out;
        fields[0].in_value = &field0_in;
 
-       fields[1].tap = xscale->jtag_info.tap;
+       fields[1].tap = target->tap;
        fields[1].num_bits = 32;
        fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_RX].value;
-       fields[1].in_value = NULL;
 
-       fields[2].tap = xscale->jtag_info.tap;
+       fields[2].tap = target->tap;
        fields[2].num_bits = 1;
        fields[2].out_value = &field2;
        uint8_t tmp;
@@ -565,20 +539,16 @@ static int xscale_write_rx(target_t *target)
 }
 
 /* send count elements of size byte to the debug handler */
-static int xscale_send(target_t *target, uint8_t *buffer, int count, int size)
+static int xscale_send(struct target *target, uint8_t *buffer, int count, int size)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
        uint32_t t[3];
        int bits[3];
-
        int retval;
-
        int done_count = 0;
 
        jtag_set_end_state(TAP_IDLE);
 
-       xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dbgrx);
+       xscale_jtag_set_instr(target->tap, XSCALE_DBGRX);
 
        bits[0]=3;
        t[0]=0;
@@ -613,9 +583,9 @@ static int xscale_send(target_t *target, uint8_t *buffer, int count, int size)
                        break;
                default:
                        LOG_ERROR("BUG: size neither 4, 2 nor 1");
-                       exit(-1);
+                       return ERROR_INVALID_ARGUMENTS;
                }
-               jtag_add_dr_out(xscale->jtag_info.tap,
+               jtag_add_dr_out(target->tap,
                                3,
                                bits,
                                t,
@@ -632,23 +602,19 @@ static int xscale_send(target_t *target, uint8_t *buffer, int count, int size)
        return ERROR_OK;
 }
 
-static int xscale_send_u32(target_t *target, uint32_t value)
+static int xscale_send_u32(struct target *target, uint32_t value)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
 
        buf_set_u32(xscale->reg_cache->reg_list[XSCALE_RX].value, 0, 32, value);
        return xscale_write_rx(target);
 }
 
-static int xscale_write_dcsr(target_t *target, int hold_rst, int ext_dbg_brk)
+static int xscale_write_dcsr(struct target *target, int hold_rst, int ext_dbg_brk)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
-
+       struct xscale_common *xscale = target_to_xscale(target);
        int retval;
-
-       scan_field_t fields[3];
+       struct scan_field fields[3];
        uint8_t field0 = 0x0;
        uint8_t field0_check_value = 0x2;
        uint8_t field0_check_mask = 0x7;
@@ -663,23 +629,24 @@ static int xscale_write_dcsr(target_t *target, int hold_rst, int ext_dbg_brk)
                xscale->external_debug_break = ext_dbg_brk;
 
        jtag_set_end_state(TAP_IDLE);
-       xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dcsr);
+       xscale_jtag_set_instr(target->tap, XSCALE_SELDCSR);
 
        buf_set_u32(&field0, 1, 1, xscale->hold_rst);
        buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
 
-       fields[0].tap = xscale->jtag_info.tap;
+       memset(&fields, 0, sizeof fields);
+
+       fields[0].tap = target->tap;
        fields[0].num_bits = 3;
        fields[0].out_value = &field0;
        uint8_t tmp;
        fields[0].in_value = &tmp;
 
-       fields[1].tap = xscale->jtag_info.tap;
+       fields[1].tap = target->tap;
        fields[1].num_bits = 32;
        fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
-       fields[1].in_value = NULL;
 
-       fields[2].tap = xscale->jtag_info.tap;
+       fields[2].tap = target->tap;
        fields[2].num_bits = 1;
        fields[2].out_value = &field2;
        uint8_t tmp2;
@@ -705,53 +672,50 @@ static int xscale_write_dcsr(target_t *target, int hold_rst, int ext_dbg_brk)
 /* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */
 static unsigned int parity (unsigned int v)
 {
-       unsigned int ov = v;
+       // unsigned int ov = v;
        v ^= v >> 16;
        v ^= v >> 8;
        v ^= v >> 4;
        v &= 0xf;
-       LOG_DEBUG("parity of 0x%x is %i", ov, (0x6996 >> v) & 1);
+       // LOG_DEBUG("parity of 0x%x is %i", ov, (0x6996 >> v) & 1);
        return (0x6996 >> v) & 1;
 }
 
-static int xscale_load_ic(target_t *target, int mini, uint32_t va, uint32_t buffer[8])
+static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8])
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
        uint8_t packet[4];
        uint8_t cmd;
        int word;
-
-       scan_field_t fields[2];
+       struct scan_field fields[2];
 
        LOG_DEBUG("loading miniIC at 0x%8.8" PRIx32 "", va);
 
+       /* LDIC into IR */
        jtag_set_end_state(TAP_IDLE);
-       xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.ldic); /* LDIC */
-
-       /* CMD is b010 for Main IC and b011 for Mini IC */
-       if (mini)
-               buf_set_u32(&cmd, 0, 3, 0x3);
-       else
-               buf_set_u32(&cmd, 0, 3, 0x2);
+       xscale_jtag_set_instr(target->tap, XSCALE_LDIC);
 
-       buf_set_u32(&cmd, 3, 3, 0x0);
+       /* CMD is b011 to load a cacheline into the Mini ICache.
+        * Loading into the main ICache is deprecated, and unused.
+        * It's followed by three zero bits, and 27 address bits.
+        */
+       buf_set_u32(&cmd, 0, 6, 0x3);
 
        /* virtual address of desired cache line */
        buf_set_u32(packet, 0, 27, va >> 5);
 
-       fields[0].tap = xscale->jtag_info.tap;
+       memset(&fields, 0, sizeof fields);
+
+       fields[0].tap = target->tap;
        fields[0].num_bits = 6;
        fields[0].out_value = &cmd;
-       fields[0].in_value = NULL;
 
-       fields[1].tap = xscale->jtag_info.tap;
+       fields[1].tap = target->tap;
        fields[1].num_bits = 27;
        fields[1].out_value = packet;
-       fields[1].in_value = NULL;
 
        jtag_add_dr_scan(2, fields, jtag_get_end_state());
 
+       /* rest of packet is a cacheline: 8 instructions, with parity */
        fields[0].num_bits = 32;
        fields[0].out_value = packet;
 
@@ -772,17 +736,14 @@ static int xscale_load_ic(target_t *target, int mini, uint32_t va, uint32_t buff
        return jtag_execute_queue();
 }
 
-static int xscale_invalidate_ic_line(target_t *target, uint32_t va)
+static int xscale_invalidate_ic_line(struct target *target, uint32_t va)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
        uint8_t packet[4];
        uint8_t cmd;
-
-       scan_field_t fields[2];
+       struct scan_field fields[2];
 
        jtag_set_end_state(TAP_IDLE);
-       xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.ldic); /* LDIC */
+       xscale_jtag_set_instr(target->tap, XSCALE_LDIC);
 
        /* CMD for invalidate IC line b000, bits [6:4] b000 */
        buf_set_u32(&cmd, 0, 6, 0x0);
@@ -790,25 +751,24 @@ static int xscale_invalidate_ic_line(target_t *target, uint32_t va)
        /* virtual address of desired cache line */
        buf_set_u32(packet, 0, 27, va >> 5);
 
-       fields[0].tap = xscale->jtag_info.tap;
+       memset(&fields, 0, sizeof fields);
+
+       fields[0].tap = target->tap;
        fields[0].num_bits = 6;
        fields[0].out_value = &cmd;
-       fields[0].in_value = NULL;
 
-       fields[1].tap = xscale->jtag_info.tap;
+       fields[1].tap = target->tap;
        fields[1].num_bits = 27;
        fields[1].out_value = packet;
-       fields[1].in_value = NULL;
 
        jtag_add_dr_scan(2, fields, jtag_get_end_state());
 
        return ERROR_OK;
 }
 
-static int xscale_update_vectors(target_t *target)
+static int xscale_update_vectors(struct target *target)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
        int i;
        int retval;
 
@@ -864,16 +824,16 @@ static int xscale_update_vectors(target_t *target)
        xscale_invalidate_ic_line(target, 0x0);
        xscale_invalidate_ic_line(target, 0xffff0000);
 
-       xscale_load_ic(target, 1, 0x0, xscale->low_vectors);
-       xscale_load_ic(target, 1, 0xffff0000, xscale->high_vectors);
+       xscale_load_ic(target, 0x0, xscale->low_vectors);
+       xscale_load_ic(target, 0xffff0000, xscale->high_vectors);
 
        return ERROR_OK;
 }
 
-static int xscale_arch_state(struct target_s *target)
+static int xscale_arch_state(struct target *target)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
+       struct armv4_5_common_s *armv4_5 = &xscale->armv4_5_common;
 
        static const char *state[] =
        {
@@ -888,7 +848,7 @@ static int xscale_arch_state(struct target_s *target)
        if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
        {
                LOG_ERROR("BUG: called for a non-ARMv4/5 target");
-               exit(-1);
+               return ERROR_INVALID_ARGUMENTS;
        }
 
        LOG_USER("target halted in %s state due to %s, current mode: %s\n"
@@ -897,7 +857,7 @@ static int xscale_arch_state(struct target_s *target)
                        "%s",
                         armv4_5_state_strings[armv4_5->core_state],
                         Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name ,
-                        armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
+                        arm_mode_name(armv4_5->core_mode),
                         buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
                         buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
                         state[xscale->armv4_5_mmu.mmu_enabled],
@@ -908,11 +868,9 @@ static int xscale_arch_state(struct target_s *target)
        return ERROR_OK;
 }
 
-static int xscale_poll(target_t *target)
+static int xscale_poll(struct target *target)
 {
        int retval = ERROR_OK;
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
 
        if ((target->state == TARGET_RUNNING) || (target->state == TARGET_DEBUG_RUNNING))
        {
@@ -921,8 +879,6 @@ static int xscale_poll(target_t *target)
                {
 
                        /* there's data to read from the tx register, we entered debug state */
-                       xscale->handler_running = 1;
-
                        target->state = TARGET_HALTED;
 
                        /* process debug entry, fetching current mode regs */
@@ -952,15 +908,14 @@ static int xscale_poll(target_t *target)
        return retval;
 }
 
-static int xscale_debug_entry(target_t *target)
+static int xscale_debug_entry(struct target *target)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
+       struct armv4_5_common_s *armv4_5 = &xscale->armv4_5_common;
        uint32_t pc;
        uint32_t buffer[10];
        int i;
        int retval;
-
        uint32_t moe;
 
        /* clear external dbg break (will be written on next DCSR read) */
@@ -999,13 +954,14 @@ static int xscale_debug_entry(target_t *target)
        LOG_DEBUG("cpsr: 0x%8.8" PRIx32 "", buffer[9]);
 
        armv4_5->core_mode = buffer[9] & 0x1f;
-       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 (buffer[9] & 0x20)
                armv4_5->core_state = ARMV4_5_STATE_THUMB;
@@ -1013,9 +969,6 @@ static int xscale_debug_entry(target_t *target)
                armv4_5->core_state = ARMV4_5_STATE_ARM;
 
 
-       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
-               return ERROR_FAIL;
-
        /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
        if ((armv4_5->core_mode != ARMV4_5_MODE_USR) && (armv4_5->core_mode != ARMV4_5_MODE_SYS))
        {
@@ -1133,10 +1086,9 @@ static int xscale_debug_entry(target_t *target)
        return ERROR_OK;
 }
 
-static int xscale_halt(target_t *target)
+static int xscale_halt(struct target *target)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
 
        LOG_DEBUG("target->state: %s",
                  target_state_name(target));
@@ -1168,16 +1120,15 @@ static int xscale_halt(target_t *target)
        return ERROR_OK;
 }
 
-static int xscale_enable_single_step(struct target_s *target, uint32_t next_pc)
+static int xscale_enable_single_step(struct target *target, uint32_t next_pc)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale= armv4_5->arch_info;
-       reg_t *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0];
+       struct xscale_common *xscale = target_to_xscale(target);
+       struct reg *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0];
        int retval;
 
        if (xscale->ibcr0_used)
        {
-               breakpoint_t *ibcr0_bp = breakpoint_find(target, buf_get_u32(ibcr0->value, 0, 32) & 0xfffffffe);
+               struct breakpoint *ibcr0_bp = breakpoint_find(target, buf_get_u32(ibcr0->value, 0, 32) & 0xfffffffe);
 
                if (ibcr0_bp)
                {
@@ -1196,11 +1147,10 @@ static int xscale_enable_single_step(struct target_s *target, uint32_t next_pc)
        return ERROR_OK;
 }
 
-static int xscale_disable_single_step(struct target_s *target)
+static int xscale_disable_single_step(struct target *target)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale= armv4_5->arch_info;
-       reg_t *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0];
+       struct xscale_common *xscale = target_to_xscale(target);
+       struct reg *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0];
        int retval;
 
        if ((retval = xscale_set_reg_u32(ibcr0, 0x0)) != ERROR_OK)
@@ -1209,9 +1159,9 @@ static int xscale_disable_single_step(struct target_s *target)
        return ERROR_OK;
 }
 
-static void xscale_enable_watchpoints(struct target_s *target)
+static void xscale_enable_watchpoints(struct target *target)
 {
-       watchpoint_t *watchpoint = target->watchpoints;
+       struct watchpoint *watchpoint = target->watchpoints;
 
        while (watchpoint)
        {
@@ -1221,9 +1171,9 @@ static void xscale_enable_watchpoints(struct target_s *target)
        }
 }
 
-static void xscale_enable_breakpoints(struct target_s *target)
+static void xscale_enable_breakpoints(struct target *target)
 {
-       breakpoint_t *breakpoint = target->breakpoints;
+       struct breakpoint *breakpoint = target->breakpoints;
 
        /* set any pending breakpoints */
        while (breakpoint)
@@ -1234,15 +1184,13 @@ static void xscale_enable_breakpoints(struct target_s *target)
        }
 }
 
-static int xscale_resume(struct target_s *target, int current,
+static int xscale_resume(struct target *target, int current,
                uint32_t address, int handle_breakpoints, int debug_execution)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale= armv4_5->arch_info;
-       breakpoint_t *breakpoint = target->breakpoints;
-
+       struct xscale_common *xscale = target_to_xscale(target);
+       struct armv4_5_common_s *armv4_5 = &xscale->armv4_5_common;
+       struct breakpoint *breakpoint = target->breakpoints;
        uint32_t current_pc;
-
        int retval;
        int i;
 
@@ -1374,7 +1322,7 @@ static int xscale_resume(struct target_s *target, int current,
        if (!debug_execution)
        {
                /* registers are now invalid */
-               armv4_5_invalidate_core_regs(target);
+               register_cache_invalidate(armv4_5->core_cache);
                target->state = TARGET_RUNNING;
                target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
        }
@@ -1386,17 +1334,14 @@ static int xscale_resume(struct target_s *target, int current,
 
        LOG_DEBUG("target resumed");
 
-       xscale->handler_running = 1;
-
        return ERROR_OK;
 }
 
-static int xscale_step_inner(struct target_s *target, int current,
+static int xscale_step_inner(struct target *target, int current,
                uint32_t address, int handle_breakpoints)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
-
+       struct xscale_common *xscale = target_to_xscale(target);
+       struct armv4_5_common_s *armv4_5 = &xscale->armv4_5_common;
        uint32_t next_pc;
        int retval;
        int i;
@@ -1456,8 +1401,7 @@ static int xscale_step_inner(struct target_s *target, int current,
        target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
 
        /* registers are now invalid */
-       if ((retval = armv4_5_invalidate_core_regs(target)) != ERROR_OK)
-               return retval;
+       register_cache_invalidate(armv4_5->core_cache);
 
        /* wait for and process debug entry */
        if ((retval = xscale_debug_entry(target)) != ERROR_OK)
@@ -1472,11 +1416,11 @@ static int xscale_step_inner(struct target_s *target, int current,
        return ERROR_OK;
 }
 
-static int xscale_step(struct target_s *target, int current,
+static int xscale_step(struct target *target, int current,
                uint32_t address, int handle_breakpoints)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       breakpoint_t *breakpoint = target->breakpoints;
+       struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
+       struct breakpoint *breakpoint = target->breakpoints;
 
        uint32_t current_pc;
        int retval;
@@ -1527,10 +1471,9 @@ static int xscale_step(struct target_s *target, int current,
 
 }
 
-static int xscale_assert_reset(target_t *target)
+static int xscale_assert_reset(struct target *target)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
 
        LOG_DEBUG("target->state: %s",
                  target_state_name(target));
@@ -1539,7 +1482,7 @@ static int xscale_assert_reset(target_t *target)
         * end up in T-L-R, which would reset JTAG
         */
        jtag_set_end_state(TAP_IDLE);
-       xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dcsr);
+       xscale_jtag_set_instr(target->tap, XSCALE_SELDCSR);
 
        /* set Hold reset, Halt mode and Trap Reset */
        buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
@@ -1547,7 +1490,7 @@ static int xscale_assert_reset(target_t *target)
        xscale_write_dcsr(target, 1, 0);
 
        /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
-       xscale_jtag_set_instr(xscale->jtag_info.tap, 0x7f);
+       xscale_jtag_set_instr(target->tap, 0x7f);
        jtag_execute_queue();
 
        /* assert reset */
@@ -1569,20 +1512,10 @@ static int xscale_assert_reset(target_t *target)
        return ERROR_OK;
 }
 
-static int xscale_deassert_reset(target_t *target)
+static int xscale_deassert_reset(struct target *target)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
-
-       fileio_t debug_handler;
-       uint32_t address;
-       uint32_t binary_size;
-
-       uint32_t buf_cnt;
-       uint32_t i;
-       int retval;
-
-       breakpoint_t *breakpoint = target->breakpoints;
+       struct xscale_common *xscale = target_to_xscale(target);
+       struct breakpoint *breakpoint = target->breakpoints;
 
        LOG_DEBUG("-");
 
@@ -1604,8 +1537,23 @@ static int xscale_deassert_reset(target_t *target)
                breakpoint = breakpoint->next;
        }
 
-       if (!xscale->handler_installed)
+       register_cache_invalidate(xscale->armv4_5_common.core_cache);
+
+       /* FIXME mark hardware watchpoints got unset too.  Also,
+        * at least some of the XScale registers are invalid...
+        */
+
+       /*
+        * REVISIT:  *assumes* we had a SRST+TRST reset so the mini-icache
+        * contents got invalidated.  Safer to force that, so writing new
+        * contents can't ever fail..
+        */
        {
+               uint32_t address;
+               unsigned buf_cnt;
+               const uint8_t *buffer = xscale_debug_handler;
+               int retval;
+
                /* release SRST */
                jtag_add_reset(0, 0);
 
@@ -1620,36 +1568,22 @@ static int xscale_deassert_reset(target_t *target)
                buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
                xscale_write_dcsr(target, 1, 0);
 
-               /* Load debug handler */
-               if (fileio_open(&debug_handler, "xscale/debug_handler.bin", FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
-               {
-                       return ERROR_OK;
-               }
-
-               if ((binary_size = debug_handler.size) % 4)
-               {
-                       LOG_ERROR("debug_handler.bin: size not a multiple of 4");
-                       exit(-1);
-               }
-
-               if (binary_size > 0x800)
-               {
-                       LOG_ERROR("debug_handler.bin: larger than 2kb");
-                       exit(-1);
-               }
-
-               binary_size = CEIL(binary_size, 32) * 32;
-
+               /* Load the debug handler into the mini-icache.  Since
+                * it's using halt mode (not monitor mode), it runs in
+                * "Special Debug State" for access to registers, memory,
+                * coprocessors, trace data, etc.
+                */
                address = xscale->handler_address;
-               while (binary_size > 0)
+               for (unsigned binary_size = sizeof xscale_debug_handler - 1;
+                               binary_size > 0;
+                               binary_size -= buf_cnt, buffer += buf_cnt)
                {
                        uint32_t cache_line[8];
-                       uint8_t buffer[32];
+                       unsigned i;
 
-                       if ((retval = fileio_read(&debug_handler, 32, buffer, &buf_cnt)) != ERROR_OK)
-                       {
-
-                       }
+                       buf_cnt = binary_size;
+                       if (buf_cnt > 32)
+                               buf_cnt = 32;
 
                        for (i = 0; i < buf_cnt; i += 4)
                        {
@@ -1665,15 +1599,23 @@ static int xscale_deassert_reset(target_t *target)
                        /* only load addresses other than the reset vectors */
                        if ((address % 0x400) != 0x0)
                        {
-                               xscale_load_ic(target, 1, address, cache_line);
+                               retval = xscale_load_ic(target, address,
+                                               cache_line);
+                               if (retval != ERROR_OK)
+                                       return retval;
                        }
 
                        address += buf_cnt;
-                       binary_size -= buf_cnt;
                };
 
-               xscale_load_ic(target, 1, 0x0, xscale->low_vectors);
-               xscale_load_ic(target, 1, 0xffff0000, xscale->high_vectors);
+               retval = xscale_load_ic(target, 0x0,
+                                       xscale->low_vectors);
+               if (retval != ERROR_OK)
+                       return retval;
+               retval = xscale_load_ic(target, 0xffff0000,
+                                       xscale->high_vectors);
+               if (retval != ERROR_OK)
+                       return retval;
 
                jtag_add_runtest(30, jtag_set_end_state(TAP_IDLE));
 
@@ -1699,34 +1641,28 @@ static int xscale_deassert_reset(target_t *target)
                        /* resume the target */
                        xscale_resume(target, 1, 0x0, 1, 0);
                }
-
-               fileio_close(&debug_handler);
-       }
-       else
-       {
-               jtag_add_reset(0, 0);
        }
 
        return ERROR_OK;
 }
 
-static int xscale_read_core_reg(struct target_s *target, int num,
+static int xscale_read_core_reg(struct target *target, int num,
                enum armv4_5_mode mode)
 {
        LOG_ERROR("not implemented");
        return ERROR_OK;
 }
 
-static int xscale_write_core_reg(struct target_s *target, int num,
+static int xscale_write_core_reg(struct target *target, int num,
                enum armv4_5_mode mode, uint32_t value)
 {
        LOG_ERROR("not implemented");
        return ERROR_OK;
 }
 
-static int xscale_full_context(target_t *target)
+static int xscale_full_context(struct target *target)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
+       struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
 
        uint32_t *buffer;
 
@@ -1800,9 +1736,9 @@ static int xscale_full_context(target_t *target)
        return ERROR_OK;
 }
 
-static int xscale_restore_context(target_t *target)
+static int xscale_restore_context(struct target *target)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
+       struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
 
        int i, j;
 
@@ -1867,11 +1803,10 @@ static int xscale_restore_context(target_t *target)
        return ERROR_OK;
 }
 
-static int xscale_read_memory(struct target_s *target, uint32_t address,
+static int xscale_read_memory(struct target *target, uint32_t address,
                uint32_t size, uint32_t count, uint8_t *buffer)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
        uint32_t *buf32;
        uint32_t i;
        int retval;
@@ -1925,8 +1860,8 @@ static int xscale_read_memory(struct target_s *target, uint32_t address,
                                *buffer++ = buf32[i] & 0xff;
                                break;
                        default:
-                               LOG_ERROR("should never get here");
-                               exit(-1);
+                               LOG_ERROR("invalid read size");
+                               return ERROR_INVALID_ARGUMENTS;
                }
        }
 
@@ -1947,11 +1882,10 @@ static int xscale_read_memory(struct target_s *target, uint32_t address,
        return ERROR_OK;
 }
 
-static int xscale_write_memory(struct target_s *target, uint32_t address,
+static int xscale_write_memory(struct target *target, uint32_t address,
                uint32_t size, uint32_t count, uint8_t *buffer)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
        int retval;
 
        LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32, address, size, count);
@@ -2026,16 +1960,15 @@ static int xscale_write_memory(struct target_s *target, uint32_t address,
        return ERROR_OK;
 }
 
-static int xscale_bulk_write_memory(target_t *target, uint32_t address,
+static int xscale_bulk_write_memory(struct target *target, uint32_t address,
                uint32_t count, uint8_t *buffer)
 {
        return xscale_write_memory(target, address, 4, count, buffer);
 }
 
-static uint32_t xscale_get_ttb(target_t *target)
+static uint32_t xscale_get_ttb(struct target *target)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
        uint32_t ttb;
 
        xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_TTB]);
@@ -2044,11 +1977,10 @@ static uint32_t xscale_get_ttb(target_t *target)
        return ttb;
 }
 
-static void xscale_disable_mmu_caches(target_t *target, int mmu,
+static void xscale_disable_mmu_caches(struct target *target, int mmu,
                int d_u_cache, int i_cache)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
        uint32_t cp15_control;
 
        /* read cp15 control register */
@@ -2084,11 +2016,10 @@ static void xscale_disable_mmu_caches(target_t *target, int mmu,
        xscale_send_u32(target, 0x53);
 }
 
-static void xscale_enable_mmu_caches(target_t *target, int mmu,
+static void xscale_enable_mmu_caches(struct target *target, int mmu,
                int d_u_cache, int i_cache)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
        uint32_t cp15_control;
 
        /* read cp15 control register */
@@ -2111,12 +2042,11 @@ static void xscale_enable_mmu_caches(target_t *target, int mmu,
        xscale_send_u32(target, 0x53);
 }
 
-static int xscale_set_breakpoint(struct target_s *target,
-               breakpoint_t *breakpoint)
+static int xscale_set_breakpoint(struct target *target,
+               struct breakpoint *breakpoint)
 {
        int retval;
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
 
        if (target->state != TARGET_HALTED)
        {
@@ -2185,11 +2115,10 @@ static int xscale_set_breakpoint(struct target_s *target,
        return ERROR_OK;
 }
 
-static int xscale_add_breakpoint(struct target_s *target,
-               breakpoint_t *breakpoint)
+static int xscale_add_breakpoint(struct target *target,
+               struct breakpoint *breakpoint)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
 
        if (target->state != TARGET_HALTED)
        {
@@ -2217,12 +2146,11 @@ static int xscale_add_breakpoint(struct target_s *target,
        return ERROR_OK;
 }
 
-static int xscale_unset_breakpoint(struct target_s *target,
-               breakpoint_t *breakpoint)
+static int xscale_unset_breakpoint(struct target *target,
+               struct breakpoint *breakpoint)
 {
        int retval;
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
 
        if (target->state != TARGET_HALTED)
        {
@@ -2273,10 +2201,9 @@ static int xscale_unset_breakpoint(struct target_s *target,
        return ERROR_OK;
 }
 
-static int xscale_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
+static int xscale_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
 
        if (target->state != TARGET_HALTED)
        {
@@ -2295,13 +2222,12 @@ static int xscale_remove_breakpoint(struct target_s *target, breakpoint_t *break
        return ERROR_OK;
 }
 
-static int xscale_set_watchpoint(struct target_s *target,
-               watchpoint_t *watchpoint)
+static int xscale_set_watchpoint(struct target *target,
+               struct watchpoint *watchpoint)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
        uint8_t enable = 0;
-       reg_t *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];
+       struct reg *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];
        uint32_t dbcon_value = buf_get_u32(dbcon->value, 0, 32);
 
        if (target->state != TARGET_HALTED)
@@ -2352,11 +2278,10 @@ static int xscale_set_watchpoint(struct target_s *target,
        return ERROR_OK;
 }
 
-static int xscale_add_watchpoint(struct target_s *target,
-               watchpoint_t *watchpoint)
+static int xscale_add_watchpoint(struct target *target,
+               struct watchpoint *watchpoint)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
 
        if (target->state != TARGET_HALTED)
        {
@@ -2379,12 +2304,11 @@ static int xscale_add_watchpoint(struct target_s *target,
        return ERROR_OK;
 }
 
-static int xscale_unset_watchpoint(struct target_s *target,
-               watchpoint_t *watchpoint)
+static int xscale_unset_watchpoint(struct target *target,
+               struct watchpoint *watchpoint)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
-       reg_t *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];
+       struct xscale_common *xscale = target_to_xscale(target);
+       struct reg *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];
        uint32_t dbcon_value = buf_get_u32(dbcon->value, 0, 32);
 
        if (target->state != TARGET_HALTED)
@@ -2416,10 +2340,9 @@ static int xscale_unset_watchpoint(struct target_s *target,
        return ERROR_OK;
 }
 
-static int xscale_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
+static int xscale_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
 
        if (target->state != TARGET_HALTED)
        {
@@ -2437,12 +2360,11 @@ static int xscale_remove_watchpoint(struct target_s *target, watchpoint_t *watch
        return ERROR_OK;
 }
 
-static int xscale_get_reg(reg_t *reg)
+static int xscale_get_reg(struct reg *reg)
 {
-       xscale_reg_t *arch_info = reg->arch_info;
-       target_t *target = arch_info->target;
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_reg *arch_info = reg->arch_info;
+       struct target *target = arch_info->target;
+       struct xscale_common *xscale = target_to_xscale(target);
 
        /* DCSR, TX and RX are accessible via JTAG */
        if (strcmp(reg->name, "XSCALE_DCSR") == 0)
@@ -2483,12 +2405,11 @@ static int xscale_get_reg(reg_t *reg)
        return ERROR_OK;
 }
 
-static int xscale_set_reg(reg_t *reg, uint8_t* buf)
+static int xscale_set_reg(struct reg *reg, uint8_t* buf)
 {
-       xscale_reg_t *arch_info = reg->arch_info;
-       target_t *target = arch_info->target;
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_reg *arch_info = reg->arch_info;
+       struct target *target = arch_info->target;
+       struct xscale_common *xscale = target_to_xscale(target);
        uint32_t value = buf_get_u32(buf, 0, 32);
 
        /* DCSR, TX and RX are accessible via JTAG */
@@ -2528,13 +2449,11 @@ static int xscale_set_reg(reg_t *reg, uint8_t* buf)
        return ERROR_OK;
 }
 
-static int xscale_write_dcsr_sw(target_t *target, uint32_t value)
+static int xscale_write_dcsr_sw(struct target *target, uint32_t value)
 {
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
-       reg_t *dcsr = &xscale->reg_cache->reg_list[XSCALE_DCSR];
-       xscale_reg_t *dcsr_arch_info = dcsr->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
+       struct reg *dcsr = &xscale->reg_cache->reg_list[XSCALE_DCSR];
+       struct xscale_reg *dcsr_arch_info = dcsr->arch_info;
 
        /* send CP write request (command 0x41) */
        xscale_send_u32(target, 0x41);
@@ -2549,12 +2468,11 @@ static int xscale_write_dcsr_sw(target_t *target, uint32_t value)
        return ERROR_OK;
 }
 
-static int xscale_read_trace(target_t *target)
+static int xscale_read_trace(struct target *target)
 {
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
-       xscale_trace_data_t **trace_data_p;
+       struct xscale_common *xscale = target_to_xscale(target);
+       struct armv4_5_common_s *armv4_5 = &xscale->armv4_5_common;
+       struct xscale_trace_data **trace_data_p;
 
        /* 258 words from debug handler
         * 256 trace buffer entries
@@ -2608,12 +2526,12 @@ static int xscale_read_trace(target_t *target)
        for (trace_data_p = &xscale->trace.data; *trace_data_p; trace_data_p = &(*trace_data_p)->next)
                ;
 
-       *trace_data_p = malloc(sizeof(xscale_trace_data_t));
+       *trace_data_p = malloc(sizeof(struct xscale_trace_data));
        (*trace_data_p)->next = NULL;
        (*trace_data_p)->chkpt0 = trace_buffer[256];
        (*trace_data_p)->chkpt1 = trace_buffer[257];
        (*trace_data_p)->last_instruction = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
-       (*trace_data_p)->entries = malloc(sizeof(xscale_trace_entry_t) * (256 - j));
+       (*trace_data_p)->entries = malloc(sizeof(struct xscale_trace_entry) * (256 - j));
        (*trace_data_p)->depth = 256 - j;
 
        for (i = j; i < 256; i++)
@@ -2628,15 +2546,13 @@ static int xscale_read_trace(target_t *target)
        return ERROR_OK;
 }
 
-static int xscale_read_instruction(target_t *target,
-               arm_instruction_t *instruction)
+static int xscale_read_instruction(struct target *target,
+               struct arm_instruction *instruction)
 {
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
        int i;
        int section = -1;
-       uint32_t size_read;
+       size_t size_read;
        uint32_t opcode;
        int retval;
 
@@ -2695,7 +2611,7 @@ static int xscale_read_instruction(target_t *target,
        return ERROR_OK;
 }
 
-static int xscale_branch_address(xscale_trace_data_t *trace_data,
+static int xscale_branch_address(struct xscale_trace_data *trace_data,
                int i, uint32_t *target)
 {
        /* if there are less than four entries prior to the indirect branch message
@@ -2711,14 +2627,12 @@ static int xscale_branch_address(xscale_trace_data_t *trace_data,
        return 0;
 }
 
-static int xscale_analyze_trace(target_t *target, command_context_t *cmd_ctx)
+static int xscale_analyze_trace(struct target *target, struct command_context *cmd_ctx)
 {
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
        int next_pc_ok = 0;
        uint32_t next_pc = 0x0;
-       xscale_trace_data_t *trace_data = xscale->trace.data;
+       struct xscale_trace_data *trace_data = xscale->trace.data;
        int retval;
 
        while (trace_data)
@@ -2806,7 +2720,7 @@ static int xscale_analyze_trace(target_t *target, command_context_t *cmd_ctx)
                        if (xscale->trace.pc_ok)
                        {
                                int executed = (trace_data->entries[i].data & 0xf) + rollover * 16;
-                               arm_instruction_t instruction;
+                               struct arm_instruction instruction;
 
                                if ((exception == 6) || (exception == 7))
                                {
@@ -2878,7 +2792,7 @@ static int xscale_analyze_trace(target_t *target, command_context_t *cmd_ctx)
 
                for (; xscale->trace.current_pc < trace_data->last_instruction; xscale->trace.current_pc += (xscale->trace.core_state == ARMV4_5_STATE_ARM) ? 4 : 2)
                {
-                       arm_instruction_t instruction;
+                       struct arm_instruction instruction;
                        if ((retval = xscale_read_instruction(target, &instruction)) != ERROR_OK)
                        {
                                /* can't continue tracing with no image available */
@@ -2900,31 +2814,30 @@ static int xscale_analyze_trace(target_t *target, command_context_t *cmd_ctx)
        return ERROR_OK;
 }
 
-static void xscale_build_reg_cache(target_t *target)
-{
-       /* get pointers to arch-specific information */
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+static const struct reg_arch_type xscale_reg_type = {
+       .get = xscale_get_reg,
+       .set = xscale_set_reg,
+};
 
-       reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
-       xscale_reg_t *arch_info = malloc(sizeof(xscale_reg_arch_info));
+static void xscale_build_reg_cache(struct target *target)
+{
+       struct xscale_common *xscale = target_to_xscale(target);
+       struct armv4_5_common_s *armv4_5 = &xscale->armv4_5_common;
+       struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
+       struct xscale_reg *arch_info = malloc(sizeof(xscale_reg_arch_info));
        int i;
-       int num_regs = sizeof(xscale_reg_arch_info) / sizeof(xscale_reg_t);
+       int num_regs = sizeof(xscale_reg_arch_info) / sizeof(struct xscale_reg);
 
        (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
        armv4_5->core_cache = (*cache_p);
 
-       /* register a register arch-type for XScale dbg registers only once */
-       if (xscale_reg_arch_type == -1)
-               xscale_reg_arch_type = register_reg_arch_type(xscale_get_reg, xscale_set_reg);
-
-       (*cache_p)->next = malloc(sizeof(reg_cache_t));
+       (*cache_p)->next = malloc(sizeof(struct reg_cache));
        cache_p = &(*cache_p)->next;
 
        /* fill in values for the xscale reg cache */
        (*cache_p)->name = "XScale registers";
        (*cache_p)->next = NULL;
-       (*cache_p)->reg_list = malloc(num_regs * sizeof(reg_t));
+       (*cache_p)->reg_list = malloc(num_regs * sizeof(struct reg));
        (*cache_p)->num_regs = num_regs;
 
        for (i = 0; i < num_regs; i++)
@@ -2934,10 +2847,8 @@ static void xscale_build_reg_cache(target_t *target)
                (*cache_p)->reg_list[i].dirty = 0;
                (*cache_p)->reg_list[i].valid = 0;
                (*cache_p)->reg_list[i].size = 32;
-               (*cache_p)->reg_list[i].bitfield_desc = NULL;
-               (*cache_p)->reg_list[i].num_bitfields = 0;
                (*cache_p)->reg_list[i].arch_info = &arch_info[i];
-               (*cache_p)->reg_list[i].arch_type = xscale_reg_arch_type;
+               (*cache_p)->reg_list[i].type = &xscale_reg_type;
                arch_info[i] = xscale_reg_arch_info[i];
                arch_info[i].target = target;
        }
@@ -2945,59 +2856,50 @@ static void xscale_build_reg_cache(target_t *target)
        xscale->reg_cache = (*cache_p);
 }
 
-static int xscale_init_target(struct command_context_s *cmd_ctx,
-               struct target_s *target)
+static int xscale_init_target(struct command_context *cmd_ctx,
+               struct target *target)
 {
+       xscale_build_reg_cache(target);
        return ERROR_OK;
 }
 
-static int xscale_quit(void)
-{
-       jtag_add_runtest(100, TAP_RESET);
-       return ERROR_OK;
-}
-
-static int xscale_init_arch_info(target_t *target,
-               xscale_common_t *xscale, jtag_tap_t *tap, const char *variant)
+static int xscale_init_arch_info(struct target *target,
+               struct xscale_common *xscale, struct jtag_tap *tap, const char *variant)
 {
-       armv4_5_common_t *armv4_5;
+       struct arm *armv4_5;
        uint32_t high_reset_branch, low_reset_branch;
        int i;
 
        armv4_5 = &xscale->armv4_5_common;
 
        /* store architecture specfic data (none so far) */
-       xscale->arch_info = NULL;
        xscale->common_magic = XSCALE_COMMON_MAGIC;
 
-       /* remember the variant (PXA25x, PXA27x, IXP42x, ...) */
-       xscale->variant = strdup(variant);
-
-       /* prepare JTAG information for the new target */
-       xscale->jtag_info.tap = tap;
-
-       xscale->jtag_info.dbgrx = 0x02;
-       xscale->jtag_info.dbgtx = 0x10;
-       xscale->jtag_info.dcsr = 0x09;
-       xscale->jtag_info.ldic = 0x07;
+       /* we don't really *need* variant info ... */
+       if (variant) {
+               int ir_length = 0;
+
+               if (strcmp(variant, "pxa250") == 0
+                               || strcmp(variant, "pxa255") == 0
+                               || strcmp(variant, "pxa26x") == 0)
+                       ir_length = 5;
+               else if (strcmp(variant, "pxa27x") == 0
+                               || strcmp(variant, "ixp42x") == 0
+                               || strcmp(variant, "ixp45x") == 0
+                               || strcmp(variant, "ixp46x") == 0)
+                       ir_length = 7;
+               else
+                       LOG_WARNING("%s: unrecognized variant %s",
+                               tap->dotted_name, variant);
 
-       if ((strcmp(xscale->variant, "pxa250") == 0) ||
-               (strcmp(xscale->variant, "pxa255") == 0) ||
-               (strcmp(xscale->variant, "pxa26x") == 0))
-       {
-               xscale->jtag_info.ir_length = 5;
-       }
-       else if ((strcmp(xscale->variant, "pxa27x") == 0) ||
-               (strcmp(xscale->variant, "ixp42x") == 0) ||
-               (strcmp(xscale->variant, "ixp45x") == 0) ||
-               (strcmp(xscale->variant, "ixp46x") == 0))
-       {
-               xscale->jtag_info.ir_length = 7;
+               if (ir_length && ir_length != tap->ir_length) {
+                       LOG_WARNING("%s: IR length for %s is %d; fixing",
+                               tap->dotted_name, variant, ir_length);
+                       tap->ir_length = ir_length;
+               }
        }
 
        /* the debug handler isn't installed (and thus not running) at this time */
-       xscale->handler_installed = 0;
-       xscale->handler_running = 0;
        xscale->handler_address = 0xfe000800;
 
        /* clear the vectors we keep locally for reference */
@@ -3066,45 +2968,48 @@ static int xscale_init_arch_info(target_t *target,
        return ERROR_OK;
 }
 
-/* target xscale <endianess> <startup_mode> <chain_pos> <variant> */
-static int xscale_target_create(struct target_s *target, Jim_Interp *interp)
+static int xscale_target_create(struct target *target, Jim_Interp *interp)
 {
-       xscale_common_t *xscale = calloc(1,sizeof(xscale_common_t));
+       struct xscale_common *xscale;
 
-       xscale_init_arch_info(target, xscale, target->tap, target->variant);
-       xscale_build_reg_cache(target);
+       if (sizeof xscale_debug_handler - 1 > 0x800) {
+               LOG_ERROR("debug_handler.bin: larger than 2kb");
+               return ERROR_FAIL;
+       }
 
-       return ERROR_OK;
+       xscale = calloc(1, sizeof(*xscale));
+       if (!xscale)
+               return ERROR_FAIL;
+
+       return xscale_init_arch_info(target, xscale, target->tap,
+                       target->variant);
 }
 
-static int
-xscale_handle_debug_handler_command(struct command_context_s *cmd_ctx,
-               char *cmd, char **args, int argc)
+COMMAND_HANDLER(xscale_handle_debug_handler_command)
 {
-       target_t *target = NULL;
-       armv4_5_common_t *armv4_5;
-       xscale_common_t *xscale;
-
+       struct target *target = NULL;
+       struct xscale_common *xscale;
+       int retval;
        uint32_t handler_address;
 
-       if (argc < 2)
+       if (CMD_ARGC < 2)
        {
                LOG_ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
                return ERROR_OK;
        }
 
-       if ((target = get_target(args[0])) == NULL)
+       if ((target = get_target(CMD_ARGV[0])) == NULL)
        {
-               LOG_ERROR("target '%s' not defined", args[0]);
+               LOG_ERROR("target '%s' not defined", CMD_ARGV[0]);
                return ERROR_FAIL;
        }
 
-       if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
-       {
-               return ERROR_FAIL;
-       }
+       xscale = target_to_xscale(target);
+       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       if (retval != ERROR_OK)
+               return retval;
 
-       handler_address = strtoul(args[1], NULL, 0);
+       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], handler_address);
 
        if (((handler_address >= 0x800) && (handler_address <= 0x1fef800)) ||
                ((handler_address >= 0xfe000800) && (handler_address <= 0xfffff800)))
@@ -3120,34 +3025,30 @@ xscale_handle_debug_handler_command(struct command_context_s *cmd_ctx,
        return ERROR_OK;
 }
 
-static int
-xscale_handle_cache_clean_address_command(struct command_context_s *cmd_ctx,
-               char *cmd, char **args, int argc)
+COMMAND_HANDLER(xscale_handle_cache_clean_address_command)
 {
-       target_t *target = NULL;
-       armv4_5_common_t *armv4_5;
-       xscale_common_t *xscale;
-
+       struct target *target = NULL;
+       struct xscale_common *xscale;
+       int retval;
        uint32_t cache_clean_address;
 
-       if (argc < 2)
+       if (CMD_ARGC < 2)
        {
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
-       target = get_target(args[0]);
+       target = get_target(CMD_ARGV[0]);
        if (target == NULL)
        {
-               LOG_ERROR("target '%s' not defined", args[0]);
-               return ERROR_FAIL;
-       }
-
-       if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
-       {
+               LOG_ERROR("target '%s' not defined", CMD_ARGV[0]);
                return ERROR_FAIL;
        }
+       xscale = target_to_xscale(target);
+       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       if (retval != ERROR_OK)
+               return retval;
 
-       cache_clean_address = strtoul(args[1], NULL, 0);
+       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cache_clean_address);
 
        if (cache_clean_address & 0xffff)
        {
@@ -3161,37 +3062,33 @@ xscale_handle_cache_clean_address_command(struct command_context_s *cmd_ctx,
        return ERROR_OK;
 }
 
-static int
-xscale_handle_cache_info_command(struct command_context_s *cmd_ctx,
-               char *cmd, char **args, int argc)
+COMMAND_HANDLER(xscale_handle_cache_info_command)
 {
-       target_t *target = get_current_target(cmd_ctx);
-       armv4_5_common_t *armv4_5;
-       xscale_common_t *xscale;
+       struct target *target = get_current_target(CMD_CTX);
+       struct xscale_common *xscale = target_to_xscale(target);
+       int retval;
 
-       if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
-       {
-               return ERROR_OK;
-       }
+       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       if (retval != ERROR_OK)
+               return retval;
 
-       return armv4_5_handle_cache_info_command(cmd_ctx, &xscale->armv4_5_mmu.armv4_5_cache);
+       return armv4_5_handle_cache_info_command(CMD_CTX, &xscale->armv4_5_mmu.armv4_5_cache);
 }
 
-static int xscale_virt2phys(struct target_s *target,
+static int xscale_virt2phys(struct target *target,
                uint32_t virtual, uint32_t *physical)
 {
-       armv4_5_common_t *armv4_5;
-       xscale_common_t *xscale;
-       int retval;
+       struct xscale_common *xscale = target_to_xscale(target);
        int type;
        uint32_t cb;
        int domain;
        uint32_t ap;
 
-       if ((retval = xscale_get_arch_pointers(target, &armv4_5, &xscale)) != ERROR_OK)
-       {
-               return retval;
+       if (xscale->common_magic != XSCALE_COMMON_MAGIC) {
+               LOG_ERROR(xscale_not);
+               return ERROR_TARGET_INVALID;
        }
+
        uint32_t ret = armv4_5_mmu_translate_va(target, &xscale->armv4_5_mmu, virtual, &type, &cb, &domain, &ap);
        if (type == -1)
        {
@@ -3201,10 +3098,9 @@ static int xscale_virt2phys(struct target_s *target,
        return ERROR_OK;
 }
 
-static int xscale_mmu(struct target_s *target, int *enabled)
+static int xscale_mmu(struct target *target, int *enabled)
 {
-       armv4_5_common_t *armv4_5 = target->arch_info;
-       xscale_common_t *xscale = armv4_5->arch_info;
+       struct xscale_common *xscale = target_to_xscale(target);
 
        if (target->state != TARGET_HALTED)
        {
@@ -3215,172 +3111,149 @@ static int xscale_mmu(struct target_s *target, int *enabled)
        return ERROR_OK;
 }
 
-static int xscale_handle_mmu_command(command_context_t *cmd_ctx,
-               char *cmd, char **args, int argc)
+COMMAND_HANDLER(xscale_handle_mmu_command)
 {
-       target_t *target = get_current_target(cmd_ctx);
-       armv4_5_common_t *armv4_5;
-       xscale_common_t *xscale;
+       struct target *target = get_current_target(CMD_CTX);
+       struct xscale_common *xscale = target_to_xscale(target);
+       int retval;
 
-       if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
-       {
-               return ERROR_OK;
-       }
+       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       if (retval != ERROR_OK)
+               return retval;
 
        if (target->state != TARGET_HALTED)
        {
-               command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
+               command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
                return ERROR_OK;
        }
 
-       if (argc >= 1)
+       if (CMD_ARGC >= 1)
        {
-               if (strcmp("enable", args[0]) == 0)
-               {
+               bool enable;
+               COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
+               if (enable)
                        xscale_enable_mmu_caches(target, 1, 0, 0);
-                       xscale->armv4_5_mmu.mmu_enabled = 1;
-               }
-               else if (strcmp("disable", args[0]) == 0)
-               {
+               else
                        xscale_disable_mmu_caches(target, 1, 0, 0);
-                       xscale->armv4_5_mmu.mmu_enabled = 0;
-               }
+               xscale->armv4_5_mmu.mmu_enabled = enable;
        }
 
-       command_print(cmd_ctx, "mmu %s", (xscale->armv4_5_mmu.mmu_enabled) ? "enabled" : "disabled");
+       command_print(CMD_CTX, "mmu %s", (xscale->armv4_5_mmu.mmu_enabled) ? "enabled" : "disabled");
 
        return ERROR_OK;
 }
 
-static int xscale_handle_idcache_command(command_context_t *cmd_ctx,
-               char *cmd, char **args, int argc)
+COMMAND_HANDLER(xscale_handle_idcache_command)
 {
-       target_t *target = get_current_target(cmd_ctx);
-       armv4_5_common_t *armv4_5;
-       xscale_common_t *xscale;
-       int icache = 0, dcache = 0;
+       struct target *target = get_current_target(CMD_CTX);
+       struct xscale_common *xscale = target_to_xscale(target);
 
-       if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
-       {
-               return ERROR_OK;
-       }
+       int retval = xscale_verify_pointer(CMD_CTX, xscale);
+       if (retval != ERROR_OK)
+               return retval;
 
        if (target->state != TARGET_HALTED)
        {
-               command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
+               command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
                return ERROR_OK;
        }
 
-       if (strcmp(cmd, "icache") == 0)
-               icache = 1;
-       else if (strcmp(cmd, "dcache") == 0)
-               dcache = 1;
+       bool icache;
+       COMMAND_PARSE_BOOL(CMD_NAME, icache, "icache", "dcache");
 
-       if (argc >= 1)
+       if (CMD_ARGC >= 1)
        {
-               if (strcmp("enable", args[0]) == 0)
-               {
-                       xscale_enable_mmu_caches(target, 0, dcache, icache);
-
-                       if (icache)
-                               xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 1;
-                       else if (dcache)
-                               xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 1;
-               }
-               else if (strcmp("disable", args[0]) == 0)
-               {
-                       xscale_disable_mmu_caches(target, 0, dcache, icache);
-
-                       if (icache)
-                               xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
-                       else if (dcache)
-                               xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
-               }
+               bool enable;
+               COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
+               if (enable)
+                       xscale_enable_mmu_caches(target, 1, 0, 0);
+               else
+                       xscale_disable_mmu_caches(target, 1, 0, 0);
+               if (icache)
+                       xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = enable;
+               else
+                       xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = enable;
        }
 
-       if (icache)
-               command_print(cmd_ctx, "icache %s", (xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled) ? "enabled" : "disabled");
-
-       if (dcache)
-               command_print(cmd_ctx, "dcache %s", (xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) ? "enabled" : "disabled");
+       bool enabled = icache ?
+                                       xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled :
+                                       xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled;
+       const char *msg = enabled ? "enabled" : "disabled";
+       command_print(CMD_CTX, "%s %s", CMD_NAME, msg);
 
        return ERROR_OK;
 }
 
-static int xscale_handle_vector_catch_command(command_context_t *cmd_ctx,
-               char *cmd, char **args, int argc)
+COMMAND_HANDLER(xscale_handle_vector_catch_command)
 {
-       target_t *target = get_current_target(cmd_ctx);
-       armv4_5_common_t *armv4_5;
-       xscale_common_t *xscale;
+       struct target *target = get_current_target(CMD_CTX);
+       struct xscale_common *xscale = target_to_xscale(target);
+       int retval;
 
-       if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
-       {
-               return ERROR_OK;
-       }
+       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       if (retval != ERROR_OK)
+               return retval;
 
-       if (argc < 1)
+       if (CMD_ARGC < 1)
        {
-               command_print(cmd_ctx, "usage: xscale vector_catch [mask]");
+               command_print(CMD_CTX, "usage: xscale vector_catch [mask]");
        }
        else
        {
-               xscale->vector_catch = strtoul(args[0], NULL, 0);
+               COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], xscale->vector_catch);
                buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 8, xscale->vector_catch);
                xscale_write_dcsr(target, -1, -1);
        }
 
-       command_print(cmd_ctx, "vector catch mask: 0x%2.2x", xscale->vector_catch);
+       command_print(CMD_CTX, "vector catch mask: 0x%2.2x", xscale->vector_catch);
 
        return ERROR_OK;
 }
 
 
-static int xscale_handle_vector_table_command(command_context_t *cmd_ctx,
-               char *cmd, char **args, int argc)
+COMMAND_HANDLER(xscale_handle_vector_table_command)
 {
-       target_t *target = get_current_target(cmd_ctx);
-       armv4_5_common_t *armv4_5;
-       xscale_common_t *xscale;
+       struct target *target = get_current_target(CMD_CTX);
+       struct xscale_common *xscale = target_to_xscale(target);
        int err = 0;
+       int retval;
 
-       if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
-       {
-               return ERROR_OK;
-       }
+       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       if (retval != ERROR_OK)
+               return retval;
 
-       if (argc == 0) /* print current settings */
+       if (CMD_ARGC == 0) /* print current settings */
        {
                int idx;
 
-               command_print(cmd_ctx, "active user-set static vectors:");
+               command_print(CMD_CTX, "active user-set static vectors:");
                for (idx = 1; idx < 8; idx++)
                        if (xscale->static_low_vectors_set & (1 << idx))
-                               command_print(cmd_ctx, "low  %d: 0x%" PRIx32, idx, xscale->static_low_vectors[idx]);
+                               command_print(CMD_CTX, "low  %d: 0x%" PRIx32, idx, xscale->static_low_vectors[idx]);
                for (idx = 1; idx < 8; idx++)
                        if (xscale->static_high_vectors_set & (1 << idx))
-                               command_print(cmd_ctx, "high %d: 0x%" PRIx32, idx, xscale->static_high_vectors[idx]);
+                               command_print(CMD_CTX, "high %d: 0x%" PRIx32, idx, xscale->static_high_vectors[idx]);
                return ERROR_OK;
        }
 
-       if (argc != 3)
+       if (CMD_ARGC != 3)
                err = 1;
        else
        {
                int idx;
+               COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], idx);
                uint32_t vec;
-               idx = strtoul(args[1], NULL, 0);
-               vec = strtoul(args[2], NULL, 0);
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], vec);
 
                if (idx < 1 || idx >= 8)
                        err = 1;
 
-               if (!err && strcmp(args[0], "low") == 0)
+               if (!err && strcmp(CMD_ARGV[0], "low") == 0)
                {
                        xscale->static_low_vectors_set |= (1<<idx);
                        xscale->static_low_vectors[idx] = vec;
                }
-               else if (!err && (strcmp(args[0], "high") == 0))
+               else if (!err && (strcmp(CMD_ARGV[0], "high") == 0))
                {
                        xscale->static_high_vectors_set |= (1<<idx);
                        xscale->static_high_vectors[idx] = vec;
@@ -3390,35 +3263,33 @@ static int xscale_handle_vector_table_command(command_context_t *cmd_ctx,
        }
 
        if (err)
-               command_print(cmd_ctx, "usage: xscale vector_table <high|low> <index> <code>");
+               command_print(CMD_CTX, "usage: xscale vector_table <high|low> <index> <code>");
 
        return ERROR_OK;
 }
 
 
-static int
-xscale_handle_trace_buffer_command(struct command_context_s *cmd_ctx,
-               char *cmd, char **args, int argc)
+COMMAND_HANDLER(xscale_handle_trace_buffer_command)
 {
-       target_t *target = get_current_target(cmd_ctx);
-       armv4_5_common_t *armv4_5;
-       xscale_common_t *xscale;
+       struct target *target = get_current_target(CMD_CTX);
+       struct xscale_common *xscale = target_to_xscale(target);
+       struct armv4_5_common_s *armv4_5 = &xscale->armv4_5_common;
        uint32_t dcsr_value;
+       int retval;
 
-       if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
-       {
-               return ERROR_OK;
-       }
+       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       if (retval != ERROR_OK)
+               return retval;
 
        if (target->state != TARGET_HALTED)
        {
-               command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
+               command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
                return ERROR_OK;
        }
 
-       if ((argc >= 1) && (strcmp("enable", args[0]) == 0))
+       if ((CMD_ARGC >= 1) && (strcmp("enable", CMD_ARGV[0]) == 0))
        {
-               xscale_trace_data_t *td, *next_td;
+               struct xscale_trace_data *td, *next_td;
                xscale->trace.buffer_enabled = 1;
 
                /* free old trace data */
@@ -3434,19 +3305,19 @@ xscale_handle_trace_buffer_command(struct command_context_s *cmd_ctx,
                }
                xscale->trace.data = NULL;
        }
-       else if ((argc >= 1) && (strcmp("disable", args[0]) == 0))
+       else if ((CMD_ARGC >= 1) && (strcmp("disable", CMD_ARGV[0]) == 0))
        {
                xscale->trace.buffer_enabled = 0;
        }
 
-       if ((argc >= 2) && (strcmp("fill", args[1]) == 0))
+       if ((CMD_ARGC >= 2) && (strcmp("fill", CMD_ARGV[1]) == 0))
        {
-               if (argc >= 3)
-                       xscale->trace.buffer_fill = strtoul(args[2], NULL, 0);
-               else
-                       xscale->trace.buffer_fill = 1;
+               uint32_t fill = 1;
+               if (CMD_ARGC >= 3)
+                       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], fill);
+               xscale->trace.buffer_fill = fill;
        }
-       else if ((argc >= 2) && (strcmp("wrap", args[1]) == 0))
+       else if ((CMD_ARGC >= 2) && (strcmp("wrap", CMD_ARGV[1]) == 0))
        {
                xscale->trace.buffer_fill = -1;
        }
@@ -3464,7 +3335,7 @@ xscale_handle_trace_buffer_command(struct command_context_s *cmd_ctx,
                xscale->trace.pc_ok = 0;
        }
 
-       command_print(cmd_ctx, "trace buffer %s (%s)",
+       command_print(CMD_CTX, "trace buffer %s (%s)",
                (xscale->trace.buffer_enabled) ? "enabled" : "disabled",
                (xscale->trace.buffer_fill > 0) ? "fill" : "wrap");
 
@@ -3477,50 +3348,45 @@ xscale_handle_trace_buffer_command(struct command_context_s *cmd_ctx,
        return ERROR_OK;
 }
 
-static int
-xscale_handle_trace_image_command(struct command_context_s *cmd_ctx,
-               char *cmd, char **args, int argc)
+COMMAND_HANDLER(xscale_handle_trace_image_command)
 {
-       target_t *target;
-       armv4_5_common_t *armv4_5;
-       xscale_common_t *xscale;
+       struct target *target = get_current_target(CMD_CTX);
+       struct xscale_common *xscale = target_to_xscale(target);
+       int retval;
 
-       if (argc < 1)
+       if (CMD_ARGC < 1)
        {
-               command_print(cmd_ctx, "usage: xscale trace_image <file> [base address] [type]");
+               command_print(CMD_CTX, "usage: xscale trace_image <file> [base address] [type]");
                return ERROR_OK;
        }
 
-       target = get_current_target(cmd_ctx);
-
-       if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
-       {
-               return ERROR_OK;
-       }
+       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       if (retval != ERROR_OK)
+               return retval;
 
        if (xscale->trace.image)
        {
                image_close(xscale->trace.image);
                free(xscale->trace.image);
-               command_print(cmd_ctx, "previously loaded image found and closed");
+               command_print(CMD_CTX, "previously loaded image found and closed");
        }
 
-       xscale->trace.image = malloc(sizeof(image_t));
+       xscale->trace.image = malloc(sizeof(struct image));
        xscale->trace.image->base_address_set = 0;
        xscale->trace.image->start_address_set = 0;
 
        /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
-       if (argc >= 2)
+       if (CMD_ARGC >= 2)
        {
                xscale->trace.image->base_address_set = 1;
-               xscale->trace.image->base_address = strtoul(args[1], NULL, 0);
+               COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], xscale->trace.image->base_address);
        }
        else
        {
                xscale->trace.image->base_address_set = 0;
        }
 
-       if (image_open(xscale->trace.image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
+       if (image_open(xscale->trace.image, CMD_ARGV[0], (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL) != ERROR_OK)
        {
                free(xscale->trace.image);
                xscale->trace.image = NULL;
@@ -3530,29 +3396,27 @@ xscale_handle_trace_image_command(struct command_context_s *cmd_ctx,
        return ERROR_OK;
 }
 
-static int xscale_handle_dump_trace_command(struct command_context_s *cmd_ctx,
-               char *cmd, char **args, int argc)
+COMMAND_HANDLER(xscale_handle_dump_trace_command)
 {
-       target_t *target = get_current_target(cmd_ctx);
-       armv4_5_common_t *armv4_5;
-       xscale_common_t *xscale;
-       xscale_trace_data_t *trace_data;
-       fileio_t file;
+       struct target *target = get_current_target(CMD_CTX);
+       struct xscale_common *xscale = target_to_xscale(target);
+       struct xscale_trace_data *trace_data;
+       struct fileio file;
+       int retval;
 
-       if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
-       {
-               return ERROR_OK;
-       }
+       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       if (retval != ERROR_OK)
+               return retval;
 
        if (target->state != TARGET_HALTED)
        {
-               command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
+               command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
                return ERROR_OK;
        }
 
-       if (argc < 1)
+       if (CMD_ARGC < 1)
        {
-               command_print(cmd_ctx, "usage: xscale dump_trace <file>");
+               command_print(CMD_CTX, "usage: xscale dump_trace <file>");
                return ERROR_OK;
        }
 
@@ -3560,11 +3424,11 @@ static int xscale_handle_dump_trace_command(struct command_context_s *cmd_ctx,
 
        if (!trace_data)
        {
-               command_print(cmd_ctx, "no trace data collected");
+               command_print(CMD_CTX, "no trace data collected");
                return ERROR_OK;
        }
 
-       if (fileio_open(&file, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
+       if (fileio_open(&file, CMD_ARGV[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
        {
                return ERROR_OK;
        }
@@ -3589,46 +3453,41 @@ static int xscale_handle_dump_trace_command(struct command_context_s *cmd_ctx,
        return ERROR_OK;
 }
 
-static int
-xscale_handle_analyze_trace_buffer_command(struct command_context_s *cmd_ctx,
-               char *cmd, char **args, int argc)
+COMMAND_HANDLER(xscale_handle_analyze_trace_buffer_command)
 {
-       target_t *target = get_current_target(cmd_ctx);
-       armv4_5_common_t *armv4_5;
-       xscale_common_t *xscale;
+       struct target *target = get_current_target(CMD_CTX);
+       struct xscale_common *xscale = target_to_xscale(target);
+       int retval;
 
-       if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
-       {
-               return ERROR_OK;
-       }
+       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       if (retval != ERROR_OK)
+               return retval;
 
-       xscale_analyze_trace(target, cmd_ctx);
+       xscale_analyze_trace(target, CMD_CTX);
 
        return ERROR_OK;
 }
 
-static int xscale_handle_cp15(command_context_t *cmd_ctx,
-               char *cmd, char **args, int argc)
+COMMAND_HANDLER(xscale_handle_cp15)
 {
-       target_t *target = get_current_target(cmd_ctx);
-       armv4_5_common_t *armv4_5;
-       xscale_common_t *xscale;
+       struct target *target = get_current_target(CMD_CTX);
+       struct xscale_common *xscale = target_to_xscale(target);
+       int retval;
 
-       if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
-       {
-               return ERROR_OK;
-       }
+       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       if (retval != ERROR_OK)
+               return retval;
 
        if (target->state != TARGET_HALTED)
        {
-               command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
+               command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
                return ERROR_OK;
        }
        uint32_t reg_no = 0;
-       reg_t *reg = NULL;
-       if (argc > 0)
+       struct reg *reg = NULL;
+       if (CMD_ARGC > 0)
        {
-               reg_no = strtoul(args[0], NULL, 0);
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], reg_no);
                /*translate from xscale cp15 register no to openocd register*/
                switch (reg_no)
                {
@@ -3657,25 +3516,25 @@ static int xscale_handle_cp15(command_context_t *cmd_ctx,
                        reg_no = XSCALE_CPACCESS;
                        break;
                default:
-                       command_print(cmd_ctx, "invalid register number");
+                       command_print(CMD_CTX, "invalid register number");
                        return ERROR_INVALID_ARGUMENTS;
                }
                reg = &xscale->reg_cache->reg_list[reg_no];
 
        }
-       if (argc == 1)
+       if (CMD_ARGC == 1)
        {
                uint32_t value;
 
                /* read cp15 control register */
                xscale_get_reg(reg);
                value = buf_get_u32(reg->value, 0, 32);
-               command_print(cmd_ctx, "%s (/%i): 0x%" PRIx32 "", reg->name, (int)(reg->size), value);
+               command_print(CMD_CTX, "%s (/%i): 0x%" PRIx32 "", reg->name, (int)(reg->size), value);
        }
-       else if (argc == 2)
+       else if (CMD_ARGC == 2)
        {
-
-               uint32_t value = strtoul(args[1], NULL, 0);
+               uint32_t value;
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
 
                /* send CP write request (command 0x41) */
                xscale_send_u32(target, 0x41);
@@ -3691,15 +3550,15 @@ static int xscale_handle_cp15(command_context_t *cmd_ctx,
        }
        else
        {
-               command_print(cmd_ctx, "usage: cp15 [register]<, [value]>");
+               command_print(CMD_CTX, "usage: cp15 [register]<, [value]>");
        }
 
        return ERROR_OK;
 }
 
-static int xscale_register_commands(struct command_context_s *cmd_ctx)
+static int xscale_register_commands(struct command_context *cmd_ctx)
 {
-       command_t *xscale_cmd;
+       struct command *xscale_cmd;
 
        xscale_cmd = register_command(cmd_ctx, NULL, "xscale", NULL, COMMAND_ANY, "xscale specific commands");
 
@@ -3728,7 +3587,7 @@ static int xscale_register_commands(struct command_context_s *cmd_ctx)
        return ERROR_OK;
 }
 
-target_type_t xscale_target =
+struct target_type xscale_target =
 {
        .name = "xscale",
 
@@ -3750,8 +3609,9 @@ target_type_t xscale_target =
        .read_memory = xscale_read_memory,
        .write_memory = xscale_write_memory,
        .bulk_write_memory = xscale_bulk_write_memory,
-       .checksum_memory = arm7_9_checksum_memory,
-       .blank_check_memory = arm7_9_blank_check_memory,
+
+       .checksum_memory = arm_checksum_memory,
+       .blank_check_memory = arm_blank_check_memory,
 
        .run_algorithm = armv4_5_run_algorithm,
 
@@ -3763,7 +3623,6 @@ target_type_t xscale_target =
        .register_commands = xscale_register_commands,
        .target_create = xscale_target_create,
        .init_target = xscale_init_target,
-       .quit = xscale_quit,
 
        .virt2phys = xscale_virt2phys,
        .mmu = xscale_mmu

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)