target/xscale: Use 'bool' data type
[openocd.git] / src / target / xscale.c
index f0e2311f905f0c1d4b785815fcfb4bdc5151ba3b..09abd9ef0e2e81c758c6d4bc13ce9c39dfa1ac58 100644 (file)
  *   GNU General Public License for more details.                          *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -39,7 +38,6 @@
 #include "arm_opcodes.h"
 #include "armv4_5.h"
 
-
 /*
  * Important XScale documents available as of October 2009 include:
  *
  * Chip-specific microarchitecture documents may also be useful.
  */
 
-
 /* forward declarations */
 static int xscale_resume(struct target *, int current,
-       uint32_t address, int handle_breakpoints, int debug_execution);
+       target_addr_t address, int handle_breakpoints, int debug_execution);
 static int xscale_debug_entry(struct target *);
 static int xscale_restore_banked(struct target *);
 static int xscale_get_reg(struct reg *reg);
@@ -72,20 +69,14 @@ 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 const uint8_t xscale_debug_handler[] = {
+#include "../../contrib/loaders/debug/xscale/debug_handler.inc"
+};
 
-static char *const xscale_reg_list[] =
-{
+static const char *const xscale_reg_list[] = {
        "XSCALE_MAINID",                /* 0 */
        "XSCALE_CACHETYPE",
        "XSCALE_CTRL",
@@ -110,8 +101,7 @@ static char *const xscale_reg_list[] =
        "XSCALE_TXRXCTRL",
 };
 
-static const struct xscale_reg xscale_reg_arch_info[] =
-{
+static const struct xscale_reg xscale_reg_arch_info[] = {
        {XSCALE_MAINID, NULL},
        {XSCALE_CACHETYPE, NULL},
        {XSCALE_CTRL, NULL},
@@ -130,10 +120,10 @@ static const struct xscale_reg xscale_reg_arch_info[] =
        {XSCALE_TBREG, NULL},
        {XSCALE_CHKPT0, NULL},
        {XSCALE_CHKPT1, NULL},
-       {XSCALE_DCSR, NULL}, /* DCSR accessed via JTAG or SW */
-       {-1, NULL}, /* TX accessed via JTAG */
-       {-1, NULL}, /* RX accessed via JTAG */
-       {-1, NULL}, /* TXRXCTRL implicit access via JTAG */
+       {XSCALE_DCSR, NULL},    /* DCSR accessed via JTAG or SW */
+       {-1, NULL},     /* TX accessed via JTAG */
+       {-1, NULL},     /* RX accessed via JTAG */
+       {-1, NULL},     /* TXRXCTRL implicit access via JTAG */
 };
 
 /* convenience wrapper to access XScale specific registers */
@@ -149,7 +139,7 @@ static int xscale_set_reg_u32(struct reg *reg, uint32_t value)
 static const char xscale_not[] = "target is not an XScale";
 
 static int xscale_verify_pointer(struct command_context *cmd_ctx,
-               struct xscale_common *xscale)
+       struct xscale_common *xscale)
 {
        if (xscale->common_magic != XSCALE_COMMON_MAGIC) {
                command_print(cmd_ctx, xscale_not);
@@ -160,18 +150,16 @@ static int xscale_verify_pointer(struct command_context *cmd_ctx,
 
 static int xscale_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state)
 {
-       if (tap == NULL)
-               return ERROR_FAIL;
+       assert(tap != NULL);
 
-       if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr)
-       {
+       if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {
                struct scan_field field;
                uint8_t scratch[4];
 
                memset(&field, 0, sizeof field);
                field.num_bits = tap->ir_length;
                field.out_value = scratch;
-               buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
+               buf_set_u32(scratch, 0, field.num_bits, new_instr);
 
                jtag_add_ir_scan(tap, &field, end_state);
        }
@@ -218,14 +206,14 @@ static int xscale_read_dcsr(struct target *target)
        jtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask);
        jtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask);
 
-       if ((retval = jtag_execute_queue()) != ERROR_OK)
-       {
+       retval = jtag_execute_queue();
+       if (retval != ERROR_OK) {
                LOG_ERROR("JTAG error while reading DCSR");
                return retval;
        }
 
-       xscale->reg_cache->reg_list[XSCALE_DCSR].dirty = 0;
-       xscale->reg_cache->reg_list[XSCALE_DCSR].valid = 1;
+       xscale->reg_cache->reg_list[XSCALE_DCSR].dirty = false;
+       xscale->reg_cache->reg_list[XSCALE_DCSR].valid = true;
 
        /* write the register with the value we just read
         * on this second pass, only the first bit of field0 is guaranteed to be 0)
@@ -245,13 +233,13 @@ static int xscale_read_dcsr(struct target *target)
 static void xscale_getbuf(jtag_callback_data_t arg)
 {
        uint8_t *in = (uint8_t *)arg;
-       *((uint32_t *)in) = buf_get_u32(in, 0, 32);
+       *((uint32_t *)arg) = buf_get_u32(in, 0, 32);
 }
 
 static int xscale_receive(struct target *target, uint32_t *buffer, int num_words)
 {
        if (num_words == 0)
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        struct xscale_common *xscale = target_to_xscale(target);
        int retval = ERROR_OK;
@@ -274,28 +262,31 @@ static int xscale_receive(struct target *target, uint32_t *buffer, int num_words
        memset(&fields, 0, sizeof fields);
 
        fields[0].num_bits = 3;
+       uint8_t tmp;
+       fields[0].in_value = &tmp;
        fields[0].check_value = &field0_check_value;
        fields[0].check_mask = &field0_check_mask;
 
        fields[1].num_bits = 32;
 
        fields[2].num_bits = 1;
+       uint8_t tmp2;
+       fields[2].in_value = &tmp2;
        fields[2].check_value = &field2_check_value;
        fields[2].check_mask = &field2_check_mask;
 
        xscale_jtag_set_instr(target->tap,
                XSCALE_DBGTX << xscale->xscale_variant,
                TAP_IDLE);
-       jtag_add_runtest(1, TAP_IDLE); /* ensures that we're in the TAP_IDLE state as the above could be a no-op */
+       jtag_add_runtest(1, TAP_IDLE);  /* ensures that we're in the TAP_IDLE state as the above
+                                        *could be a no-op */
 
        /* repeat until all words have been collected */
        int attempts = 0;
-       while (words_done < num_words)
-       {
+       while (words_done < num_words) {
                /* schedule reads */
                words_scheduled = 0;
-               for (i = words_done; i < num_words; i++)
-               {
+               for (i = words_done; i < num_words; i++) {
                        fields[0].in_value = &field0[i];
 
                        jtag_add_pathmove(3, path);
@@ -309,32 +300,28 @@ static int xscale_receive(struct target *target, uint32_t *buffer, int num_words
                        words_scheduled++;
                }
 
-               if ((retval = jtag_execute_queue()) != ERROR_OK)
-               {
+               retval = jtag_execute_queue();
+               if (retval != ERROR_OK) {
                        LOG_ERROR("JTAG error while receiving data from debug handler");
                        break;
                }
 
                /* examine results */
-               for (i = words_done; i < num_words; i++)
-               {
-                       if (!(field0[0] & 1))
-                       {
+               for (i = words_done; i < num_words; i++) {
+                       if (!(field0[i] & 1)) {
                                /* move backwards if necessary */
                                int j;
-                               for (j = i; j < num_words - 1; j++)
-                               {
+                               for (j = i; j < num_words - 1; j++) {
                                        field0[j] = field0[j + 1];
                                        field1[j] = field1[j + 1];
                                }
                                words_scheduled--;
                        }
                }
-               if (words_scheduled == 0)
-               {
-                       if (attempts++==1000)
-                       {
-                               LOG_ERROR("Failed to receiving data from debug handler after 1000 attempts");
+               if (words_scheduled == 0) {
+                       if (attempts++ == 1000) {
+                               LOG_ERROR(
+                                       "Failed to receiving data from debug handler after 1000 attempts");
                                retval = ERROR_TARGET_TIMEOUT;
                                break;
                        }
@@ -344,7 +331,7 @@ static int xscale_receive(struct target *target, uint32_t *buffer, int num_words
        }
 
        for (i = 0; i < num_words; i++)
-               *(buffer++) = buf_get_u32((uint8_t*)&field1[i], 0, 32);
+               *(buffer++) = buf_get_u32((uint8_t *)&field1[i], 0, 32);
 
        free(field1);
 
@@ -395,8 +382,7 @@ static int xscale_read_tx(struct target *target, int consume)
        gettimeofday(&timeout, NULL);
        timeval_add_time(&timeout, 1, 0);
 
-       for (;;)
-       {
+       for (;; ) {
                /* if we want to consume the register content (i.e. clear TX_READY),
                 * we have to go straight from Capture-DR to Shift-DR
                 * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR
@@ -404,41 +390,33 @@ static int xscale_read_tx(struct target *target, int consume)
                if (consume)
                        jtag_add_pathmove(3, path);
                else
-               {
                        jtag_add_pathmove(ARRAY_SIZE(noconsume_path), noconsume_path);
-               }
 
                jtag_add_dr_scan(target->tap, 3, fields, TAP_IDLE);
 
                jtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask);
                jtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask);
 
-               if ((retval = jtag_execute_queue()) != ERROR_OK)
-               {
+               retval = jtag_execute_queue();
+               if (retval != ERROR_OK) {
                        LOG_ERROR("JTAG error while reading TX");
                        return ERROR_TARGET_TIMEOUT;
                }
 
                gettimeofday(&now, NULL);
-               if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec)&& (now.tv_usec > timeout.tv_usec)))
-               {
+               if (timeval_compare(&now, &timeout) > 0) {
                        LOG_ERROR("time out reading TX register");
                        return ERROR_TARGET_TIMEOUT;
                }
                if (!((!(field0_in & 1)) && consume))
-               {
                        goto done;
-               }
-               if (debug_level >= 3)
-               {
+               if (debug_level >= 3) {
                        LOG_DEBUG("waiting 100ms");
-                       alive_sleep(100); /* avoid flooding the logs */
+                       alive_sleep(100);       /* avoid flooding the logs */
                } else
-               {
                        keep_alive();
-               }
        }
-       done:
+done:
 
        if (!(field0_in & 1))
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
@@ -483,44 +461,40 @@ static int xscale_write_rx(struct target *target)
 
        /* poll until rx_read is low */
        LOG_DEBUG("polling RX");
-       for (;;)
-       {
+       for (;;) {
                jtag_add_dr_scan(target->tap, 3, fields, TAP_IDLE);
 
                jtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask);
                jtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask);
 
-               if ((retval = jtag_execute_queue()) != ERROR_OK)
-               {
+               retval = jtag_execute_queue();
+               if (retval != ERROR_OK) {
                        LOG_ERROR("JTAG error while writing RX");
                        return retval;
                }
 
                gettimeofday(&now, NULL);
-               if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec)&& (now.tv_usec > timeout.tv_usec)))
-               {
+               if ((now.tv_sec > timeout.tv_sec) ||
+                       ((now.tv_sec == timeout.tv_sec) && (now.tv_usec > timeout.tv_usec))) {
                        LOG_ERROR("time out writing RX register");
                        return ERROR_TARGET_TIMEOUT;
                }
                if (!(field0_in & 1))
                        goto done;
-               if (debug_level >= 3)
-               {
+               if (debug_level >= 3) {
                        LOG_DEBUG("waiting 100ms");
-                       alive_sleep(100); /* avoid flooding the logs */
+                       alive_sleep(100);       /* avoid flooding the logs */
                } else
-               {
                        keep_alive();
-               }
        }
-       done:
+done:
 
        /* set rx_valid */
        field2 = 0x1;
        jtag_add_dr_scan(target->tap, 3, fields, TAP_IDLE);
 
-       if ((retval = jtag_execute_queue()) != ERROR_OK)
-       {
+       retval = jtag_execute_queue();
+       if (retval != ERROR_OK) {
                LOG_ERROR("JTAG error while writing RX");
                return retval;
        }
@@ -529,11 +503,9 @@ static int xscale_write_rx(struct target *target)
 }
 
 /* send count elements of size byte to the debug handler */
-static int xscale_send(struct target *target, uint8_t *buffer, int count, int size)
+static int xscale_send(struct target *target, const uint8_t *buffer, int count, int size)
 {
        struct xscale_common *xscale = target_to_xscale(target);
-       uint32_t t[3];
-       int bits[3];
        int retval;
        int done_count = 0;
 
@@ -541,51 +513,51 @@ static int xscale_send(struct target *target, uint8_t *buffer, int count, int si
                XSCALE_DBGRX << xscale->xscale_variant,
                TAP_IDLE);
 
-       bits[0]=3;
-       t[0]=0;
-       bits[1]=32;
-       t[2]=1;
-       bits[2]=1;
+       static const uint8_t t0;
+       uint8_t t1[4];
+       static const uint8_t t2 = 1;
+       struct scan_field fields[3] = {
+                       { .num_bits = 3, .out_value = &t0 },
+                       { .num_bits = 32, .out_value = t1 },
+                       { .num_bits = 1, .out_value = &t2 },
+       };
+
        int endianness = target->endianness;
-       while (done_count++ < count)
-       {
-               switch (size)
-               {
-               case 4:
-                       if (endianness == TARGET_LITTLE_ENDIAN)
-                       {
-                               t[1]=le_to_h_u32(buffer);
-                       } else
-                       {
-                               t[1]=be_to_h_u32(buffer);
-                       }
-                       break;
-               case 2:
-                       if (endianness == TARGET_LITTLE_ENDIAN)
-                       {
-                               t[1]=le_to_h_u16(buffer);
-                       } else
-                       {
-                               t[1]=be_to_h_u16(buffer);
-                       }
-                       break;
-               case 1:
-                       t[1]=buffer[0];
-                       break;
-               default:
-                       LOG_ERROR("BUG: size neither 4, 2 nor 1");
-                       return ERROR_INVALID_ARGUMENTS;
+       while (done_count++ < count) {
+               uint32_t t;
+
+               switch (size) {
+                       case 4:
+                               if (endianness == TARGET_LITTLE_ENDIAN)
+                                       t = le_to_h_u32(buffer);
+                               else
+                                       t = be_to_h_u32(buffer);
+                               break;
+                       case 2:
+                               if (endianness == TARGET_LITTLE_ENDIAN)
+                                       t = le_to_h_u16(buffer);
+                               else
+                                       t = be_to_h_u16(buffer);
+                               break;
+                       case 1:
+                               t = buffer[0];
+                               break;
+                       default:
+                               LOG_ERROR("BUG: size neither 4, 2 nor 1");
+                               return ERROR_COMMAND_SYNTAX_ERROR;
                }
-               jtag_add_dr_out(target->tap,
-                               3,
-                               bits,
-                               t,
-                               TAP_IDLE);
+
+               buf_set_u32(t1, 0, 32, t);
+
+               jtag_add_dr_scan(target->tap,
+                       3,
+                       fields,
+                       TAP_IDLE);
                buffer += size;
        }
 
-       if ((retval = jtag_execute_queue()) != ERROR_OK)
-       {
+       retval = jtag_execute_queue();
+       if (retval != ERROR_OK) {
                LOG_ERROR("JTAG error while sending data to debug handler");
                return retval;
        }
@@ -646,27 +618,27 @@ static int xscale_write_dcsr(struct target *target, int hold_rst, int ext_dbg_br
        jtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask);
        jtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask);
 
-       if ((retval = jtag_execute_queue()) != ERROR_OK)
-       {
+       retval = jtag_execute_queue();
+       if (retval != ERROR_OK) {
                LOG_ERROR("JTAG error while writing DCSR");
                return retval;
        }
 
-       xscale->reg_cache->reg_list[XSCALE_DCSR].dirty = 0;
-       xscale->reg_cache->reg_list[XSCALE_DCSR].valid = 1;
+       xscale->reg_cache->reg_list[XSCALE_DCSR].dirty = false;
+       xscale->reg_cache->reg_list[XSCALE_DCSR].valid = true;
 
        return ERROR_OK;
 }
 
 /* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */
-static unsigned int parity (unsigned int v)
+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;
 }
 
@@ -711,8 +683,7 @@ static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8]
        fields[1].num_bits = 1;
        fields[1].out_value = &cmd;
 
-       for (word = 0; word < 8; word++)
-       {
+       for (word = 0; word < 8; word++) {
                buf_set_u32(packet, 0, 32, buffer[word]);
 
                uint32_t value;
@@ -763,39 +734,29 @@ static int xscale_update_vectors(struct target *target)
 
        uint32_t low_reset_branch, high_reset_branch;
 
-       for (i = 1; i < 8; i++)
-       {
+       for (i = 1; i < 8; i++) {
                /* if there's a static vector specified for this exception, override */
                if (xscale->static_high_vectors_set & (1 << i))
-               {
                        xscale->high_vectors[i] = xscale->static_high_vectors[i];
-               }
-               else
-               {
+               else {
                        retval = target_read_u32(target, 0xffff0000 + 4*i, &xscale->high_vectors[i]);
                        if (retval == ERROR_TARGET_TIMEOUT)
                                return retval;
-                       if (retval != ERROR_OK)
-                       {
+                       if (retval != ERROR_OK) {
                                /* Some of these reads will fail as part of normal execution */
                                xscale->high_vectors[i] = ARMV4_5_B(0xfffffe, 0);
                        }
                }
        }
 
-       for (i = 1; i < 8; i++)
-       {
+       for (i = 1; i < 8; i++) {
                if (xscale->static_low_vectors_set & (1 << i))
-               {
                        xscale->low_vectors[i] = xscale->static_low_vectors[i];
-               }
-               else
-               {
+               else {
                        retval = target_read_u32(target, 0x0 + 4*i, &xscale->low_vectors[i]);
                        if (retval == ERROR_TARGET_TIMEOUT)
                                return retval;
-                       if (retval != ERROR_OK)
-                       {
+                       if (retval != ERROR_OK) {
                                /* Some of these reads will fail as part of normal execution */
                                xscale->low_vectors[i] = ARMV4_5_B(0xfffffe, 0);
                        }
@@ -822,30 +783,27 @@ static int xscale_update_vectors(struct target *target)
 static int xscale_arch_state(struct target *target)
 {
        struct xscale_common *xscale = target_to_xscale(target);
-       struct arm *armv4_5 = &xscale->armv4_5_common;
+       struct arm *arm = &xscale->arm;
 
-       static const char *state[] =
-       {
+       static const char *state[] = {
                "disabled", "enabled"
        };
 
-       static const char *arch_dbg_reason[] =
-       {
+       static const char *arch_dbg_reason[] = {
                "", "\n(processor reset)", "\n(trace buffer full)"
        };
 
-       if (armv4_5->common_magic != ARM_COMMON_MAGIC)
-       {
+       if (arm->common_magic != ARM_COMMON_MAGIC) {
                LOG_ERROR("BUG: called for a non-ARMv4/5 target");
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        arm_arch_state(target);
        LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s%s",
-                        state[xscale->armv4_5_mmu.mmu_enabled],
-                        state[xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
-                        state[xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled],
-                        arch_dbg_reason[xscale->arch_debug_reason]);
+               state[xscale->armv4_5_mmu.mmu_enabled],
+               state[xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
+               state[xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled],
+               arch_dbg_reason[xscale->arch_debug_reason]);
 
        return ERROR_OK;
 }
@@ -854,20 +812,17 @@ static int xscale_poll(struct target *target)
 {
        int retval = ERROR_OK;
 
-       if ((target->state == TARGET_RUNNING) || (target->state == TARGET_DEBUG_RUNNING))
-       {
+       if ((target->state == TARGET_RUNNING) || (target->state == TARGET_DEBUG_RUNNING)) {
                enum target_state previous_state = target->state;
-               if ((retval = xscale_read_tx(target, 0)) == ERROR_OK)
-               {
+               retval = xscale_read_tx(target, 0);
+               if (retval == ERROR_OK) {
 
                        /* there's data to read from the tx register, we entered debug state */
                        target->state = TARGET_HALTED;
 
                        /* process debug entry, fetching current mode regs */
                        retval = xscale_debug_entry(target);
-               }
-               else if (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
-               {
+               } else if (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
                        LOG_USER("error while polling TX register, reset CPU");
                        /* here we "lie" so GDB won't get stuck and a reset can be perfomed */
                        target->state = TARGET_HALTED;
@@ -893,123 +848,124 @@ static int xscale_poll(struct target *target)
 static int xscale_debug_entry(struct target *target)
 {
        struct xscale_common *xscale = target_to_xscale(target);
-       struct arm *armv4_5 = &xscale->armv4_5_common;
+       struct arm *arm = &xscale->arm;
        uint32_t pc;
        uint32_t buffer[10];
-       int i;
+       unsigned i;
        int retval;
        uint32_t moe;
 
        /* clear external dbg break (will be written on next DCSR read) */
        xscale->external_debug_break = 0;
-       if ((retval = xscale_read_dcsr(target)) != ERROR_OK)
+       retval = xscale_read_dcsr(target);
+       if (retval != ERROR_OK)
                return retval;
 
        /* get r0, pc, r1 to r7 and cpsr */
-       if ((retval = xscale_receive(target, buffer, 10)) != ERROR_OK)
+       retval = xscale_receive(target, buffer, 10);
+       if (retval != ERROR_OK)
                return retval;
 
        /* move r0 from buffer to register cache */
-       buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, buffer[0]);
-       armv4_5->core_cache->reg_list[0].dirty = 1;
-       armv4_5->core_cache->reg_list[0].valid = 1;
+       buf_set_u32(arm->core_cache->reg_list[0].value, 0, 32, buffer[0]);
+       arm->core_cache->reg_list[0].dirty = true;
+       arm->core_cache->reg_list[0].valid = true;
        LOG_DEBUG("r0: 0x%8.8" PRIx32 "", buffer[0]);
 
        /* move pc from buffer to register cache */
-       buf_set_u32(armv4_5->pc->value, 0, 32, buffer[1]);
-       armv4_5->pc->dirty = 1;
-       armv4_5->pc->valid = 1;
+       buf_set_u32(arm->pc->value, 0, 32, buffer[1]);
+       arm->pc->dirty = true;
+       arm->pc->valid = true;
        LOG_DEBUG("pc: 0x%8.8" PRIx32 "", buffer[1]);
 
        /* move data from buffer to register cache */
-       for (i = 1; i <= 7; i++)
-       {
-               buf_set_u32(armv4_5->core_cache->reg_list[i].value, 0, 32, buffer[1 + i]);
-               armv4_5->core_cache->reg_list[i].dirty = 1;
-               armv4_5->core_cache->reg_list[i].valid = 1;
+       for (i = 1; i <= 7; i++) {
+               buf_set_u32(arm->core_cache->reg_list[i].value, 0, 32, buffer[1 + i]);
+               arm->core_cache->reg_list[i].dirty = true;
+               arm->core_cache->reg_list[i].valid = true;
                LOG_DEBUG("r%i: 0x%8.8" PRIx32 "", i, buffer[i + 1]);
        }
 
-       arm_set_cpsr(armv4_5, buffer[9]);
+       arm_set_cpsr(arm, buffer[9]);
        LOG_DEBUG("cpsr: 0x%8.8" PRIx32 "", buffer[9]);
 
-       if (!is_arm_mode(armv4_5->core_mode))
-       {
+       if (!is_arm_mode(arm->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",
-                        arm_mode_name(armv4_5->core_mode));
+               arm_mode_name(arm->core_mode));
 
        /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
-       if (armv4_5->spsr) {
+       if (arm->spsr) {
                xscale_receive(target, buffer, 8);
-               buf_set_u32(armv4_5->spsr->value, 0, 32, buffer[7]);
-               armv4_5->spsr->dirty = false;
-               armv4_5->spsr->valid = true;
-       }
-       else
-       {
+               buf_set_u32(arm->spsr->value, 0, 32, buffer[7]);
+               arm->spsr->dirty = false;
+               arm->spsr->valid = true;
+       } else {
                /* r8 to r14, but no spsr */
                xscale_receive(target, buffer, 7);
        }
 
        /* move data from buffer to right banked register in cache */
-       for (i = 8; i <= 14; i++)
-       {
-               struct reg *r = arm_reg_current(armv4_5, i);
+       for (i = 8; i <= 14; i++) {
+               struct reg *r = arm_reg_current(arm, i);
 
                buf_set_u32(r->value, 0, 32, buffer[i - 8]);
                r->dirty = false;
                r->valid = true;
        }
 
+       /* mark xscale regs invalid to ensure they are retrieved from the
+        * debug handler if requested  */
+       for (i = 0; i < xscale->reg_cache->num_regs; i++)
+               xscale->reg_cache->reg_list[i].valid = false;
+
        /* examine debug reason */
        xscale_read_dcsr(target);
        moe = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 2, 3);
 
        /* stored PC (for calculating fixup) */
-       pc = buf_get_u32(armv4_5->pc->value, 0, 32);
+       pc = buf_get_u32(arm->pc->value, 0, 32);
 
-       switch (moe)
-       {
-               case 0x0: /* Processor reset */
+       switch (moe) {
+               case 0x0:       /* Processor reset */
                        target->debug_reason = DBG_REASON_DBGRQ;
                        xscale->arch_debug_reason = XSCALE_DBG_REASON_RESET;
                        pc -= 4;
                        break;
-               case 0x1: /* Instruction breakpoint hit */
+               case 0x1:       /* Instruction breakpoint hit */
                        target->debug_reason = DBG_REASON_BREAKPOINT;
                        xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
                        pc -= 4;
                        break;
-               case 0x2: /* Data breakpoint hit */
+               case 0x2:       /* Data breakpoint hit */
                        target->debug_reason = DBG_REASON_WATCHPOINT;
                        xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
                        pc -= 4;
                        break;
-               case 0x3: /* BKPT instruction executed */
+               case 0x3:       /* BKPT instruction executed */
                        target->debug_reason = DBG_REASON_BREAKPOINT;
                        xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
                        pc -= 4;
                        break;
-               case 0x4: /* Ext. debug event */
+               case 0x4:       /* Ext. debug event */
                        target->debug_reason = DBG_REASON_DBGRQ;
                        xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
                        pc -= 4;
                        break;
-               case 0x5: /* Vector trap occured */
+               case 0x5:       /* Vector trap occured */
                        target->debug_reason = DBG_REASON_BREAKPOINT;
                        xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
                        pc -= 4;
                        break;
-               case 0x6: /* Trace buffer full break */
+               case 0x6:       /* Trace buffer full break */
                        target->debug_reason = DBG_REASON_DBGRQ;
                        xscale->arch_debug_reason = XSCALE_DBG_REASON_TB_FULL;
                        pc -= 4;
                        break;
-               case 0x7: /* Reserved (may flag Hot-Debug support) */
+               case 0x7:       /* Reserved (may flag Hot-Debug support) */
                default:
                        LOG_ERROR("Method of Entry is 'Reserved'");
                        exit(-1);
@@ -1017,44 +973,44 @@ static int xscale_debug_entry(struct target *target)
        }
 
        /* apply PC fixup */
-       buf_set_u32(armv4_5->pc->value, 0, 32, pc);
+       buf_set_u32(arm->pc->value, 0, 32, pc);
 
        /* on the first debug entry, identify cache type */
-       if (xscale->armv4_5_mmu.armv4_5_cache.ctype == -1)
-       {
+       if (xscale->armv4_5_mmu.armv4_5_cache.ctype == -1) {
                uint32_t cache_type_reg;
 
                /* read cp15 cache type register */
                xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CACHETYPE]);
-               cache_type_reg = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CACHETYPE].value, 0, 32);
+               cache_type_reg = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CACHETYPE].value,
+                               0,
+                               32);
 
                armv4_5_identify_cache(cache_type_reg, &xscale->armv4_5_mmu.armv4_5_cache);
        }
 
-       /* examine MMU and Cache settings */
-       /* read cp15 control register */
+       /* examine MMU and Cache settings
+        * read cp15 control register */
        xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
-       xscale->cp15_control_reg = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
+       xscale->cp15_control_reg =
+               buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
        xscale->armv4_5_mmu.mmu_enabled = (xscale->cp15_control_reg & 0x1U) ? 1 : 0;
-       xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (xscale->cp15_control_reg & 0x4U) ? 1 : 0;
-       xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (xscale->cp15_control_reg & 0x1000U) ? 1 : 0;
+       xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled =
+               (xscale->cp15_control_reg & 0x4U) ? 1 : 0;
+       xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled =
+               (xscale->cp15_control_reg & 0x1000U) ? 1 : 0;
 
        /* tracing enabled, read collected trace data */
-       if (xscale->trace.buffer_enabled)
-       {
+       if (xscale->trace.mode != XSCALE_TRACE_DISABLED) {
                xscale_read_trace(target);
-               xscale->trace.buffer_fill--;
 
-               /* resume if we're still collecting trace data */
-               if ((xscale->arch_debug_reason == XSCALE_DBG_REASON_TB_FULL)
-                       && (xscale->trace.buffer_fill > 0))
-               {
-                       xscale_resume(target, 1, 0x0, 1, 0);
-               }
-               else
-               {
-                       xscale->trace.buffer_enabled = 0;
-               }
+               /* Resume if entered debug due to buffer fill and we're still collecting
+                * trace data.  Note that a debug exception due to trace buffer full
+                * can only happen in fill mode. */
+               if (xscale->arch_debug_reason == XSCALE_DBG_REASON_TB_FULL) {
+                       if (--xscale->trace.fill_counter > 0)
+                               xscale_resume(target, 1, 0x0, 1, 0);
+               } else  /* entered debug for other reason; reset counter */
+                       xscale->trace.fill_counter = 0;
        }
 
        return ERROR_OK;
@@ -1065,25 +1021,18 @@ static int xscale_halt(struct target *target)
        struct xscale_common *xscale = target_to_xscale(target);
 
        LOG_DEBUG("target->state: %s",
-                 target_state_name(target));
+               target_state_name(target));
 
-       if (target->state == TARGET_HALTED)
-       {
+       if (target->state == TARGET_HALTED) {
                LOG_DEBUG("target was already halted");
                return ERROR_OK;
-       }
-       else if (target->state == TARGET_UNKNOWN)
-       {
+       } else if (target->state == TARGET_UNKNOWN) {
                /* this must not happen for a xscale target */
                LOG_ERROR("target was in unknown state when halt was requested");
                return ERROR_TARGET_INVALID;
-       }
-       else if (target->state == TARGET_RESET)
-       {
+       } else if (target->state == TARGET_RESET)
                LOG_DEBUG("target->state == TARGET_RESET");
-       }
-       else
-       {
+       else {
                /* assert external dbg break */
                xscale->external_debug_break = 1;
                xscale_read_dcsr(target);
@@ -1100,22 +1049,21 @@ static int xscale_enable_single_step(struct target *target, uint32_t next_pc)
        struct reg *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0];
        int retval;
 
-       if (xscale->ibcr0_used)
-       {
-               struct breakpoint *ibcr0_bp = breakpoint_find(target, buf_get_u32(ibcr0->value, 0, 32) & 0xfffffffe);
+       if (xscale->ibcr0_used) {
+               struct breakpoint *ibcr0_bp =
+                       breakpoint_find(target, buf_get_u32(ibcr0->value, 0, 32) & 0xfffffffe);
 
                if (ibcr0_bp)
-               {
                        xscale_unset_breakpoint(target, ibcr0_bp);
-               }
-               else
-               {
-                       LOG_ERROR("BUG: xscale->ibcr0_used is set, but no breakpoint with that address found");
+               else {
+                       LOG_ERROR(
+                               "BUG: xscale->ibcr0_used is set, but no breakpoint with that address found");
                        exit(-1);
                }
        }
 
-       if ((retval = xscale_set_reg_u32(ibcr0, next_pc | 0x1)) != ERROR_OK)
+       retval = xscale_set_reg_u32(ibcr0, next_pc | 0x1);
+       if (retval != ERROR_OK)
                return retval;
 
        return ERROR_OK;
@@ -1127,7 +1075,8 @@ static int xscale_disable_single_step(struct target *target)
        struct reg *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0];
        int retval;
 
-       if ((retval = xscale_set_reg_u32(ibcr0, 0x0)) != ERROR_OK)
+       retval = xscale_set_reg_u32(ibcr0, 0x0);
+       if (retval != ERROR_OK)
                return retval;
 
        return ERROR_OK;
@@ -1137,8 +1086,7 @@ static void xscale_enable_watchpoints(struct target *target)
 {
        struct watchpoint *watchpoint = target->watchpoints;
 
-       while (watchpoint)
-       {
+       while (watchpoint) {
                if (watchpoint->set == 0)
                        xscale_set_watchpoint(target, watchpoint);
                watchpoint = watchpoint->next;
@@ -1150,73 +1098,84 @@ static void xscale_enable_breakpoints(struct target *target)
        struct breakpoint *breakpoint = target->breakpoints;
 
        /* set any pending breakpoints */
-       while (breakpoint)
-       {
+       while (breakpoint) {
                if (breakpoint->set == 0)
                        xscale_set_breakpoint(target, breakpoint);
                breakpoint = breakpoint->next;
        }
 }
 
+static void xscale_free_trace_data(struct xscale_common *xscale)
+{
+       struct xscale_trace_data *td = xscale->trace.data;
+       while (td) {
+               struct xscale_trace_data *next_td = td->next;
+               if (td->entries)
+                       free(td->entries);
+               free(td);
+               td = next_td;
+       }
+       xscale->trace.data = NULL;
+}
+
 static int xscale_resume(struct target *target, int current,
-               uint32_t address, int handle_breakpoints, int debug_execution)
+       target_addr_t address, int handle_breakpoints, int debug_execution)
 {
        struct xscale_common *xscale = target_to_xscale(target);
-       struct arm *armv4_5 = &xscale->armv4_5_common;
-       struct breakpoint *breakpoint = target->breakpoints;
+       struct arm *arm = &xscale->arm;
        uint32_t current_pc;
        int retval;
        int i;
 
        LOG_DEBUG("-");
 
-       if (target->state != TARGET_HALTED)
-       {
+       if (target->state != TARGET_HALTED) {
                LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
        if (!debug_execution)
-       {
                target_free_all_working_areas(target);
-       }
 
        /* update vector tables */
-       if ((retval = xscale_update_vectors(target)) != ERROR_OK)
+       retval = xscale_update_vectors(target);
+       if (retval != ERROR_OK)
                return retval;
 
        /* current = 1: continue on current pc, otherwise continue at <address> */
        if (!current)
-               buf_set_u32(armv4_5->pc->value, 0, 32, address);
+               buf_set_u32(arm->pc->value, 0, 32, address);
 
-       current_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
+       current_pc = buf_get_u32(arm->pc->value, 0, 32);
 
        /* if we're at the reset vector, we have to simulate the branch */
-       if (current_pc == 0x0)
-       {
+       if (current_pc == 0x0) {
                arm_simulate_step(target, NULL);
-               current_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
+               current_pc = buf_get_u32(arm->pc->value, 0, 32);
        }
 
        /* the front-end may request us not to handle breakpoints */
-       if (handle_breakpoints)
-       {
+       if (handle_breakpoints) {
+               struct breakpoint *breakpoint;
                breakpoint = breakpoint_find(target,
-                               buf_get_u32(armv4_5->pc->value, 0, 32));
-               if (breakpoint != NULL)
-               {
+                               buf_get_u32(arm->pc->value, 0, 32));
+               if (breakpoint != NULL) {
                        uint32_t next_pc;
+                       enum trace_mode saved_trace_mode;
 
                        /* there's a breakpoint at the current PC, we have to step over it */
-                       LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
+                       LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT "",
+                               breakpoint->address);
                        xscale_unset_breakpoint(target, breakpoint);
 
                        /* calculate PC of next instruction */
-                       if ((retval = arm_simulate_step(target, &next_pc)) != ERROR_OK)
-                       {
+                       retval = arm_simulate_step(target, &next_pc);
+                       if (retval != ERROR_OK) {
                                uint32_t current_opcode;
                                target_read_u32(target, current_pc, &current_opcode);
-                               LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32 "", current_opcode);
+                               LOG_ERROR(
+                                       "BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32 "",
+                                       current_opcode);
                        }
 
                        LOG_DEBUG("enable single-step");
@@ -1224,43 +1183,47 @@ static int xscale_resume(struct target *target, int current,
 
                        /* restore banked registers */
                        retval = xscale_restore_banked(target);
+                       if (retval != ERROR_OK)
+                               return retval;
 
-                       /* send resume request (command 0x30 or 0x31)
-                        * clean the trace buffer if it is to be enabled (0x62) */
-                       if (xscale->trace.buffer_enabled)
-                       {
-                               xscale_send_u32(target, 0x62);
-                               xscale_send_u32(target, 0x31);
-                       }
-                       else
-                               xscale_send_u32(target, 0x30);
+                       /* send resume request */
+                       xscale_send_u32(target, 0x30);
 
                        /* send CPSR */
                        xscale_send_u32(target,
-                               buf_get_u32(armv4_5->cpsr->value, 0, 32));
+                               buf_get_u32(arm->cpsr->value, 0, 32));
                        LOG_DEBUG("writing cpsr with value 0x%8.8" PRIx32,
-                               buf_get_u32(armv4_5->cpsr->value, 0, 32));
+                               buf_get_u32(arm->cpsr->value, 0, 32));
 
-                       for (i = 7; i >= 0; i--)
-                       {
+                       for (i = 7; i >= 0; i--) {
                                /* send register */
-                               xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
-                               LOG_DEBUG("writing r%i with value 0x%8.8" PRIx32 "", i, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
+                               xscale_send_u32(target,
+                                       buf_get_u32(arm->core_cache->reg_list[i].value, 0, 32));
+                               LOG_DEBUG("writing r%i with value 0x%8.8" PRIx32 "",
+                                       i, buf_get_u32(arm->core_cache->reg_list[i].value, 0, 32));
                        }
 
                        /* send PC */
                        xscale_send_u32(target,
-                                       buf_get_u32(armv4_5->pc->value, 0, 32));
+                               buf_get_u32(arm->pc->value, 0, 32));
                        LOG_DEBUG("writing PC with value 0x%8.8" PRIx32,
-                                       buf_get_u32(armv4_5->pc->value, 0, 32));
+                               buf_get_u32(arm->pc->value, 0, 32));
+
+                       /* disable trace data collection in xscale_debug_entry() */
+                       saved_trace_mode = xscale->trace.mode;
+                       xscale->trace.mode = XSCALE_TRACE_DISABLED;
 
                        /* wait for and process debug entry */
                        xscale_debug_entry(target);
 
+                       /* re-enable trace buffer, if enabled previously */
+                       xscale->trace.mode = saved_trace_mode;
+
                        LOG_DEBUG("disable single-step");
                        xscale_disable_single_step(target);
 
-                       LOG_DEBUG("set breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
+                       LOG_DEBUG("set breakpoint at " TARGET_ADDR_FMT "",
+                               breakpoint->address);
                        xscale_set_breakpoint(target, breakpoint);
                }
        }
@@ -1271,45 +1234,52 @@ static int xscale_resume(struct target *target, int current,
 
        /* restore banked registers */
        retval = xscale_restore_banked(target);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* send resume request (command 0x30 or 0x31)
         * clean the trace buffer if it is to be enabled (0x62) */
-       if (xscale->trace.buffer_enabled)
-       {
+       if (xscale->trace.mode != XSCALE_TRACE_DISABLED) {
+               if (xscale->trace.mode == XSCALE_TRACE_FILL) {
+                       /* If trace enabled in fill mode and starting collection of new set
+                            * of buffers, initialize buffer counter and free previous buffers */
+                       if (xscale->trace.fill_counter == 0) {
+                               xscale->trace.fill_counter = xscale->trace.buffer_fill;
+                               xscale_free_trace_data(xscale);
+                       }
+               } else  /* wrap mode; free previous buffer */
+                       xscale_free_trace_data(xscale);
+
                xscale_send_u32(target, 0x62);
                xscale_send_u32(target, 0x31);
-       }
-       else
+       } else
                xscale_send_u32(target, 0x30);
 
        /* send CPSR */
-       xscale_send_u32(target, buf_get_u32(armv4_5->cpsr->value, 0, 32));
+       xscale_send_u32(target, buf_get_u32(arm->cpsr->value, 0, 32));
        LOG_DEBUG("writing cpsr with value 0x%8.8" PRIx32,
-                       buf_get_u32(armv4_5->cpsr->value, 0, 32));
+               buf_get_u32(arm->cpsr->value, 0, 32));
 
-       for (i = 7; i >= 0; i--)
-       {
+       for (i = 7; i >= 0; i--) {
                /* send register */
-               xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
-               LOG_DEBUG("writing r%i with value 0x%8.8" PRIx32 "", i, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
+               xscale_send_u32(target, buf_get_u32(arm->core_cache->reg_list[i].value, 0, 32));
+               LOG_DEBUG("writing r%i with value 0x%8.8" PRIx32 "",
+                       i, buf_get_u32(arm->core_cache->reg_list[i].value, 0, 32));
        }
 
        /* send PC */
-       xscale_send_u32(target, buf_get_u32(armv4_5->pc->value, 0, 32));
+       xscale_send_u32(target, buf_get_u32(arm->pc->value, 0, 32));
        LOG_DEBUG("wrote PC with value 0x%8.8" PRIx32,
-                       buf_get_u32(armv4_5->pc->value, 0, 32));
+               buf_get_u32(arm->pc->value, 0, 32));
 
        target->debug_reason = DBG_REASON_NOTHALTED;
 
-       if (!debug_execution)
-       {
+       if (!debug_execution) {
                /* registers are now invalid */
-               register_cache_invalidate(armv4_5->core_cache);
+               register_cache_invalidate(arm->core_cache);
                target->state = TARGET_RUNNING;
                target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
-       }
-       else
-       {
+       } else {
                target->state = TARGET_DEBUG_RUNNING;
                target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
        }
@@ -1320,10 +1290,10 @@ static int xscale_resume(struct target *target, int current,
 }
 
 static int xscale_step_inner(struct target *target, int current,
-               uint32_t address, int handle_breakpoints)
+       uint32_t address, int handle_breakpoints)
 {
        struct xscale_common *xscale = target_to_xscale(target);
-       struct arm *armv4_5 = &xscale->armv4_5_common;
+       struct arm *arm = &xscale->arm;
        uint32_t next_pc;
        int retval;
        int i;
@@ -1331,72 +1301,82 @@ static int xscale_step_inner(struct target *target, int current,
        target->debug_reason = DBG_REASON_SINGLESTEP;
 
        /* calculate PC of next instruction */
-       if ((retval = arm_simulate_step(target, &next_pc)) != ERROR_OK)
-       {
+       retval = arm_simulate_step(target, &next_pc);
+       if (retval != ERROR_OK) {
                uint32_t current_opcode, current_pc;
-               current_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
+               current_pc = buf_get_u32(arm->pc->value, 0, 32);
 
                target_read_u32(target, current_pc, &current_opcode);
-               LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32 "", current_opcode);
+               LOG_ERROR(
+                       "BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32 "",
+                       current_opcode);
                return retval;
        }
 
        LOG_DEBUG("enable single-step");
-       if ((retval = xscale_enable_single_step(target, next_pc)) != ERROR_OK)
+       retval = xscale_enable_single_step(target, next_pc);
+       if (retval != ERROR_OK)
                return retval;
 
        /* restore banked registers */
-       if ((retval = xscale_restore_banked(target)) != ERROR_OK)
+       retval = xscale_restore_banked(target);
+       if (retval != ERROR_OK)
                return retval;
 
        /* send resume request (command 0x30 or 0x31)
         * clean the trace buffer if it is to be enabled (0x62) */
-       if (xscale->trace.buffer_enabled)
-       {
-               if ((retval = xscale_send_u32(target, 0x62)) != ERROR_OK)
+       if (xscale->trace.mode != XSCALE_TRACE_DISABLED) {
+               retval = xscale_send_u32(target, 0x62);
+               if (retval != ERROR_OK)
+                       return retval;
+               retval = xscale_send_u32(target, 0x31);
+               if (retval != ERROR_OK)
                        return retval;
-               if ((retval = xscale_send_u32(target, 0x31)) != ERROR_OK)
+       } else {
+               retval = xscale_send_u32(target, 0x30);
+               if (retval != ERROR_OK)
                        return retval;
        }
-       else
-               if ((retval = xscale_send_u32(target, 0x30)) != ERROR_OK)
-                       return retval;
 
        /* send CPSR */
        retval = xscale_send_u32(target,
-                       buf_get_u32(armv4_5->cpsr->value, 0, 32));
+                       buf_get_u32(arm->cpsr->value, 0, 32));
        if (retval != ERROR_OK)
                return retval;
        LOG_DEBUG("writing cpsr with value 0x%8.8" PRIx32,
-                       buf_get_u32(armv4_5->cpsr->value, 0, 32));
+               buf_get_u32(arm->cpsr->value, 0, 32));
 
-       for (i = 7; i >= 0; i--)
-       {
+       for (i = 7; i >= 0; i--) {
                /* send register */
-               if ((retval = xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32))) != ERROR_OK)
+               retval = xscale_send_u32(target,
+                               buf_get_u32(arm->core_cache->reg_list[i].value, 0, 32));
+               if (retval != ERROR_OK)
                        return retval;
-               LOG_DEBUG("writing r%i with value 0x%8.8" PRIx32 "", i, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
+               LOG_DEBUG("writing r%i with value 0x%8.8" PRIx32 "", i,
+                       buf_get_u32(arm->core_cache->reg_list[i].value, 0, 32));
        }
 
        /* send PC */
        retval = xscale_send_u32(target,
-                       buf_get_u32(armv4_5->pc->value, 0, 32));
+                       buf_get_u32(arm->pc->value, 0, 32));
        if (retval != ERROR_OK)
                return retval;
        LOG_DEBUG("wrote PC with value 0x%8.8" PRIx32,
-                       buf_get_u32(armv4_5->pc->value, 0, 32));
+               buf_get_u32(arm->pc->value, 0, 32));
 
        target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
 
        /* registers are now invalid */
-       register_cache_invalidate(armv4_5->core_cache);
+       register_cache_invalidate(arm->core_cache);
 
        /* wait for and process debug entry */
-       if ((retval = xscale_debug_entry(target)) != ERROR_OK)
+       retval = xscale_debug_entry(target);
+       if (retval != ERROR_OK)
                return retval;
 
        LOG_DEBUG("disable single-step");
-       if ((retval = xscale_disable_single_step(target)) != ERROR_OK)
+       retval = xscale_disable_single_step(target);
+       if (retval != ERROR_OK)
                return retval;
 
        target_call_event_callbacks(target, TARGET_EVENT_HALTED);
@@ -1405,32 +1385,32 @@ static int xscale_step_inner(struct target *target, int current,
 }
 
 static int xscale_step(struct target *target, int current,
-               uint32_t address, int handle_breakpoints)
+       target_addr_t address, int handle_breakpoints)
 {
-       struct arm *armv4_5 = target_to_arm(target);
+       struct arm *arm = target_to_arm(target);
        struct breakpoint *breakpoint = NULL;
 
        uint32_t current_pc;
        int retval;
 
-       if (target->state != TARGET_HALTED)
-       {
+       if (target->state != TARGET_HALTED) {
                LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
        /* current = 1: continue on current pc, otherwise continue at <address> */
        if (!current)
-               buf_set_u32(armv4_5->pc->value, 0, 32, address);
+               buf_set_u32(arm->pc->value, 0, 32, address);
 
-       current_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
+       current_pc = buf_get_u32(arm->pc->value, 0, 32);
 
        /* if we're at the reset vector, we have to simulate the step */
-       if (current_pc == 0x0)
-       {
-               if ((retval = arm_simulate_step(target, NULL)) != ERROR_OK)
+       if (current_pc == 0x0) {
+               retval = arm_simulate_step(target, NULL);
+               if (retval != ERROR_OK)
                        return retval;
-               current_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
+               current_pc = buf_get_u32(arm->pc->value, 0, 32);
+               LOG_DEBUG("current pc %" PRIx32, current_pc);
 
                target->debug_reason = DBG_REASON_SINGLESTEP;
                target_call_event_callbacks(target, TARGET_EVENT_HALTED);
@@ -1441,7 +1421,7 @@ static int xscale_step(struct target *target, int current,
        /* the front-end may request us not to handle breakpoints */
        if (handle_breakpoints)
                breakpoint = breakpoint_find(target,
-                               buf_get_u32(armv4_5->pc->value, 0, 32));
+                               buf_get_u32(arm->pc->value, 0, 32));
        if (breakpoint != NULL) {
                retval = xscale_unset_breakpoint(target, breakpoint);
                if (retval != ERROR_OK)
@@ -1449,11 +1429,11 @@ static int xscale_step(struct target *target, int current,
        }
 
        retval = xscale_step_inner(target, current, address, handle_breakpoints);
+       if (retval != ERROR_OK)
+               return retval;
 
        if (breakpoint)
-       {
                xscale_set_breakpoint(target, breakpoint);
-       }
 
        LOG_DEBUG("target stepped");
 
@@ -1465,8 +1445,22 @@ static int xscale_assert_reset(struct target *target)
 {
        struct xscale_common *xscale = target_to_xscale(target);
 
+       /* TODO: apply hw reset signal in not examined state */
+       if (!(target_was_examined(target))) {
+               LOG_WARNING("Reset is not asserted because the target is not examined.");
+               LOG_WARNING("Use a reset button or power cycle the target.");
+               return ERROR_TARGET_NOT_EXAMINED;
+       }
+
        LOG_DEBUG("target->state: %s",
-                 target_state_name(target));
+               target_state_name(target));
+
+       /* assert reset */
+       jtag_add_reset(0, 1);
+
+       /* sleep 1ms, to be sure we fulfill any requirements */
+       jtag_add_sleep(1000);
+       jtag_execute_queue();
 
        /* select DCSR instruction (set endstate to R-T-I to ensure we don't
         * end up in T-L-R, which would reset JTAG
@@ -1484,21 +1478,13 @@ static int xscale_assert_reset(struct target *target)
        xscale_jtag_set_instr(target->tap, ~0, TAP_IDLE);
        jtag_execute_queue();
 
-       /* assert reset */
-       jtag_add_reset(0, 1);
-
-       /* sleep 1ms, to be sure we fulfill any requirements */
-       jtag_add_sleep(1000);
-       jtag_execute_queue();
-
        target->state = TARGET_RESET;
 
-    if (target->reset_halt)
-    {
-       int retval;
-               if ((retval = target_halt(target)) != ERROR_OK)
+       if (target->reset_halt) {
+               int retval = target_halt(target);
+               if (retval != ERROR_OK)
                        return retval;
-    }
+       }
 
        return ERROR_OK;
 }
@@ -1519,16 +1505,16 @@ static int xscale_deassert_reset(struct target *target)
        xscale->dbr1_used = 0;
 
        /* mark all hardware breakpoints as unset */
-       while (breakpoint)
-       {
+       while (breakpoint) {
                if (breakpoint->type == BKPT_HARD)
-               {
                        breakpoint->set = 0;
-               }
                breakpoint = breakpoint->next;
        }
 
-       register_cache_invalidate(xscale->armv4_5_common.core_cache);
+       xscale->trace.mode = XSCALE_TRACE_DISABLED;
+       xscale_free_trace_data(xscale);
+
+       register_cache_invalidate(xscale->arm.core_cache);
 
        /* FIXME mark hardware watchpoints got unset too.  Also,
         * at least some of the XScale registers are invalid...
@@ -1565,10 +1551,9 @@ static int xscale_deassert_reset(struct target *target)
                 * coprocessors, trace data, etc.
                 */
                address = xscale->handler_address;
-               for (unsigned binary_size = sizeof xscale_debug_handler - 1;
-                               binary_size > 0;
-                               binary_size -= buf_cnt, buffer += buf_cnt)
-               {
+               for (unsigned binary_size = sizeof xscale_debug_handler;
+                       binary_size > 0;
+                       binary_size -= buf_cnt, buffer += buf_cnt) {
                        uint32_t cache_line[8];
                        unsigned i;
 
@@ -1576,20 +1561,16 @@ static int xscale_deassert_reset(struct target *target)
                        if (buf_cnt > 32)
                                buf_cnt = 32;
 
-                       for (i = 0; i < buf_cnt; i += 4)
-                       {
+                       for (i = 0; i < buf_cnt; i += 4) {
                                /* convert LE buffer to host-endian uint32_t */
                                cache_line[i / 4] = le_to_h_u32(&buffer[i]);
                        }
 
                        for (; i < 32; i += 4)
-                       {
                                cache_line[i / 4] = 0xe1a08008;
-                       }
 
                        /* only load addresses other than the reset vectors */
-                       if ((address % 0x400) != 0x0)
-                       {
+                       if ((address % 0x400) != 0x0) {
                                retval = xscale_load_ic(target, address,
                                                cache_line);
                                if (retval != ERROR_OK)
@@ -1597,14 +1578,14 @@ static int xscale_deassert_reset(struct target *target)
                        }
 
                        address += buf_cnt;
-               };
+               }
 
                retval = xscale_load_ic(target, 0x0,
-                                       xscale->low_vectors);
+                               xscale->low_vectors);
                if (retval != ERROR_OK)
                        return retval;
                retval = xscale_load_ic(target, 0xffff0000,
-                                       xscale->high_vectors);
+                               xscale->high_vectors);
                if (retval != ERROR_OK)
                        return retval;
 
@@ -1621,8 +1602,7 @@ static int xscale_deassert_reset(struct target *target)
                xscale_write_dcsr(target, 0, 1);
                target->state = TARGET_RUNNING;
 
-               if (!target->reset_halt)
-               {
+               if (!target->reset_halt) {
                        jtag_add_sleep(10000);
 
                        /* we should have entered debug now */
@@ -1638,7 +1618,7 @@ static int xscale_deassert_reset(struct target *target)
 }
 
 static int xscale_read_core_reg(struct target *target, struct reg *r,
-               int num, enum arm_mode mode)
+       int num, enum arm_mode mode)
 {
        /** \todo add debug handler support for core register reads */
        LOG_ERROR("not implemented");
@@ -1646,7 +1626,7 @@ static int xscale_read_core_reg(struct target *target, struct reg *r,
 }
 
 static int xscale_write_core_reg(struct target *target, struct reg *r,
-               int num, enum arm_mode mode, uint32_t value)
+       int num, enum arm_mode mode, uint8_t *value)
 {
        /** \todo add debug handler support for core register writes */
        LOG_ERROR("not implemented");
@@ -1655,7 +1635,7 @@ static int xscale_write_core_reg(struct target *target, struct reg *r,
 
 static int xscale_full_context(struct target *target)
 {
-       struct arm *armv4_5 = target_to_arm(target);
+       struct arm *arm = target_to_arm(target);
 
        uint32_t *buffer;
 
@@ -1663,8 +1643,7 @@ static int xscale_full_context(struct target *target)
 
        LOG_DEBUG("-");
 
-       if (target->state != TARGET_HALTED)
-       {
+       if (target->state != TARGET_HALTED) {
                LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
@@ -1675,8 +1654,7 @@ static int xscale_full_context(struct target *target)
         * we can't enter User mode on an XScale (unpredictable),
         * but User shares registers with SYS
         */
-       for (i = 1; i < 7; i++)
-       {
+       for (i = 1; i < 7; i++) {
                enum arm_mode mode = armv4_5_number_to_mode(i);
                bool valid = true;
                struct reg *r;
@@ -1686,10 +1664,9 @@ static int xscale_full_context(struct target *target)
 
                /* check if there are invalid registers in the current mode
                 */
-               for (j = 0; valid && j <= 16; j++)
-               {
-                       if (!ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
-                                       mode, j).valid)
+               for (j = 0; valid && j <= 16; j++) {
+                       if (!ARMV4_5_CORE_REG_MODE(arm->core_cache,
+                               mode, j).valid)
                                valid = false;
                }
                if (valid)
@@ -1706,7 +1683,7 @@ static int xscale_full_context(struct target *target)
                 */
                if (mode != ARM_MODE_SYS) {
                        /* SPSR */
-                       r = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
+                       r = &ARMV4_5_CORE_REG_MODE(arm->core_cache,
                                        mode, 16);
 
                        xscale_receive(target, buffer, 8);
@@ -1714,14 +1691,12 @@ static int xscale_full_context(struct target *target)
                        buf_set_u32(r->value, 0, 32, buffer[7]);
                        r->dirty = false;
                        r->valid = true;
-               } else {
+               } else
                        xscale_receive(target, buffer, 7);
-               }
 
                /* move data from buffer to register cache */
-               for (j = 8; j <= 14; j++)
-               {
-                       r = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
+               for (j = 8; j <= 14; j++) {
+                       r = &ARMV4_5_CORE_REG_MODE(arm->core_cache,
                                        mode, j);
 
                        buf_set_u32(r->value, 0, 32, buffer[j - 8]);
@@ -1737,12 +1712,11 @@ static int xscale_full_context(struct target *target)
 
 static int xscale_restore_banked(struct target *target)
 {
-       struct arm *armv4_5 = target_to_arm(target);
+       struct arm *arm = target_to_arm(target);
 
        int i, j;
 
-       if (target->state != TARGET_HALTED)
-       {
+       if (target->state != TARGET_HALTED) {
                LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
@@ -1752,8 +1726,7 @@ static int xscale_restore_banked(struct target *target)
         * USR mode (number 0) in favor of SYS; we can't enter User mode on
         * an XScale (unpredictable), but they share all registers.
         */
-       for (i = 1; i < 7; i++)
-       {
+       for (i = 1; i < 7; i++) {
                enum arm_mode mode = armv4_5_number_to_mode(i);
                struct reg *r;
 
@@ -1761,18 +1734,16 @@ static int xscale_restore_banked(struct target *target)
                        continue;
 
                /* check if there are dirty registers in this mode */
-               for (j = 8; j <= 14; j++)
-               {
-                       if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
-                                       mode, j).dirty)
+               for (j = 8; j <= 14; j++) {
+                       if (ARMV4_5_CORE_REG_MODE(arm->core_cache,
+                               mode, j).dirty)
                                goto dirty;
                }
 
                /* if not USR/SYS, check if the SPSR needs to be written */
-               if (mode != ARM_MODE_SYS)
-               {
-                       if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
-                                       mode, 16).dirty)
+               if (mode != ARM_MODE_SYS) {
+                       if (ARMV4_5_CORE_REG_MODE(arm->core_cache,
+                               mode, 16).dirty)
                                goto dirty;
                }
 
@@ -1790,7 +1761,7 @@ dirty:
                 * but this protocol doesn't understand that nuance.
                 */
                for (j = 8; j <= 14; j++) {
-                       r = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
+                       r = &ARMV4_5_CORE_REG_MODE(arm->core_cache,
                                        mode, j);
                        xscale_send_u32(target, buf_get_u32(r->value, 0, 32));
                        r->dirty = false;
@@ -1798,7 +1769,7 @@ dirty:
 
                /* send spsr if not in USR/SYS mode */
                if (mode != ARM_MODE_SYS) {
-                       r = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
+                       r = &ARMV4_5_CORE_REG_MODE(arm->core_cache,
                                        mode, 16);
                        xscale_send_u32(target, buf_get_u32(r->value, 0, 32));
                        r->dirty = false;
@@ -1808,51 +1779,57 @@ dirty:
        return ERROR_OK;
 }
 
-static int xscale_read_memory(struct target *target, uint32_t address,
-               uint32_t size, uint32_t count, uint8_t *buffer)
+static int xscale_read_memory(struct target *target, target_addr_t address,
+       uint32_t size, uint32_t count, uint8_t *buffer)
 {
        struct xscale_common *xscale = target_to_xscale(target);
        uint32_t *buf32;
        uint32_t i;
        int retval;
 
-       LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32, address, size, count);
+       LOG_DEBUG("address: " TARGET_ADDR_FMT ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32,
+               address,
+               size,
+               count);
 
-       if (target->state != TARGET_HALTED)
-       {
+       if (target->state != TARGET_HALTED) {
                LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
        /* sanitize arguments */
        if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
                return ERROR_TARGET_UNALIGNED_ACCESS;
 
        /* send memory read request (command 0x1n, n: access size) */
-       if ((retval = xscale_send_u32(target, 0x10 | size)) != ERROR_OK)
+       retval = xscale_send_u32(target, 0x10 | size);
+       if (retval != ERROR_OK)
                return retval;
 
        /* send base address for read request */
-       if ((retval = xscale_send_u32(target, address)) != ERROR_OK)
+       retval = xscale_send_u32(target, address);
+       if (retval != ERROR_OK)
                return retval;
 
        /* send number of requested data words */
-       if ((retval = xscale_send_u32(target, count)) != ERROR_OK)
+       retval = xscale_send_u32(target, count);
+       if (retval != ERROR_OK)
                return retval;
 
        /* receive data from target (count times 32-bit words in host endianness) */
        buf32 = malloc(4 * count);
-       if ((retval = xscale_receive(target, buf32, count)) != ERROR_OK)
+       retval = xscale_receive(target, buf32, count);
+       if (retval != ERROR_OK) {
+               free(buf32);
                return retval;
+       }
 
        /* extract data from host-endian buffer into byte stream */
-       for (i = 0; i < count; i++)
-       {
-               switch (size)
-               {
+       for (i = 0; i < count; i++) {
+               switch (size) {
                        case 4:
                                target_buffer_set_u32(target, buffer, buf32[i]);
                                buffer += 4;
@@ -1866,19 +1843,20 @@ static int xscale_read_memory(struct target *target, uint32_t address,
                                break;
                        default:
                                LOG_ERROR("invalid read size");
-                               return ERROR_INVALID_ARGUMENTS;
+                               return ERROR_COMMAND_SYNTAX_ERROR;
                }
        }
 
        free(buf32);
 
        /* examine DCSR, to see if Sticky Abort (SA) got set */
-       if ((retval = xscale_read_dcsr(target)) != ERROR_OK)
+       retval = xscale_read_dcsr(target);
+       if (retval != ERROR_OK)
                return retval;
-       if (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1)
-       {
+       if (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1) {
                /* clear SA bit */
-               if ((retval = xscale_send_u32(target, 0x60)) != ERROR_OK)
+               retval = xscale_send_u32(target, 0x60);
+               if (retval != ERROR_OK)
                        return retval;
 
                return ERROR_TARGET_DATA_ABORT;
@@ -1887,8 +1865,8 @@ static int xscale_read_memory(struct target *target, uint32_t address,
        return ERROR_OK;
 }
 
-static int xscale_read_phys_memory(struct target *target, uint32_t address,
-               uint32_t size, uint32_t count, uint8_t *buffer)
+static int xscale_read_phys_memory(struct target *target, target_addr_t address,
+       uint32_t size, uint32_t count, uint8_t *buffer)
 {
        struct xscale_common *xscale = target_to_xscale(target);
 
@@ -1898,49 +1876,52 @@ static int xscale_read_phys_memory(struct target *target, uint32_t address,
 
        /** \todo: provide a non-stub implementation of this routine. */
        LOG_ERROR("%s: %s is not implemented.  Disable MMU?",
-                       target_name(target), __func__);
+               target_name(target), __func__);
        return ERROR_FAIL;
 }
 
-static int xscale_write_memory(struct target *target, uint32_t address,
-               uint32_t size, uint32_t count, uint8_t *buffer)
+static int xscale_write_memory(struct target *target, target_addr_t address,
+       uint32_t size, uint32_t count, const uint8_t *buffer)
 {
        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);
+       LOG_DEBUG("address: " TARGET_ADDR_FMT ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32,
+               address,
+               size,
+               count);
 
-       if (target->state != TARGET_HALTED)
-       {
+       if (target->state != TARGET_HALTED) {
                LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
        /* sanitize arguments */
        if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
                return ERROR_TARGET_UNALIGNED_ACCESS;
 
        /* send memory write request (command 0x2n, n: access size) */
-       if ((retval = xscale_send_u32(target, 0x20 | size)) != ERROR_OK)
+       retval = xscale_send_u32(target, 0x20 | size);
+       if (retval != ERROR_OK)
                return retval;
 
        /* send base address for read request */
-       if ((retval = xscale_send_u32(target, address)) != ERROR_OK)
+       retval = xscale_send_u32(target, address);
+       if (retval != ERROR_OK)
                return retval;
 
        /* send number of requested data words to be written*/
-       if ((retval = xscale_send_u32(target, count)) != ERROR_OK)
+       retval = xscale_send_u32(target, count);
+       if (retval != ERROR_OK)
                return retval;
 
        /* extract data from host-endian buffer into byte stream */
 #if 0
-       for (i = 0; i < count; i++)
-       {
-               switch (size)
-               {
+       for (i = 0; i < count; i++) {
+               switch (size) {
                        case 4:
                                value = target_buffer_get_u32(target, buffer);
                                xscale_send_u32(target, value);
@@ -1962,103 +1943,120 @@ static int xscale_write_memory(struct target *target, uint32_t address,
                }
        }
 #endif
-       if ((retval = xscale_send(target, buffer, count, size)) != ERROR_OK)
+       retval = xscale_send(target, buffer, count, size);
+       if (retval != ERROR_OK)
                return retval;
 
        /* examine DCSR, to see if Sticky Abort (SA) got set */
-       if ((retval = xscale_read_dcsr(target)) != ERROR_OK)
+       retval = xscale_read_dcsr(target);
+       if (retval != ERROR_OK)
                return retval;
-       if (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1)
-       {
+       if (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1) {
                /* clear SA bit */
-               if ((retval = xscale_send_u32(target, 0x60)) != ERROR_OK)
+               retval = xscale_send_u32(target, 0x60);
+               if (retval != ERROR_OK)
                        return retval;
 
+               LOG_ERROR("data abort writing memory");
                return ERROR_TARGET_DATA_ABORT;
        }
 
        return ERROR_OK;
 }
 
-static int xscale_write_phys_memory(struct target *target, uint32_t address,
-               uint32_t size, uint32_t count, uint8_t *buffer)
+static int xscale_write_phys_memory(struct target *target, target_addr_t address,
+       uint32_t size, uint32_t count, const uint8_t *buffer)
 {
        struct xscale_common *xscale = target_to_xscale(target);
 
        /* with MMU inactive, there are only physical addresses */
        if (!xscale->armv4_5_mmu.mmu_enabled)
-               return xscale_read_memory(target, address, size, count, buffer);
+               return xscale_write_memory(target, address, size, count, buffer);
 
        /** \todo: provide a non-stub implementation of this routine. */
        LOG_ERROR("%s: %s is not implemented.  Disable MMU?",
-                       target_name(target), __func__);
+               target_name(target), __func__);
        return ERROR_FAIL;
 }
 
-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(struct target *target)
+static int xscale_get_ttb(struct target *target, uint32_t *result)
 {
        struct xscale_common *xscale = target_to_xscale(target);
        uint32_t ttb;
+       int retval;
 
-       xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_TTB]);
+       retval = xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_TTB]);
+       if (retval != ERROR_OK)
+               return retval;
        ttb = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_TTB].value, 0, 32);
 
-       return ttb;
+       *result = ttb;
+
+       return ERROR_OK;
 }
 
-static void xscale_disable_mmu_caches(struct target *target, int mmu,
-               int d_u_cache, int i_cache)
+static int xscale_disable_mmu_caches(struct target *target, int mmu,
+       int d_u_cache, int i_cache)
 {
        struct xscale_common *xscale = target_to_xscale(target);
        uint32_t cp15_control;
+       int retval;
 
        /* read cp15 control register */
-       xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
+       retval = xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
+       if (retval != ERROR_OK)
+               return retval;
        cp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
 
        if (mmu)
                cp15_control &= ~0x1U;
 
-       if (d_u_cache)
-       {
+       if (d_u_cache) {
                /* clean DCache */
-               xscale_send_u32(target, 0x50);
-               xscale_send_u32(target, xscale->cache_clean_address);
+               retval = xscale_send_u32(target, 0x50);
+               if (retval != ERROR_OK)
+                       return retval;
+               retval = xscale_send_u32(target, xscale->cache_clean_address);
+               if (retval != ERROR_OK)
+                       return retval;
 
                /* invalidate DCache */
-               xscale_send_u32(target, 0x51);
+               retval = xscale_send_u32(target, 0x51);
+               if (retval != ERROR_OK)
+                       return retval;
 
                cp15_control &= ~0x4U;
        }
 
-       if (i_cache)
-       {
+       if (i_cache) {
                /* invalidate ICache */
-               xscale_send_u32(target, 0x52);
+               retval = xscale_send_u32(target, 0x52);
+               if (retval != ERROR_OK)
+                       return retval;
                cp15_control &= ~0x1000U;
        }
 
        /* write new cp15 control register */
-       xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
+       retval = xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* execute cpwait to ensure outstanding operations complete */
-       xscale_send_u32(target, 0x53);
+       retval = xscale_send_u32(target, 0x53);
+       return retval;
 }
 
-static void xscale_enable_mmu_caches(struct target *target, int mmu,
-               int d_u_cache, int i_cache)
+static int xscale_enable_mmu_caches(struct target *target, int mmu,
+       int d_u_cache, int i_cache)
 {
        struct xscale_common *xscale = target_to_xscale(target);
        uint32_t cp15_control;
+       int retval;
 
        /* read cp15 control register */
-       xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
+       retval = xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
+       if (retval != ERROR_OK)
+               return retval;
        cp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
 
        if (mmu)
@@ -2071,160 +2069,147 @@ static void xscale_enable_mmu_caches(struct target *target, int mmu,
                cp15_control |= 0x1000U;
 
        /* write new cp15 control register */
-       xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
+       retval = xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* execute cpwait to ensure outstanding operations complete */
-       xscale_send_u32(target, 0x53);
+       retval = xscale_send_u32(target, 0x53);
+       return retval;
 }
 
 static int xscale_set_breakpoint(struct target *target,
-               struct breakpoint *breakpoint)
+       struct breakpoint *breakpoint)
 {
        int retval;
        struct xscale_common *xscale = target_to_xscale(target);
 
-       if (target->state != TARGET_HALTED)
-       {
+       if (target->state != TARGET_HALTED) {
                LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       if (breakpoint->set)
-       {
+       if (breakpoint->set) {
                LOG_WARNING("breakpoint already set");
                return ERROR_OK;
        }
 
-       if (breakpoint->type == BKPT_HARD)
-       {
+       if (breakpoint->type == BKPT_HARD) {
                uint32_t value = breakpoint->address | 1;
-               if (!xscale->ibcr0_used)
-               {
+               if (!xscale->ibcr0_used) {
                        xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], value);
                        xscale->ibcr0_used = 1;
                        breakpoint->set = 1;    /* breakpoint set on first breakpoint register */
-               }
-               else if (!xscale->ibcr1_used)
-               {
+               } else if (!xscale->ibcr1_used) {
                        xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], value);
                        xscale->ibcr1_used = 1;
                        breakpoint->set = 2;    /* breakpoint set on second breakpoint register */
-               }
-               else
-               {
+               } else {/* bug: availability previously verified in xscale_add_breakpoint() */
                        LOG_ERROR("BUG: no hardware comparator available");
-                       return ERROR_OK;
+                       return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
                }
-       }
-       else if (breakpoint->type == BKPT_SOFT)
-       {
-               if (breakpoint->length == 4)
-               {
+       } else if (breakpoint->type == BKPT_SOFT) {
+               if (breakpoint->length == 4) {
                        /* keep the original instruction in target endianness */
-                       if ((retval = target_read_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr)) != ERROR_OK)
-                       {
+                       retval = target_read_memory(target, breakpoint->address, 4, 1,
+                                       breakpoint->orig_instr);
+                       if (retval != ERROR_OK)
                                return retval;
-                       }
-                       /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
-                       if ((retval = target_write_u32(target, breakpoint->address, xscale->arm_bkpt)) != ERROR_OK)
-                       {
+                       /* write the bkpt instruction in target endianness
+                        *(arm7_9->arm_bkpt is host endian) */
+                       retval = target_write_u32(target, breakpoint->address,
+                                       xscale->arm_bkpt);
+                       if (retval != ERROR_OK)
                                return retval;
-                       }
-               }
-               else
-               {
+               } else {
                        /* keep the original instruction in target endianness */
-                       if ((retval = target_read_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr)) != ERROR_OK)
-                       {
+                       retval = target_read_memory(target, breakpoint->address, 2, 1,
+                                       breakpoint->orig_instr);
+                       if (retval != ERROR_OK)
                                return retval;
-                       }
-                       /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
-                       if ((retval = target_write_u32(target, breakpoint->address, xscale->thumb_bkpt)) != ERROR_OK)
-                       {
+                       /* write the bkpt instruction in target endianness
+                        *(arm7_9->arm_bkpt is host endian) */
+                       retval = target_write_u16(target, breakpoint->address,
+                                       xscale->thumb_bkpt);
+                       if (retval != ERROR_OK)
                                return retval;
-                       }
                }
                breakpoint->set = 1;
+
+               xscale_send_u32(target, 0x50);  /* clean dcache */
+               xscale_send_u32(target, xscale->cache_clean_address);
+               xscale_send_u32(target, 0x51);  /* invalidate dcache */
+               xscale_send_u32(target, 0x52);  /* invalidate icache and flush fetch buffers */
        }
 
        return ERROR_OK;
 }
 
 static int xscale_add_breakpoint(struct target *target,
-               struct breakpoint *breakpoint)
+       struct breakpoint *breakpoint)
 {
        struct xscale_common *xscale = target_to_xscale(target);
 
-       if ((breakpoint->type == BKPT_HARD) && (xscale->ibcr_available < 1))
-       {
-               LOG_INFO("no breakpoint unit available for hardware breakpoint");
+       if ((breakpoint->type == BKPT_HARD) && (xscale->ibcr_available < 1)) {
+               LOG_ERROR("no breakpoint unit available for hardware breakpoint");
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
 
-       if ((breakpoint->length != 2) && (breakpoint->length != 4))
-       {
-               LOG_INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
+       if ((breakpoint->length != 2) && (breakpoint->length != 4)) {
+               LOG_ERROR("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
 
        if (breakpoint->type == BKPT_HARD)
-       {
                xscale->ibcr_available--;
-       }
 
-       return ERROR_OK;
+       return xscale_set_breakpoint(target, breakpoint);
 }
 
 static int xscale_unset_breakpoint(struct target *target,
-               struct breakpoint *breakpoint)
+       struct breakpoint *breakpoint)
 {
        int retval;
        struct xscale_common *xscale = target_to_xscale(target);
 
-       if (target->state != TARGET_HALTED)
-       {
+       if (target->state != TARGET_HALTED) {
                LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       if (!breakpoint->set)
-       {
+       if (!breakpoint->set) {
                LOG_WARNING("breakpoint not set");
                return ERROR_OK;
        }
 
-       if (breakpoint->type == BKPT_HARD)
-       {
-               if (breakpoint->set == 1)
-               {
+       if (breakpoint->type == BKPT_HARD) {
+               if (breakpoint->set == 1) {
                        xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], 0x0);
                        xscale->ibcr0_used = 0;
-               }
-               else if (breakpoint->set == 2)
-               {
+               } else if (breakpoint->set == 2) {
                        xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], 0x0);
                        xscale->ibcr1_used = 0;
                }
                breakpoint->set = 0;
-       }
-       else
-       {
+       } else {
                /* restore original instruction (kept in target endianness) */
-               if (breakpoint->length == 4)
-               {
-                       if ((retval = target_write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr)) != ERROR_OK)
-                       {
+               if (breakpoint->length == 4) {
+                       retval = target_write_memory(target, breakpoint->address, 4, 1,
+                                       breakpoint->orig_instr);
+                       if (retval != ERROR_OK)
                                return retval;
-                       }
-               }
-               else
-               {
-                       if ((retval = target_write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr)) != ERROR_OK)
-                       {
+               } else {
+                       retval = target_write_memory(target, breakpoint->address, 2, 1,
+                                       breakpoint->orig_instr);
+                       if (retval != ERROR_OK)
                                return retval;
-                       }
                }
                breakpoint->set = 0;
+
+               xscale_send_u32(target, 0x50);  /* clean dcache */
+               xscale_send_u32(target, xscale->cache_clean_address);
+               xscale_send_u32(target, 0x51);  /* invalidate dcache */
+               xscale_send_u32(target, 0x52);  /* invalidate icache and flush fetch buffers */
        }
 
        return ERROR_OK;
@@ -2234,16 +2219,13 @@ static int xscale_remove_breakpoint(struct target *target, struct breakpoint *br
 {
        struct xscale_common *xscale = target_to_xscale(target);
 
-       if (target->state != TARGET_HALTED)
-       {
-               LOG_WARNING("target not halted");
+       if (target->state != TARGET_HALTED) {
+               LOG_ERROR("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
        if (breakpoint->set)
-       {
                xscale_unset_breakpoint(target, breakpoint);
-       }
 
        if (breakpoint->type == BKPT_HARD)
                xscale->ibcr_available++;
@@ -2252,23 +2234,19 @@ static int xscale_remove_breakpoint(struct target *target, struct breakpoint *br
 }
 
 static int xscale_set_watchpoint(struct target *target,
-               struct watchpoint *watchpoint)
+       struct watchpoint *watchpoint)
 {
        struct xscale_common *xscale = target_to_xscale(target);
-       uint8_t enable = 0;
+       uint32_t enable = 0;
        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)
-       {
-               LOG_WARNING("target not halted");
+       if (target->state != TARGET_HALTED) {
+               LOG_ERROR("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       xscale_get_reg(dbcon);
-
-       switch (watchpoint->rw)
-       {
+       switch (watchpoint->rw) {
                case WPT_READ:
                        enable = 0x3;
                        break;
@@ -2282,78 +2260,111 @@ static int xscale_set_watchpoint(struct target *target,
                        LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
        }
 
-       if (!xscale->dbr0_used)
-       {
+       /* For watchpoint across more than one word, both DBR registers must
+          be enlisted, with the second used as a mask. */
+       if (watchpoint->length > 4) {
+               if (xscale->dbr0_used || xscale->dbr1_used) {
+                       LOG_ERROR("BUG: sufficient hardware comparators unavailable");
+                       return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+               }
+
+               /* Write mask value to DBR1, based on the length argument.
+                * Address bits ignored by the comparator are those set in mask. */
+               xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR1],
+                       watchpoint->length - 1);
+               xscale->dbr1_used = 1;
+               enable |= 0x100;                /* DBCON[M] */
+       }
+
+       if (!xscale->dbr0_used) {
                xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR0], watchpoint->address);
                dbcon_value |= enable;
                xscale_set_reg_u32(dbcon, dbcon_value);
                watchpoint->set = 1;
                xscale->dbr0_used = 1;
-       }
-       else if (!xscale->dbr1_used)
-       {
+       } else if (!xscale->dbr1_used) {
                xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR1], watchpoint->address);
                dbcon_value |= enable << 2;
                xscale_set_reg_u32(dbcon, dbcon_value);
                watchpoint->set = 2;
                xscale->dbr1_used = 1;
-       }
-       else
-       {
+       } else {
                LOG_ERROR("BUG: no hardware comparator available");
-               return ERROR_OK;
+               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
 
        return ERROR_OK;
 }
 
 static int xscale_add_watchpoint(struct target *target,
-               struct watchpoint *watchpoint)
+       struct watchpoint *watchpoint)
 {
        struct xscale_common *xscale = target_to_xscale(target);
 
-       if (xscale->dbr_available < 1)
-       {
+       if (xscale->dbr_available < 1) {
+               LOG_ERROR("no more watchpoint registers available");
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
 
-       if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
-       {
+       if (watchpoint->value)
+               LOG_WARNING("xscale does not support value, mask arguments; ignoring");
+
+       /* check that length is a power of two */
+       for (uint32_t len = watchpoint->length; len != 1; len /= 2) {
+               if (len % 2) {
+                       LOG_ERROR("xscale requires that watchpoint length is a power of two");
+                       return ERROR_COMMAND_ARGUMENT_INVALID;
+               }
+       }
+
+       if (watchpoint->length == 4) {  /* single word watchpoint */
+               xscale->dbr_available--;/* one DBR reg used */
+               return ERROR_OK;
+       }
+
+       /* watchpoints across multiple words require both DBR registers */
+       if (xscale->dbr_available < 2) {
+               LOG_ERROR("insufficient watchpoint registers available");
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
 
-       xscale->dbr_available--;
+       if (watchpoint->length > watchpoint->address) {
+               LOG_ERROR("xscale does not support watchpoints with length "
+                       "greater than address");
+               return ERROR_COMMAND_ARGUMENT_INVALID;
+       }
 
+       xscale->dbr_available = 0;
        return ERROR_OK;
 }
 
 static int xscale_unset_watchpoint(struct target *target,
-               struct watchpoint *watchpoint)
+       struct watchpoint *watchpoint)
 {
        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)
-       {
+       if (target->state != TARGET_HALTED) {
                LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       if (!watchpoint->set)
-       {
+       if (!watchpoint->set) {
                LOG_WARNING("breakpoint not set");
                return ERROR_OK;
        }
 
-       if (watchpoint->set == 1)
-       {
-               dbcon_value &= ~0x3;
+       if (watchpoint->set == 1) {
+               if (watchpoint->length > 4) {
+                       dbcon_value &= ~0x103;  /* clear DBCON[M] as well */
+                       xscale->dbr1_used = 0;  /* DBR1 was used for mask */
+               } else
+                       dbcon_value &= ~0x3;
+
                xscale_set_reg_u32(dbcon, dbcon_value);
                xscale->dbr0_used = 0;
-       }
-       else if (watchpoint->set == 2)
-       {
+       } else if (watchpoint->set == 2) {
                dbcon_value &= ~0xc;
                xscale_set_reg_u32(dbcon, dbcon_value);
                xscale->dbr1_used = 0;
@@ -2367,16 +2378,16 @@ static int xscale_remove_watchpoint(struct target *target, struct watchpoint *wa
 {
        struct xscale_common *xscale = target_to_xscale(target);
 
-       if (target->state != TARGET_HALTED)
-       {
-               LOG_WARNING("target not halted");
+       if (target->state != TARGET_HALTED) {
+               LOG_ERROR("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
        if (watchpoint->set)
-       {
                xscale_unset_watchpoint(target, watchpoint);
-       }
+
+       if (watchpoint->length > 4)
+               xscale->dbr_available++;/* both DBR regs now available */
 
        xscale->dbr_available++;
 
@@ -2391,27 +2402,18 @@ static int xscale_get_reg(struct reg *reg)
 
        /* DCSR, TX and RX are accessible via JTAG */
        if (strcmp(reg->name, "XSCALE_DCSR") == 0)
-       {
                return xscale_read_dcsr(arch_info->target);
-       }
-       else if (strcmp(reg->name, "XSCALE_TX") == 0)
-       {
+       else if (strcmp(reg->name, "XSCALE_TX") == 0) {
                /* 1 = consume register content */
                return xscale_read_tx(arch_info->target, 1);
-       }
-       else if (strcmp(reg->name, "XSCALE_RX") == 0)
-       {
+       } else if (strcmp(reg->name, "XSCALE_RX") == 0) {
                /* can't read from RX register (host -> debug handler) */
                return ERROR_OK;
-       }
-       else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0)
-       {
+       } else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0) {
                /* can't (explicitly) read from TXRXCTRL register */
                return ERROR_OK;
-       }
-       else /* Other DBG registers have to be transfered by the debug handler */
-       {
-               /* send CP read request (command 0x40) */
+       } else {/* Other DBG registers have to be transfered by the debug handler
+                * send CP read request (command 0x40) */
                xscale_send_u32(target, 0x40);
 
                /* send CP register number */
@@ -2421,14 +2423,14 @@ static int xscale_get_reg(struct reg *reg)
                xscale_read_tx(target, 1);
                buf_cpy(xscale->reg_cache->reg_list[XSCALE_TX].value, reg->value, 32);
 
-               reg->dirty = 0;
-               reg->valid = 1;
+               reg->dirty = false;
+               reg->valid = true;
        }
 
        return ERROR_OK;
 }
 
-static int xscale_set_reg(struct reg *reg, uint8_tbuf)
+static int xscale_set_reg(struct reg *reg, uint8_t *buf)
 {
        struct xscale_reg *arch_info = reg->arch_info;
        struct target *target = arch_info->target;
@@ -2436,29 +2438,20 @@ static int xscale_set_reg(struct reg *reg, uint8_t* buf)
        uint32_t value = buf_get_u32(buf, 0, 32);
 
        /* DCSR, TX and RX are accessible via JTAG */
-       if (strcmp(reg->name, "XSCALE_DCSR") == 0)
-       {
+       if (strcmp(reg->name, "XSCALE_DCSR") == 0) {
                buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32, value);
                return xscale_write_dcsr(arch_info->target, -1, -1);
-       }
-       else if (strcmp(reg->name, "XSCALE_RX") == 0)
-       {
+       } else if (strcmp(reg->name, "XSCALE_RX") == 0) {
                buf_set_u32(xscale->reg_cache->reg_list[XSCALE_RX].value, 0, 32, value);
                return xscale_write_rx(arch_info->target);
-       }
-       else if (strcmp(reg->name, "XSCALE_TX") == 0)
-       {
+       } else if (strcmp(reg->name, "XSCALE_TX") == 0) {
                /* can't write to TX register (debug-handler -> host) */
                return ERROR_OK;
-       }
-       else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0)
-       {
+       } else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0) {
                /* can't (explicitly) write to TXRXCTRL register */
                return ERROR_OK;
-       }
-       else /* Other DBG registers have to be transfered by the debug handler */
-       {
-               /* send CP write request (command 0x41) */
+       } else {/* Other DBG registers have to be transfered by the debug handler
+                * send CP write request (command 0x41) */
                xscale_send_u32(target, 0x41);
 
                /* send CP register number */
@@ -2494,7 +2487,7 @@ static int xscale_write_dcsr_sw(struct target *target, uint32_t value)
 static int xscale_read_trace(struct target *target)
 {
        struct xscale_common *xscale = target_to_xscale(target);
-       struct arm *armv4_5 = &xscale->armv4_5_common;
+       struct arm *arm = &xscale->arm;
        struct xscale_trace_data **trace_data_p;
 
        /* 258 words from debug handler
@@ -2504,9 +2497,9 @@ static int xscale_read_trace(struct target *target)
        uint32_t trace_buffer[258];
        int is_address[256];
        int i, j;
+       unsigned int num_checkpoints = 0;
 
-       if (target->state != TARGET_HALTED)
-       {
+       if (target->state != TARGET_HALTED) {
                LOG_WARNING("target must be stopped to read trace data");
                return ERROR_TARGET_NOT_HALTED;
        }
@@ -2518,48 +2511,64 @@ static int xscale_read_trace(struct target *target)
        xscale_receive(target, trace_buffer, 258);
 
        /* parse buffer backwards to identify address entries */
-       for (i = 255; i >= 0; i--)
-       {
+       for (i = 255; i >= 0; i--) {
+               /* also count number of checkpointed entries */
+               if ((trace_buffer[i] & 0xe0) == 0xc0)
+                       num_checkpoints++;
+
                is_address[i] = 0;
                if (((trace_buffer[i] & 0xf0) == 0x90) ||
-                       ((trace_buffer[i] & 0xf0) == 0xd0))
-               {
-                       if (i >= 3)
+                       ((trace_buffer[i] & 0xf0) == 0xd0)) {
+                       if (i > 0)
                                is_address[--i] = 1;
-                       if (i >= 2)
+                       if (i > 0)
                                is_address[--i] = 1;
-                       if (i >= 1)
+                       if (i > 0)
                                is_address[--i] = 1;
-                       if (i >= 0)
+                       if (i > 0)
                                is_address[--i] = 1;
                }
        }
 
 
-       /* search first non-zero entry */
+       /* search first non-zero entry that is not part of an address */
        for (j = 0; (j < 256) && (trace_buffer[j] == 0) && (!is_address[j]); j++)
                ;
 
-       if (j == 256)
-       {
+       if (j == 256) {
                LOG_DEBUG("no trace data collected");
                return ERROR_XSCALE_NO_TRACE_DATA;
        }
 
-       for (trace_data_p = &xscale->trace.data; *trace_data_p; trace_data_p = &(*trace_data_p)->next)
+       /* account for possible partial address at buffer start (wrap mode only) */
+       if (is_address[0]) {    /* first entry is address; complete set of 4? */
+               i = 1;
+               while (i < 4)
+                       if (!is_address[i++])
+                               break;
+               if (i < 4)
+                       j += i;         /* partial address; can't use it */
+       }
+
+       /* if first valid entry is indirect branch, can't use that either (no address) */
+       if (((trace_buffer[j] & 0xf0) == 0x90) || ((trace_buffer[j] & 0xf0) == 0xd0))
+               j++;
+
+       /* walk linked list to terminating entry */
+       for (trace_data_p = &xscale->trace.data; *trace_data_p;
+               trace_data_p = &(*trace_data_p)->next)
                ;
 
        *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->pc->value, 0, 32);
+       (*trace_data_p)->last_instruction = buf_get_u32(arm->pc->value, 0, 32);
        (*trace_data_p)->entries = malloc(sizeof(struct xscale_trace_entry) * (256 - j));
        (*trace_data_p)->depth = 256 - j;
+       (*trace_data_p)->num_checkpoints = num_checkpoints;
 
-       for (i = j; i < 256; i++)
-       {
+       for (i = j; i < 256; i++) {
                (*trace_data_p)->entries[i - j].data = trace_buffer[i];
                if (is_address[i])
                        (*trace_data_p)->entries[i - j].type = XSCALE_TRACE_ADDRESS;
@@ -2570,10 +2579,10 @@ static int xscale_read_trace(struct target *target)
        return ERROR_OK;
 }
 
-static int xscale_read_instruction(struct target *target,
-               struct arm_instruction *instruction)
+static int xscale_read_instruction(struct target *target, uint32_t pc,
+       struct arm_instruction *instruction)
 {
-       struct xscale_common *xscale = target_to_xscale(target);
+       struct xscale_common *const xscale = target_to_xscale(target);
        int i;
        int section = -1;
        size_t size_read;
@@ -2584,50 +2593,43 @@ static int xscale_read_instruction(struct target *target,
                return ERROR_TRACE_IMAGE_UNAVAILABLE;
 
        /* search for the section the current instruction belongs to */
-       for (i = 0; i < xscale->trace.image->num_sections; i++)
-       {
-               if ((xscale->trace.image->sections[i].base_address <= xscale->trace.current_pc) &&
-                       (xscale->trace.image->sections[i].base_address + xscale->trace.image->sections[i].size > xscale->trace.current_pc))
-               {
+       for (i = 0; i < xscale->trace.image->num_sections; i++) {
+               if ((xscale->trace.image->sections[i].base_address <= pc) &&
+                       (xscale->trace.image->sections[i].base_address +
+                       xscale->trace.image->sections[i].size > pc)) {
                        section = i;
                        break;
                }
        }
 
-       if (section == -1)
-       {
+       if (section == -1) {
                /* current instruction couldn't be found in the image */
                return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
        }
 
-       if (xscale->trace.core_state == ARM_STATE_ARM)
-       {
+       if (xscale->trace.core_state == ARM_STATE_ARM) {
                uint8_t buf[4];
-               if ((retval = image_read_section(xscale->trace.image, section,
-                       xscale->trace.current_pc - xscale->trace.image->sections[section].base_address,
-                       4, buf, &size_read)) != ERROR_OK)
-               {
-                       LOG_ERROR("error while reading instruction: %i", retval);
+               retval = image_read_section(xscale->trace.image, section,
+                               pc - xscale->trace.image->sections[section].base_address,
+                               4, buf, &size_read);
+               if (retval != ERROR_OK) {
+                       LOG_ERROR("error while reading instruction");
                        return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
                }
                opcode = target_buffer_get_u32(target, buf);
-               arm_evaluate_opcode(opcode, xscale->trace.current_pc, instruction);
-       }
-       else if (xscale->trace.core_state == ARM_STATE_THUMB)
-       {
+               arm_evaluate_opcode(opcode, pc, instruction);
+       } else if (xscale->trace.core_state == ARM_STATE_THUMB) {
                uint8_t buf[2];
-               if ((retval = image_read_section(xscale->trace.image, section,
-                       xscale->trace.current_pc - xscale->trace.image->sections[section].base_address,
-                       2, buf, &size_read)) != ERROR_OK)
-               {
-                       LOG_ERROR("error while reading instruction: %i", retval);
+               retval = image_read_section(xscale->trace.image, section,
+                               pc - xscale->trace.image->sections[section].base_address,
+                               2, buf, &size_read);
+               if (retval != ERROR_OK) {
+                       LOG_ERROR("error while reading instruction");
                        return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
                }
                opcode = target_buffer_get_u16(target, buf);
-               thumb_evaluate_opcode(opcode, xscale->trace.current_pc, instruction);
-       }
-       else
-       {
+               thumb_evaluate_opcode(opcode, pc, instruction);
+       } else {
                LOG_ERROR("BUG: unknown core state encountered");
                exit(-1);
        }
@@ -2635,53 +2637,69 @@ static int xscale_read_instruction(struct target *target,
        return ERROR_OK;
 }
 
-static int xscale_branch_address(struct xscale_trace_data *trace_data,
-               int i, uint32_t *target)
+/* Extract address encoded into trace data.
+ * Write result to address referenced by argument 'target', or 0 if incomplete.  */
+static inline void 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
         * we can't extract the address */
        if (i < 4)
-       {
-               return -1;
+               *target = 0;
+       else {
+               *target = (trace_data->entries[i-1].data) | (trace_data->entries[i-2].data << 8) |
+                       (trace_data->entries[i-3].data << 16) | (trace_data->entries[i-4].data << 24);
        }
+}
 
-       *target = (trace_data->entries[i-1].data) | (trace_data->entries[i-2].data << 8) |
-                               (trace_data->entries[i-3].data << 16) | (trace_data->entries[i-4].data << 24);
-
-       return 0;
+static inline void xscale_display_instruction(struct target *target, uint32_t pc,
+       struct arm_instruction *instruction,
+       struct command_context *cmd_ctx)
+{
+       int retval = xscale_read_instruction(target, pc, instruction);
+       if (retval == ERROR_OK)
+               command_print(cmd_ctx, "%s", instruction->text);
+       else
+               command_print(cmd_ctx, "0x%8.8" PRIx32 "\t<not found in image>", pc);
 }
 
 static int xscale_analyze_trace(struct target *target, struct command_context *cmd_ctx)
 {
        struct xscale_common *xscale = target_to_xscale(target);
-       int next_pc_ok = 0;
-       uint32_t next_pc = 0x0;
        struct xscale_trace_data *trace_data = xscale->trace.data;
-       int retval;
+       int i, retval;
+       uint32_t breakpoint_pc = 0;
+       struct arm_instruction instruction;
+       uint32_t current_pc = 0;/* initialized when address determined */
 
-       while (trace_data)
-       {
-               int i, chkpt;
-               int rollover;
-               int branch;
-               int exception;
+       if (!xscale->trace.image)
+               LOG_WARNING("No trace image loaded; use 'xscale trace_image'");
+
+       /* loop for each trace buffer that was loaded from target */
+       while (trace_data) {
+               int chkpt = 0;  /* incremented as checkpointed entries found */
+               int j;
+
+               /* FIXME: set this to correct mode when trace buffer is first enabled */
                xscale->trace.core_state = ARM_STATE_ARM;
 
-               chkpt = 0;
-               rollover = 0;
+               /* loop for each entry in this trace buffer */
+               for (i = 0; i < trace_data->depth; i++) {
+                       int exception = 0;
+                       uint32_t chkpt_reg = 0x0;
+                       uint32_t branch_target = 0;
+                       int count;
 
-               for (i = 0; i < trace_data->depth; i++)
-               {
-                       next_pc_ok = 0;
-                       branch = 0;
-                       exception = 0;
+                       /* trace entry type is upper nybble of 'message byte' */
+                       int trace_msg_type = (trace_data->entries[i].data & 0xf0) >> 4;
 
+                       /* Target addresses of indirect branches are written into buffer
+                        * before the message byte representing the branch. Skip past it */
                        if (trace_data->entries[i].type == XSCALE_TRACE_ADDRESS)
                                continue;
 
-                       switch ((trace_data->entries[i].data & 0xf0) >> 4)
-                       {
-                               case 0:         /* Exceptions */
+                       switch (trace_msg_type) {
+                               case 0: /* Exceptions */
                                case 1:
                                case 2:
                                case 3:
@@ -2690,149 +2708,155 @@ static int xscale_analyze_trace(struct target *target, struct command_context *c
                                case 6:
                                case 7:
                                        exception = (trace_data->entries[i].data & 0x70) >> 4;
-                                       next_pc_ok = 1;
-                                       next_pc = (trace_data->entries[i].data & 0xf0) >> 2;
-                                       command_print(cmd_ctx, "--- exception %i ---", (trace_data->entries[i].data & 0xf0) >> 4);
+
+                                       /* FIXME: vector table may be at ffff0000 */
+                                       branch_target = (trace_data->entries[i].data & 0xf0) >> 2;
                                        break;
-                               case 8:         /* Direct Branch */
-                                       branch = 1;
+
+                               case 8: /* Direct Branch */
                                        break;
-                               case 9:         /* Indirect Branch */
-                                       branch = 1;
-                                       if (xscale_branch_address(trace_data, i, &next_pc) == 0)
-                                       {
-                                               next_pc_ok = 1;
-                                       }
+
+                               case 9: /* Indirect Branch */
+                                       xscale_branch_address(trace_data, i, &branch_target);
                                        break;
+
                                case 13:        /* Checkpointed Indirect Branch */
-                                       if (xscale_branch_address(trace_data, i, &next_pc) == 0)
-                                       {
-                                               next_pc_ok = 1;
-                                               if (((chkpt == 0) && (next_pc != trace_data->chkpt0))
-                                                       || ((chkpt == 1) && (next_pc != trace_data->chkpt1)))
-                                                       LOG_WARNING("checkpointed indirect branch target address doesn't match checkpoint");
-                                       }
-                                       /* explicit fall-through */
+                                       xscale_branch_address(trace_data, i, &branch_target);
+                                       if ((trace_data->num_checkpoints == 2) && (chkpt == 0))
+                                               chkpt_reg = trace_data->chkpt1; /* 2 chkpts, this is
+                                                                                *oldest */
+                                       else
+                                               chkpt_reg = trace_data->chkpt0; /* 1 chkpt, or 2 and
+                                                                                *newest */
+
+                                       chkpt++;
+                                       break;
+
                                case 12:        /* Checkpointed Direct Branch */
-                                       branch = 1;
-                                       if (chkpt == 0)
-                                       {
-                                               next_pc_ok = 1;
-                                               next_pc = trace_data->chkpt0;
-                                               chkpt++;
-                                       }
-                                       else if (chkpt == 1)
-                                       {
-                                               next_pc_ok = 1;
-                                               next_pc = trace_data->chkpt0;
-                                               chkpt++;
-                                       }
+                                       if ((trace_data->num_checkpoints == 2) && (chkpt == 0))
+                                               chkpt_reg = trace_data->chkpt1; /* 2 chkpts, this is
+                                                                                *oldest */
                                        else
-                                       {
-                                               LOG_WARNING("more than two checkpointed branches encountered");
-                                       }
+                                               chkpt_reg = trace_data->chkpt0; /* 1 chkpt, or 2 and
+                                                                                *newest */
+
+                                       /* if no current_pc, checkpoint will be starting point */
+                                       if (current_pc == 0)
+                                               branch_target = chkpt_reg;
+
+                                       chkpt++;
                                        break;
-                               case 15:        /* Roll-over */
-                                       rollover++;
+
+                               case 15:/* Roll-over */
+                                       break;
+
+                               default:/* Reserved */
+                                       LOG_WARNING("trace is suspect: invalid trace message byte");
                                        continue;
-                               default:        /* Reserved */
-                                       command_print(cmd_ctx, "--- reserved trace message ---");
-                                       LOG_ERROR("BUG: trace message %i is reserved", (trace_data->entries[i].data & 0xf0) >> 4);
-                                       return ERROR_OK;
-                       }
 
-                       if (xscale->trace.pc_ok)
-                       {
-                               int executed = (trace_data->entries[i].data & 0xf) + rollover * 16;
-                               struct arm_instruction instruction;
+                       }
 
-                               if ((exception == 6) || (exception == 7))
-                               {
-                                       /* IRQ or FIQ exception, no instruction executed */
-                                       executed -= 1;
-                               }
+                       /* If we don't have the current_pc yet, but we did get the branch target
+                        * (either from the trace buffer on indirect branch, or from a checkpoint reg),
+                        * then we can start displaying instructions at the next iteration, with
+                        * branch_target as the starting point.
+                        */
+                       if (current_pc == 0) {
+                               current_pc = branch_target;     /* remains 0 unless branch_target *obtained */
+                               continue;
+                       }
 
-                               while (executed-- >= 0)
-                               {
-                                       if ((retval = xscale_read_instruction(target, &instruction)) != ERROR_OK)
-                                       {
-                                               /* can't continue tracing with no image available */
-                                               if (retval == ERROR_TRACE_IMAGE_UNAVAILABLE)
-                                               {
-                                                       return retval;
-                                               }
-                                               else if (retval == ERROR_TRACE_INSTRUCTION_UNAVAILABLE)
-                                               {
-                                                       /* TODO: handle incomplete images */
-                                               }
-                                       }
-
-                                       /* a precise abort on a load to the PC is included in the incremental
-                                        * word count, other instructions causing data aborts are not included
-                                        */
-                                       if ((executed == 0) && (exception == 4)
-                                               && ((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDM)))
-                                       {
-                                               if ((instruction.type == ARM_LDM)
-                                                       && ((instruction.info.load_store_multiple.register_list & 0x8000) == 0))
-                                               {
-                                                       executed--;
-                                               }
-                                               else if (((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDRSH))
-                                                       && (instruction.info.load_store.Rd != 15))
-                                               {
-                                                       executed--;
-                                               }
-                                       }
-
-                                       /* only the last instruction executed
-                                        * (the one that caused the control flow change)
-                                        * could be a taken branch
-                                        */
-                                       if (((executed == -1) && (branch == 1)) &&
-                                               (((instruction.type == ARM_B) ||
-                                                       (instruction.type == ARM_BL) ||
-                                                       (instruction.type == ARM_BLX)) &&
-                                                       (instruction.info.b_bl_bx_blx.target_address != 0xffffffff)))
-                                       {
-                                               xscale->trace.current_pc = instruction.info.b_bl_bx_blx.target_address;
-                                       }
-                                       else
-                                       {
-                                               xscale->trace.current_pc += (xscale->trace.core_state == ARM_STATE_ARM) ? 4 : 2;
-                                       }
-                                       command_print(cmd_ctx, "%s", instruction.text);
-                               }
+                       /* We have current_pc.  Read and display the instructions from the image.
+                        * First, display count instructions (lower nybble of message byte). */
+                       count = trace_data->entries[i].data & 0x0f;
+                       for (j = 0; j < count; j++) {
+                               xscale_display_instruction(target, current_pc, &instruction,
+                                       cmd_ctx);
+                               current_pc += xscale->trace.core_state == ARM_STATE_ARM ? 4 : 2;
+                       }
 
-                               rollover = 0;
+                       /* An additional instruction is implicitly added to count for
+                        * rollover and some exceptions: undef, swi, prefetch abort. */
+                       if ((trace_msg_type == 15) || (exception > 0 && exception < 4)) {
+                               xscale_display_instruction(target, current_pc, &instruction,
+                                       cmd_ctx);
+                               current_pc += xscale->trace.core_state == ARM_STATE_ARM ? 4 : 2;
                        }
 
-                       if (next_pc_ok)
-                       {
-                               xscale->trace.current_pc = next_pc;
-                               xscale->trace.pc_ok = 1;
+                       if (trace_msg_type == 15)       /* rollover */
+                               continue;
+
+                       if (exception) {
+                               command_print(cmd_ctx, "--- exception %i ---", exception);
+                               continue;
                        }
-               }
 
-               for (; xscale->trace.current_pc < trace_data->last_instruction; xscale->trace.current_pc += (xscale->trace.core_state == ARM_STATE_ARM) ? 4 : 2)
-               {
-                       struct arm_instruction instruction;
-                       if ((retval = xscale_read_instruction(target, &instruction)) != ERROR_OK)
-                       {
-                               /* can't continue tracing with no image available */
-                               if (retval == ERROR_TRACE_IMAGE_UNAVAILABLE)
-                               {
-                                       return retval;
-                               }
-                               else if (retval == ERROR_TRACE_INSTRUCTION_UNAVAILABLE)
-                               {
-                                       /* TODO: handle incomplete images */
+                       /* not exception or rollover; next instruction is a branch and is
+                        * not included in the count */
+                       xscale_display_instruction(target, current_pc, &instruction, cmd_ctx);
+
+                       /* for direct branches, extract branch destination from instruction */
+                       if ((trace_msg_type == 8) || (trace_msg_type == 12)) {
+                               retval = xscale_read_instruction(target, current_pc, &instruction);
+                               if (retval == ERROR_OK)
+                                       current_pc = instruction.info.b_bl_bx_blx.target_address;
+                               else
+                                       current_pc = 0; /* branch destination unknown */
+
+                               /* direct branch w/ checkpoint; can also get from checkpoint reg */
+                               if (trace_msg_type == 12) {
+                                       if (current_pc == 0)
+                                               current_pc = chkpt_reg;
+                                       else if (current_pc != chkpt_reg)       /* sanity check */
+                                               LOG_WARNING("trace is suspect: checkpoint register "
+                                                       "inconsistent with adddress from image");
                                }
+
+                               if (current_pc == 0)
+                                       command_print(cmd_ctx, "address unknown");
+
+                               continue;
                        }
-                       command_print(cmd_ctx, "%s", instruction.text);
-               }
 
+                       /* indirect branch; the branch destination was read from trace buffer */
+                       if ((trace_msg_type == 9) || (trace_msg_type == 13)) {
+                               current_pc = branch_target;
+
+                               /* sanity check (checkpoint reg is redundant) */
+                               if ((trace_msg_type == 13) && (chkpt_reg != branch_target))
+                                       LOG_WARNING("trace is suspect: checkpoint register "
+                                               "inconsistent with address from trace buffer");
+                       }
+
+               }       /* END: for (i = 0; i < trace_data->depth; i++) */
+
+               breakpoint_pc = trace_data->last_instruction;   /* used below */
                trace_data = trace_data->next;
+
+       }       /* END: while (trace_data) */
+
+       /* Finally... display all instructions up to the value of the pc when the
+        * debug break occurred (saved when trace data was collected from target).
+        * This is necessary because the trace only records execution branches and 16
+        * consecutive instructions (rollovers), so last few typically missed.
+        */
+       if (current_pc == 0)
+               return ERROR_OK;/* current_pc was never found */
+
+       /* how many instructions remaining? */
+       int gap_count = (breakpoint_pc - current_pc) /
+               (xscale->trace.core_state == ARM_STATE_ARM ? 4 : 2);
+
+       /* should never be negative or over 16, but verify */
+       if (gap_count < 0 || gap_count > 16) {
+               LOG_WARNING("trace is suspect: excessive gap at end of trace");
+               return ERROR_OK;/* bail; large number or negative value no good */
+       }
+
+       /* display remaining instructions */
+       for (i = 0; i < gap_count; i++) {
+               xscale_display_instruction(target, current_pc, &instruction, cmd_ctx);
+               current_pc += xscale->trace.core_state == ARM_STATE_ARM ? 4 : 2;
        }
 
        return ERROR_OK;
@@ -2846,13 +2870,13 @@ static const struct reg_arch_type xscale_reg_type = {
 static void xscale_build_reg_cache(struct target *target)
 {
        struct xscale_common *xscale = target_to_xscale(target);
-       struct arm *armv4_5 = &xscale->armv4_5_common;
+       struct arm *arm = &xscale->arm;
        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 = ARRAY_SIZE(xscale_reg_arch_info);
 
-       (*cache_p) = arm_build_reg_cache(target, armv4_5);
+       (*cache_p) = arm_build_reg_cache(target, arm);
 
        (*cache_p)->next = malloc(sizeof(struct reg_cache));
        cache_p = &(*cache_p)->next;
@@ -2863,12 +2887,11 @@ static void xscale_build_reg_cache(struct target *target)
        (*cache_p)->reg_list = malloc(num_regs * sizeof(struct reg));
        (*cache_p)->num_regs = num_regs;
 
-       for (i = 0; i < num_regs; i++)
-       {
+       for (i = 0; i < num_regs; i++) {
                (*cache_p)->reg_list[i].name = xscale_reg_list[i];
                (*cache_p)->reg_list[i].value = calloc(4, 1);
-               (*cache_p)->reg_list[i].dirty = 0;
-               (*cache_p)->reg_list[i].valid = 0;
+               (*cache_p)->reg_list[i].dirty = false;
+               (*cache_p)->reg_list[i].valid = false;
                (*cache_p)->reg_list[i].size = 32;
                (*cache_p)->reg_list[i].arch_info = &arch_info[i];
                (*cache_p)->reg_list[i].type = &xscale_reg_type;
@@ -2880,51 +2903,25 @@ static void xscale_build_reg_cache(struct target *target)
 }
 
 static int xscale_init_target(struct command_context *cmd_ctx,
-               struct target *target)
+       struct target *target)
 {
        xscale_build_reg_cache(target);
        return ERROR_OK;
 }
 
 static int xscale_init_arch_info(struct target *target,
-               struct xscale_common *xscale, struct jtag_tap *tap, const char *variant)
+       struct xscale_common *xscale, struct jtag_tap *tap)
 {
-       struct arm *armv4_5;
+       struct arm *arm;
        uint32_t high_reset_branch, low_reset_branch;
        int i;
 
-       armv4_5 = &xscale->armv4_5_common;
+       arm = &xscale->arm;
 
        /* store architecture specfic data */
        xscale->common_magic = XSCALE_COMMON_MAGIC;
 
-       /* we don't really *need* a variant param ... */
-       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 if (strcmp(variant, "pxa3xx") == 0)
-                       ir_length = 11;
-               else
-                       LOG_WARNING("%s: unrecognized variant %s",
-                               tap->dotted_name, variant);
-
-               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;
-               }
-       }
-
-       /* PXA3xx shifts the JTAG instructions */
+       /* PXA3xx with 11 bit IR shifts the JTAG instructions */
        if (tap->ir_length == 11)
                xscale->xscale_variant = XSCALE_PXA3XX;
        else
@@ -2948,8 +2945,7 @@ static int xscale_init_arch_info(struct target *target,
        xscale->low_vectors[0] = ARMV4_5_B((low_reset_branch & 0xffffff), 0);
        xscale->high_vectors[0] = ARMV4_5_B((high_reset_branch & 0xffffff), 0);
 
-       for (i = 1; i <= 7; i++)
-       {
+       for (i = 1; i <= 7; i++) {
                xscale->low_vectors[i] = ARMV4_5_B(0xfffffe, 0);
                xscale->high_vectors[i] = ARMV4_5_B(0xfffffe, 0);
        }
@@ -2969,26 +2965,27 @@ static int xscale_init_arch_info(struct target *target,
        xscale->dbr1_used = 0;
 
        LOG_INFO("%s: hardware has 2 breakpoints and 2 watchpoints",
-                       target_name(target));
+               target_name(target));
 
        xscale->arm_bkpt = ARMV5_BKPT(0x0);
        xscale->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
 
        xscale->vector_catch = 0x1;
 
-       xscale->trace.capture_status = TRACE_IDLE;
        xscale->trace.data = NULL;
        xscale->trace.image = NULL;
-       xscale->trace.buffer_enabled = 0;
+       xscale->trace.mode = XSCALE_TRACE_DISABLED;
        xscale->trace.buffer_fill = 0;
+       xscale->trace.fill_counter = 0;
 
        /* prepare ARMv4/5 specific information */
-       armv4_5->arch_info = xscale;
-       armv4_5->read_core_reg = xscale_read_core_reg;
-       armv4_5->write_core_reg = xscale_write_core_reg;
-       armv4_5->full_context = xscale_full_context;
+       arm->arch_info = xscale;
+       arm->core_type = ARM_MODE_ANY;
+       arm->read_core_reg = xscale_read_core_reg;
+       arm->write_core_reg = xscale_write_core_reg;
+       arm->full_context = xscale_full_context;
 
-       arm_init_arch_info(target, armv4_5);
+       arm_init_arch_info(target, arm);
 
        xscale->armv4_5_mmu.armv4_5_cache.ctype = -1;
        xscale->armv4_5_mmu.get_ttb = xscale_get_ttb;
@@ -3006,7 +3003,7 @@ static int xscale_target_create(struct target *target, Jim_Interp *interp)
 {
        struct xscale_common *xscale;
 
-       if (sizeof xscale_debug_handler - 1 > 0x800) {
+       if (sizeof xscale_debug_handler > 0x800) {
                LOG_ERROR("debug_handler.bin: larger than 2kb");
                return ERROR_FAIL;
        }
@@ -3015,8 +3012,7 @@ static int xscale_target_create(struct target *target, Jim_Interp *interp)
        if (!xscale)
                return ERROR_FAIL;
 
-       return xscale_init_arch_info(target, xscale, target->tap,
-                       target->variant);
+       return xscale_init_arch_info(target, xscale, target->tap);
 }
 
 COMMAND_HANDLER(xscale_handle_debug_handler_command)
@@ -3027,13 +3023,10 @@ COMMAND_HANDLER(xscale_handle_debug_handler_command)
        uint32_t handler_address;
 
        if (CMD_ARGC < 2)
-       {
-               LOG_ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
-               return ERROR_OK;
-       }
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
-       if ((target = get_target(CMD_ARGV[0])) == NULL)
-       {
+       target = get_target(CMD_ARGV[0]);
+       if (target == NULL) {
                LOG_ERROR("target '%s' not defined", CMD_ARGV[0]);
                return ERROR_FAIL;
        }
@@ -3047,12 +3040,10 @@ COMMAND_HANDLER(xscale_handle_debug_handler_command)
 
        if (((handler_address >= 0x800) && (handler_address <= 0x1fef800)) ||
                ((handler_address >= 0xfe000800) && (handler_address <= 0xfffff800)))
-       {
                xscale->handler_address = handler_address;
-       }
-       else
-       {
-               LOG_ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
+       else {
+               LOG_ERROR(
+                       "xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
                return ERROR_FAIL;
        }
 
@@ -3067,13 +3058,10 @@ COMMAND_HANDLER(xscale_handle_cache_clean_address_command)
        uint32_t cache_clean_address;
 
        if (CMD_ARGC < 2)
-       {
                return ERROR_COMMAND_SYNTAX_ERROR;
-       }
 
        target = get_target(CMD_ARGV[0]);
-       if (target == NULL)
-       {
+       if (target == NULL) {
                LOG_ERROR("target '%s' not defined", CMD_ARGV[0]);
                return ERROR_FAIL;
        }
@@ -3085,13 +3073,9 @@ COMMAND_HANDLER(xscale_handle_cache_clean_address_command)
        COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cache_clean_address);
 
        if (cache_clean_address & 0xffff)
-       {
                LOG_ERROR("xscale cache_clean_address <address> must be 64kb aligned");
-       }
        else
-       {
                xscale->cache_clean_address = cache_clean_address;
-       }
 
        return ERROR_OK;
 }
@@ -3110,24 +3094,21 @@ COMMAND_HANDLER(xscale_handle_cache_info_command)
 }
 
 static int xscale_virt2phys(struct target *target,
-               uint32_t virtual, uint32_t *physical)
+       target_addr_t virtual, target_addr_t *physical)
 {
        struct xscale_common *xscale = target_to_xscale(target);
-       int type;
        uint32_t cb;
-       int domain;
-       uint32_t ap;
 
        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)
-       {
-               return ret;
-       }
+       uint32_t ret;
+       int retval = armv4_5_mmu_translate_va(target, &xscale->armv4_5_mmu,
+                       virtual, &cb, &ret);
+       if (retval != ERROR_OK)
+               return retval;
        *physical = ret;
        return ERROR_OK;
 }
@@ -3136,8 +3117,7 @@ static int xscale_mmu(struct target *target, int *enabled)
 {
        struct xscale_common *xscale = target_to_xscale(target);
 
-       if (target->state != TARGET_HALTED)
-       {
+       if (target->state != TARGET_HALTED) {
                LOG_ERROR("Target not halted");
                return ERROR_TARGET_INVALID;
        }
@@ -3155,14 +3135,12 @@ COMMAND_HANDLER(xscale_handle_mmu_command)
        if (retval != ERROR_OK)
                return retval;
 
-       if (target->state != TARGET_HALTED)
-       {
+       if (target->state != TARGET_HALTED) {
                command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
                return ERROR_OK;
        }
 
-       if (CMD_ARGC >= 1)
-       {
+       if (CMD_ARGC >= 1) {
                bool enable;
                COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
                if (enable)
@@ -3172,7 +3150,8 @@ COMMAND_HANDLER(xscale_handle_mmu_command)
                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;
 }
@@ -3186,8 +3165,7 @@ COMMAND_HANDLER(xscale_handle_idcache_command)
        if (retval != ERROR_OK)
                return retval;
 
-       if (target->state != TARGET_HALTED)
-       {
+       if (target->state != TARGET_HALTED) {
                command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
                return ERROR_OK;
        }
@@ -3195,8 +3173,7 @@ COMMAND_HANDLER(xscale_handle_idcache_command)
        bool icache = false;
        if (strcmp(CMD_NAME, "icache") == 0)
                icache = true;
-       if (CMD_ARGC >= 1)
-       {
+       if (CMD_ARGC >= 1) {
                bool enable;
                COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
                if (icache) {
@@ -3215,36 +3192,74 @@ COMMAND_HANDLER(xscale_handle_idcache_command)
        }
 
        bool enabled = icache ?
-                                       xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled :
-                                       xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled;
+               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 const struct {
+       char name[15];
+       unsigned mask;
+} vec_ids[] = {
+       { "fiq",                DCSR_TF, },
+       { "irq",                DCSR_TI, },
+       { "dabt",               DCSR_TD, },
+       { "pabt",               DCSR_TA, },
+       { "swi",                DCSR_TS, },
+       { "undef",              DCSR_TU, },
+       { "reset",              DCSR_TR, },
+};
+
 COMMAND_HANDLER(xscale_handle_vector_catch_command)
 {
        struct target *target = get_current_target(CMD_CTX);
        struct xscale_common *xscale = target_to_xscale(target);
        int retval;
+       uint32_t dcsr_value;
+       uint32_t catch = 0;
+       struct reg *dcsr_reg = &xscale->reg_cache->reg_list[XSCALE_DCSR];
 
        retval = xscale_verify_pointer(CMD_CTX, xscale);
        if (retval != ERROR_OK)
                return retval;
 
-       if (CMD_ARGC < 1)
-       {
-               command_print(CMD_CTX, "usage: xscale vector_catch [mask]");
-       }
-       else
-       {
-               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);
+       dcsr_value = buf_get_u32(dcsr_reg->value, 0, 32);
+       if (CMD_ARGC > 0) {
+               if (CMD_ARGC == 1) {
+                       if (strcmp(CMD_ARGV[0], "all") == 0) {
+                               catch = DCSR_TRAP_MASK;
+                               CMD_ARGC--;
+                       } else if (strcmp(CMD_ARGV[0], "none") == 0) {
+                               catch = 0;
+                               CMD_ARGC--;
+                       }
+               }
+               while (CMD_ARGC-- > 0) {
+                       unsigned i;
+                       for (i = 0; i < ARRAY_SIZE(vec_ids); i++) {
+                               if (strcmp(CMD_ARGV[CMD_ARGC], vec_ids[i].name))
+                                       continue;
+                               catch |= vec_ids[i].mask;
+                               break;
+                       }
+                       if (i == ARRAY_SIZE(vec_ids)) {
+                               LOG_ERROR("No vector '%s'", CMD_ARGV[CMD_ARGC]);
+                               return ERROR_COMMAND_SYNTAX_ERROR;
+                       }
+               }
+               buf_set_u32(dcsr_reg->value, 0, 32,
+                               (buf_get_u32(dcsr_reg->value, 0, 32) & ~DCSR_TRAP_MASK) | catch);
                xscale_write_dcsr(target, -1, -1);
        }
 
-       command_print(CMD_CTX, "vector catch mask: 0x%2.2x", xscale->vector_catch);
+       dcsr_value = buf_get_u32(dcsr_reg->value, 0, 32);
+       for (unsigned i = 0; i < ARRAY_SIZE(vec_ids); i++) {
+               command_print(CMD_CTX, "%15s: %s", vec_ids[i].name,
+                       (dcsr_value & vec_ids[i].mask) ? "catch" : "ignore");
+       }
 
        return ERROR_OK;
 }
@@ -3261,24 +3276,28 @@ COMMAND_HANDLER(xscale_handle_vector_table_command)
        if (retval != ERROR_OK)
                return retval;
 
-       if (CMD_ARGC == 0) /* print current settings */
-       {
+       if (CMD_ARGC == 0) {    /* print current settings */
                int idx;
 
                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 (CMD_ARGC != 3)
                err = 1;
-       else
-       {
+       else {
                int idx;
                COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], idx);
                uint32_t vec;
@@ -3287,22 +3306,18 @@ COMMAND_HANDLER(xscale_handle_vector_table_command)
                if (idx < 1 || idx >= 8)
                        err = 1;
 
-               if (!err && strcmp(CMD_ARGV[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(CMD_ARGV[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;
-               }
-               else
+               } else
                        err = 1;
        }
 
        if (err)
-               command_print(CMD_CTX, "usage: xscale vector_table <high|low> <index> <code>");
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        return ERROR_OK;
 }
@@ -3312,7 +3327,6 @@ COMMAND_HANDLER(xscale_handle_trace_buffer_command)
 {
        struct target *target = get_current_target(CMD_CTX);
        struct xscale_common *xscale = target_to_xscale(target);
-       struct arm *armv4_5 = &xscale->armv4_5_common;
        uint32_t dcsr_value;
        int retval;
 
@@ -3320,67 +3334,51 @@ COMMAND_HANDLER(xscale_handle_trace_buffer_command)
        if (retval != ERROR_OK)
                return retval;
 
-       if (target->state != TARGET_HALTED)
-       {
+       if (target->state != TARGET_HALTED) {
                command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
                return ERROR_OK;
        }
 
-       if ((CMD_ARGC >= 1) && (strcmp("enable", CMD_ARGV[0]) == 0))
-       {
-               struct xscale_trace_data *td, *next_td;
-               xscale->trace.buffer_enabled = 1;
-
-               /* free old trace data */
-               td = xscale->trace.data;
-               while (td)
-               {
-                       next_td = td->next;
-
-                       if (td->entries)
-                               free(td->entries);
-                       free(td);
-                       td = next_td;
+       if (CMD_ARGC >= 1) {
+               if (strcmp("enable", CMD_ARGV[0]) == 0)
+                       xscale->trace.mode = XSCALE_TRACE_WRAP; /* default */
+               else if (strcmp("disable", CMD_ARGV[0]) == 0)
+                       xscale->trace.mode = XSCALE_TRACE_DISABLED;
+               else
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       if (CMD_ARGC >= 2 && xscale->trace.mode != XSCALE_TRACE_DISABLED) {
+               if (strcmp("fill", CMD_ARGV[1]) == 0) {
+                       int buffcount = 1;              /* default */
+                       if (CMD_ARGC >= 3)
+                               COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], buffcount);
+                       if (buffcount < 1) {            /* invalid */
+                               command_print(CMD_CTX, "fill buffer count must be > 0");
+                               xscale->trace.mode = XSCALE_TRACE_DISABLED;
+                               return ERROR_COMMAND_SYNTAX_ERROR;
+                       }
+                       xscale->trace.buffer_fill = buffcount;
+                       xscale->trace.mode = XSCALE_TRACE_FILL;
+               } else if (strcmp("wrap", CMD_ARGV[1]) == 0)
+                       xscale->trace.mode = XSCALE_TRACE_WRAP;
+               else {
+                       xscale->trace.mode = XSCALE_TRACE_DISABLED;
+                       return ERROR_COMMAND_SYNTAX_ERROR;
                }
-               xscale->trace.data = NULL;
-       }
-       else if ((CMD_ARGC >= 1) && (strcmp("disable", CMD_ARGV[0]) == 0))
-       {
-               xscale->trace.buffer_enabled = 0;
-       }
-
-       if ((CMD_ARGC >= 2) && (strcmp("fill", CMD_ARGV[1]) == 0))
-       {
-               uint32_t fill = 1;
-               if (CMD_ARGC >= 3)
-                       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], fill);
-               xscale->trace.buffer_fill = fill;
-       }
-       else if ((CMD_ARGC >= 2) && (strcmp("wrap", CMD_ARGV[1]) == 0))
-       {
-               xscale->trace.buffer_fill = -1;
-       }
-
-       if (xscale->trace.buffer_enabled)
-       {
-               /* if we enable the trace buffer in fill-once
-                * mode we know the address of the first instruction */
-               xscale->trace.pc_ok = 1;
-               xscale->trace.current_pc =
-                               buf_get_u32(armv4_5->pc->value, 0, 32);
-       }
-       else
-       {
-               /* otherwise the address is unknown, and we have no known good PC */
-               xscale->trace.pc_ok = 0;
        }
 
-       command_print(CMD_CTX, "trace buffer %s (%s)",
-               (xscale->trace.buffer_enabled) ? "enabled" : "disabled",
-               (xscale->trace.buffer_fill > 0) ? "fill" : "wrap");
+       if (xscale->trace.mode != XSCALE_TRACE_DISABLED) {
+               char fill_string[12];
+               sprintf(fill_string, "fill %d", xscale->trace.buffer_fill);
+               command_print(CMD_CTX, "trace buffer enabled (%s)",
+                       (xscale->trace.mode == XSCALE_TRACE_FILL)
+                       ? fill_string : "wrap");
+       } else
+               command_print(CMD_CTX, "trace buffer disabled");
 
        dcsr_value = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32);
-       if (xscale->trace.buffer_fill >= 0)
+       if (xscale->trace.mode == XSCALE_TRACE_FILL)
                xscale_write_dcsr_sw(target, (dcsr_value & 0xfffffffc) | 2);
        else
                xscale_write_dcsr_sw(target, dcsr_value & 0xfffffffc);
@@ -3395,17 +3393,13 @@ COMMAND_HANDLER(xscale_handle_trace_image_command)
        int retval;
 
        if (CMD_ARGC < 1)
-       {
-               command_print(CMD_CTX, "usage: xscale trace_image <file> [base address] [type]");
-               return ERROR_OK;
-       }
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        retval = xscale_verify_pointer(CMD_CTX, xscale);
        if (retval != ERROR_OK)
                return retval;
 
-       if (xscale->trace.image)
-       {
+       if (xscale->trace.image) {
                image_close(xscale->trace.image);
                free(xscale->trace.image);
                command_print(CMD_CTX, "previously loaded image found and closed");
@@ -3416,18 +3410,14 @@ COMMAND_HANDLER(xscale_handle_trace_image_command)
        xscale->trace.image->start_address_set = 0;
 
        /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
-       if (CMD_ARGC >= 2)
-       {
+       if (CMD_ARGC >= 2) {
                xscale->trace.image->base_address_set = 1;
                COMMAND_PARSE_NUMBER(llong, CMD_ARGV[1], xscale->trace.image->base_address);
-       }
-       else
-       {
+       } else
                xscale->trace.image->base_address_set = 0;
-       }
 
-       if (image_open(xscale->trace.image, CMD_ARGV[0], (CMD_ARGC >= 3) ? CMD_ARGV[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;
                return ERROR_OK;
@@ -3441,54 +3431,47 @@ COMMAND_HANDLER(xscale_handle_dump_trace_command)
        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;
+       struct fileio *file;
        int retval;
 
        retval = xscale_verify_pointer(CMD_CTX, xscale);
        if (retval != ERROR_OK)
                return retval;
 
-       if (target->state != TARGET_HALTED)
-       {
+       if (target->state != TARGET_HALTED) {
                command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
                return ERROR_OK;
        }
 
        if (CMD_ARGC < 1)
-       {
-               command_print(CMD_CTX, "usage: xscale dump_trace <file>");
-               return ERROR_OK;
-       }
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        trace_data = xscale->trace.data;
 
-       if (!trace_data)
-       {
+       if (!trace_data) {
                command_print(CMD_CTX, "no trace data collected");
                return ERROR_OK;
        }
 
        if (fileio_open(&file, CMD_ARGV[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
-       {
                return ERROR_OK;
-       }
 
-       while (trace_data)
-       {
+       while (trace_data) {
                int i;
 
-               fileio_write_u32(&file, trace_data->chkpt0);
-               fileio_write_u32(&file, trace_data->chkpt1);
-               fileio_write_u32(&file, trace_data->last_instruction);
-               fileio_write_u32(&file, trace_data->depth);
+               fileio_write_u32(file, trace_data->chkpt0);
+               fileio_write_u32(file, trace_data->chkpt1);
+               fileio_write_u32(file, trace_data->last_instruction);
+               fileio_write_u32(file, trace_data->depth);
 
                for (i = 0; i < trace_data->depth; i++)
-                       fileio_write_u32(&file, trace_data->entries[i].data | ((trace_data->entries[i].type & 0xffff) << 16));
+                       fileio_write_u32(file, trace_data->entries[i].data |
+                               ((trace_data->entries[i].type & 0xffff) << 16));
 
                trace_data = trace_data->next;
        }
 
-       fileio_close(&file);
+       fileio_close(file);
 
        return ERROR_OK;
 }
@@ -3518,61 +3501,56 @@ COMMAND_HANDLER(xscale_handle_cp15)
        if (retval != ERROR_OK)
                return retval;
 
-       if (target->state != TARGET_HALTED)
-       {
+       if (target->state != TARGET_HALTED) {
                command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
                return ERROR_OK;
        }
        uint32_t reg_no = 0;
        struct reg *reg = NULL;
-       if (CMD_ARGC > 0)
-       {
+       if (CMD_ARGC > 0) {
                COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], reg_no);
                /*translate from xscale cp15 register no to openocd register*/
-               switch (reg_no)
-               {
-               case 0:
-                       reg_no = XSCALE_MAINID;
-                       break;
-               case 1:
-                       reg_no = XSCALE_CTRL;
-                       break;
-               case 2:
-                       reg_no = XSCALE_TTB;
-                       break;
-               case 3:
-                       reg_no = XSCALE_DAC;
-                       break;
-               case 5:
-                       reg_no = XSCALE_FSR;
-                       break;
-               case 6:
-                       reg_no = XSCALE_FAR;
-                       break;
-               case 13:
-                       reg_no = XSCALE_PID;
-                       break;
-               case 15:
-                       reg_no = XSCALE_CPACCESS;
-                       break;
-               default:
-                       command_print(CMD_CTX, "invalid register number");
-                       return ERROR_INVALID_ARGUMENTS;
+               switch (reg_no) {
+                       case 0:
+                               reg_no = XSCALE_MAINID;
+                               break;
+                       case 1:
+                               reg_no = XSCALE_CTRL;
+                               break;
+                       case 2:
+                               reg_no = XSCALE_TTB;
+                               break;
+                       case 3:
+                               reg_no = XSCALE_DAC;
+                               break;
+                       case 5:
+                               reg_no = XSCALE_FSR;
+                               break;
+                       case 6:
+                               reg_no = XSCALE_FAR;
+                               break;
+                       case 13:
+                               reg_no = XSCALE_PID;
+                               break;
+                       case 15:
+                               reg_no = XSCALE_CPACCESS;
+                               break;
+                       default:
+                               command_print(CMD_CTX, "invalid register number");
+                               return ERROR_COMMAND_SYNTAX_ERROR;
                }
                reg = &xscale->reg_cache->reg_list[reg_no];
 
        }
-       if (CMD_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);
-       }
-       else if (CMD_ARGC == 2)
-       {
+               command_print(CMD_CTX, "%s (/%i): 0x%" PRIx32 "", reg->name, (int)(reg->size),
+                       value);
+       } else if (CMD_ARGC == 2) {
                uint32_t value;
                COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
 
@@ -3587,11 +3565,8 @@ COMMAND_HANDLER(xscale_handle_cp15)
 
                /* execute cpwait to ensure outstanding operations complete */
                xscale_send_u32(target, 0x53);
-       }
-       else
-       {
-               command_print(CMD_CTX, "usage: cp15 [register]<, [value]>");
-       }
+       } else
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        return ERROR_OK;
 }
@@ -3630,9 +3605,9 @@ static const struct command_registration xscale_exec_command_handlers[] = {
                .name = "vector_catch",
                .handler = xscale_handle_vector_catch_command,
                .mode = COMMAND_EXEC,
-               .help = "set or display 8-bit mask of vectors "
+               .help = "set or display mask of vectors "
                        "that should trigger debug entry",
-               .usage = "[mask]",
+               .usage = "['all'|'none'|'fiq'|'irq'|'dabt'|'pabt'|'swi'|'undef'|'reset']",
        },
        {
                .name = "vector_table",
@@ -3648,7 +3623,7 @@ static const struct command_registration xscale_exec_command_handlers[] = {
                .mode = COMMAND_EXEC,
                .help = "display trace buffer status, enable or disable "
                        "tracing, and optionally reconfigure trace mode",
-               .usage = "['enable'|'disable' ['fill' number|'wrap']]",
+               .usage = "['enable'|'disable' ['fill' [number]|'wrap']]",
        },
        {
                .name = "dump_trace",
@@ -3686,7 +3661,7 @@ static const struct command_registration xscale_any_command_handlers[] = {
                .handler = xscale_handle_debug_handler_command,
                .mode = COMMAND_ANY,
                .help = "Change address used for debug handler.",
-               .usage = "target address",
+               .usage = "<target> <address>",
        },
        {
                .name = "cache_clean_address",
@@ -3708,36 +3683,33 @@ static const struct command_registration xscale_command_handlers[] = {
                .name = "xscale",
                .mode = COMMAND_ANY,
                .help = "xscale command group",
+               .usage = "",
                .chain = xscale_any_command_handlers,
        },
        COMMAND_REGISTRATION_DONE
 };
 
-struct target_type xscale_target =
-{
+struct target_type xscale_target = {
        .name = "xscale",
 
        .poll = xscale_poll,
        .arch_state = xscale_arch_state,
 
-       .target_request_data = NULL,
-
        .halt = xscale_halt,
        .resume = xscale_resume,
        .step = xscale_step,
 
        .assert_reset = xscale_assert_reset,
        .deassert_reset = xscale_deassert_reset,
-       .soft_reset_halt = NULL,
 
        /* REVISIT on some cores, allow exporting iwmmxt registers ... */
+       .get_gdb_arch = arm_get_gdb_arch,
        .get_gdb_reg_list = arm_get_gdb_reg_list,
 
        .read_memory = xscale_read_memory,
        .read_phys_memory = xscale_read_phys_memory,
        .write_memory = xscale_write_memory,
        .write_phys_memory = xscale_write_phys_memory,
-       .bulk_write_memory = xscale_bulk_write_memory,
 
        .checksum_memory = arm_checksum_memory,
        .blank_check_memory = arm_blank_check_memory,

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)