target, register: allow a register hidden from gdb and 'reg' cmd
[fw/openocd] / src / target / xscale.c
index 92c4ede8bf3d0a6541179834e4d8bfb888b069b0..b25999d3c65ccf0d619d46b96efed69d0e00dcef 100644 (file)
@@ -19,9 +19,7 @@
  *   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.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -61,7 +59,7 @@
 
 /* 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);
@@ -73,16 +71,12 @@ 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",
@@ -135,7 +129,7 @@ static const struct xscale_reg xscale_reg_arch_info[] = {
 /* convenience wrapper to access XScale specific registers */
 static int xscale_set_reg_u32(struct reg *reg, uint32_t value)
 {
-       uint8_t buf[4];
+       uint8_t buf[4] = { 0 };
 
        buf_set_u32(buf, 0, 32, value);
 
@@ -144,11 +138,11 @@ 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,
+static int xscale_verify_pointer(struct command_invocation *cmd,
        struct xscale_common *xscale)
 {
        if (xscale->common_magic != XSCALE_COMMON_MAGIC) {
-               command_print(cmd_ctx, xscale_not);
+               command_print(cmd, xscale_not);
                return ERROR_TARGET_INVALID;
        }
        return ERROR_OK;
@@ -160,9 +154,9 @@ static int xscale_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_s
 
        if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {
                struct scan_field field;
-               uint8_t scratch[4];
+               uint8_t scratch[4] = { 0 };
 
-               memset(&field, 0, sizeof field);
+               memset(&field, 0, sizeof(field));
                field.num_bits = tap->ir_length;
                field.out_value = scratch;
                buf_set_u32(scratch, 0, field.num_bits, new_instr);
@@ -192,7 +186,7 @@ static int xscale_read_dcsr(struct target *target)
        buf_set_u32(&field0, 1, 1, xscale->hold_rst);
        buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
 
-       memset(&fields, 0, sizeof fields);
+       memset(&fields, 0, sizeof(fields));
 
        fields[0].num_bits = 3;
        fields[0].out_value = &field0;
@@ -218,8 +212,8 @@ static int xscale_read_dcsr(struct target *target)
                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)
@@ -265,7 +259,7 @@ static int xscale_receive(struct target *target, uint32_t *buffer, int num_words
        path[1] = TAP_DRCAPTURE;
        path[2] = TAP_DRSHIFT;
 
-       memset(&fields, 0, sizeof fields);
+       memset(&fields, 0, sizeof(fields));
 
        fields[0].num_bits = 3;
        uint8_t tmp;
@@ -373,7 +367,7 @@ static int xscale_read_tx(struct target *target, int consume)
        noconsume_path[4] = TAP_DREXIT2;
        noconsume_path[5] = TAP_DRSHIFT;
 
-       memset(&fields, 0, sizeof fields);
+       memset(&fields, 0, sizeof(fields));
 
        fields[0].num_bits = 3;
        fields[0].in_value = &field0_in;
@@ -410,8 +404,7 @@ static int xscale_read_tx(struct target *target, int consume)
                }
 
                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;
                }
@@ -449,7 +442,7 @@ static int xscale_write_rx(struct target *target)
                XSCALE_DBGRX << xscale->xscale_variant,
                TAP_IDLE);
 
-       memset(&fields, 0, sizeof fields);
+       memset(&fields, 0, sizeof(fields));
 
        fields[0].num_bits = 3;
        fields[0].out_value = &field0_out;
@@ -513,8 +506,6 @@ done:
 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;
 
@@ -522,37 +513,45 @@ static int xscale_send(struct target *target, const uint8_t *buffer, int count,
                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] = { 0 };
+       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) {
+               uint32_t t;
+
                switch (size) {
                        case 4:
                                if (endianness == TARGET_LITTLE_ENDIAN)
-                                       t[1] = le_to_h_u32(buffer);
+                                       t = le_to_h_u32(buffer);
                                else
-                                       t[1] = be_to_h_u32(buffer);
+                                       t = be_to_h_u32(buffer);
                                break;
                        case 2:
                                if (endianness == TARGET_LITTLE_ENDIAN)
-                                       t[1] = le_to_h_u16(buffer);
+                                       t = le_to_h_u16(buffer);
                                else
-                                       t[1] = be_to_h_u16(buffer);
+                                       t = be_to_h_u16(buffer);
                                break;
                        case 1:
-                               t[1] = buffer[0];
+                               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,
+
+               buf_set_u32(t1, 0, 32, t);
+
+               jtag_add_dr_scan(target->tap,
                        3,
-                       bits,
-                       t,
+                       fields,
                        TAP_IDLE);
                buffer += size;
        }
@@ -599,7 +598,7 @@ static int xscale_write_dcsr(struct target *target, int hold_rst, int ext_dbg_br
        buf_set_u32(&field0, 1, 1, xscale->hold_rst);
        buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
 
-       memset(&fields, 0, sizeof fields);
+       memset(&fields, 0, sizeof(fields));
 
        fields[0].num_bits = 3;
        fields[0].out_value = &field0;
@@ -625,8 +624,8 @@ static int xscale_write_dcsr(struct target *target, int hold_rst, int ext_dbg_br
                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;
 }
@@ -646,8 +645,8 @@ static unsigned int parity(unsigned int v)
 static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8])
 {
        struct xscale_common *xscale = target_to_xscale(target);
-       uint8_t packet[4];
-       uint8_t cmd;
+       uint8_t packet[4] = { 0 };
+       uint8_t cmd = 0;
        int word;
        struct scan_field fields[2];
 
@@ -667,7 +666,7 @@ static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8]
        /* virtual address of desired cache line */
        buf_set_u32(packet, 0, 27, va >> 5);
 
-       memset(&fields, 0, sizeof fields);
+       memset(&fields, 0, sizeof(fields));
 
        fields[0].num_bits = 6;
        fields[0].out_value = &cmd;
@@ -700,8 +699,8 @@ static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8]
 static int xscale_invalidate_ic_line(struct target *target, uint32_t va)
 {
        struct xscale_common *xscale = target_to_xscale(target);
-       uint8_t packet[4];
-       uint8_t cmd;
+       uint8_t packet[4] = { 0 };
+       uint8_t cmd = 0;
        struct scan_field fields[2];
 
        xscale_jtag_set_instr(target->tap,
@@ -714,7 +713,7 @@ static int xscale_invalidate_ic_line(struct target *target, uint32_t va)
        /* virtual address of desired cache line */
        buf_set_u32(packet, 0, 27, va >> 5);
 
-       memset(&fields, 0, sizeof fields);
+       memset(&fields, 0, sizeof(fields));
 
        fields[0].num_bits = 6;
        fields[0].out_value = &cmd;
@@ -825,7 +824,7 @@ static int xscale_poll(struct target *target)
                        retval = xscale_debug_entry(target);
                } 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 */
+                       /* here we "lie" so GDB won't get stuck and a reset can be performed */
                        target->state = TARGET_HALTED;
                }
 
@@ -869,21 +868,21 @@ static int xscale_debug_entry(struct target *target)
 
        /* move r0 from buffer to register cache */
        buf_set_u32(arm->core_cache->reg_list[0].value, 0, 32, buffer[0]);
-       arm->core_cache->reg_list[0].dirty = 1;
-       arm->core_cache->reg_list[0].valid = 1;
+       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(arm->pc->value, 0, 32, buffer[1]);
-       arm->pc->dirty = 1;
-       arm->pc->valid = 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(arm->core_cache->reg_list[i].value, 0, 32, buffer[1 + i]);
-               arm->core_cache->reg_list[i].dirty = 1;
-               arm->core_cache->reg_list[i].valid = 1;
+               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]);
        }
 
@@ -921,7 +920,7 @@ static int xscale_debug_entry(struct target *target)
        /* 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 = 0;
+               xscale->reg_cache->reg_list[i].valid = false;
 
        /* examine debug reason */
        xscale_read_dcsr(target);
@@ -956,7 +955,7 @@ static int xscale_debug_entry(struct target *target)
                        xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
                        pc -= 4;
                        break;
-               case 0x5:       /* Vector trap occured */
+               case 0x5:       /* Vector trap occurred */
                        target->debug_reason = DBG_REASON_BREAKPOINT;
                        xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
                        pc -= 4;
@@ -1111,8 +1110,7 @@ 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->entries);
                free(td);
                td = next_td;
        }
@@ -1120,7 +1118,7 @@ static void xscale_free_trace_data(struct xscale_common *xscale)
 }
 
 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 *arm = &xscale->arm;
@@ -1165,7 +1163,8 @@ static int xscale_resume(struct target *target, int current,
                        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 */
@@ -1222,7 +1221,8 @@ static int xscale_resume(struct target *target, int current,
                        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);
                }
        }
@@ -1384,7 +1384,7 @@ 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 *arm = target_to_arm(target);
        struct breakpoint *breakpoint = NULL;
@@ -1444,9 +1444,23 @@ 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));
 
+       /* 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
         */
@@ -1463,13 +1477,6 @@ 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) {
@@ -1543,7 +1550,7 @@ 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;
+               for (unsigned binary_size = sizeof(xscale_debug_handler);
                        binary_size > 0;
                        binary_size -= buf_cnt, buffer += buf_cnt) {
                        uint32_t cache_line[8];
@@ -1571,7 +1578,6 @@ static int xscale_deassert_reset(struct target *target)
 
                        address += buf_cnt;
                }
-               ;
 
                retval = xscale_load_ic(target, 0x0,
                                xscale->low_vectors);
@@ -1619,7 +1625,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");
@@ -1772,7 +1778,7 @@ dirty:
        return ERROR_OK;
 }
 
-static int xscale_read_memory(struct target *target, uint32_t address,
+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);
@@ -1780,7 +1786,7 @@ static int xscale_read_memory(struct target *target, uint32_t address,
        uint32_t i;
        int retval;
 
-       LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32,
+       LOG_DEBUG("address: " TARGET_ADDR_FMT ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32,
                address,
                size,
                count);
@@ -1815,8 +1821,10 @@ static int xscale_read_memory(struct target *target, uint32_t address,
        /* receive data from target (count times 32-bit words in host endianness) */
        buf32 = malloc(4 * count);
        retval = xscale_receive(target, buf32, count);
-       if (retval != ERROR_OK)
+       if (retval != ERROR_OK) {
+               free(buf32);
                return retval;
+       }
 
        /* extract data from host-endian buffer into byte stream */
        for (i = 0; i < count; i++) {
@@ -1856,7 +1864,7 @@ 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,
+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);
@@ -1871,13 +1879,13 @@ static int xscale_read_phys_memory(struct target *target, uint32_t address,
        return ERROR_FAIL;
 }
 
-static int xscale_write_memory(struct target *target, uint32_t address,
+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,
+       LOG_DEBUG("address: " TARGET_ADDR_FMT ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32,
                address,
                size,
                count);
@@ -1955,7 +1963,7 @@ static int xscale_write_memory(struct target *target, uint32_t address,
        return ERROR_OK;
 }
 
-static int xscale_write_phys_memory(struct target *target, uint32_t address,
+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);
@@ -2403,7 +2411,7 @@ static int xscale_get_reg(struct reg *reg)
        } 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
+       } else {/* Other DBG registers have to be transferred by the debug handler
                 * send CP read request (command 0x40) */
                xscale_send_u32(target, 0x40);
 
@@ -2414,8 +2422,8 @@ 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;
@@ -2441,7 +2449,7 @@ static int xscale_set_reg(struct reg *reg, uint8_t *buf)
        } 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
+       } else {/* Other DBG registers have to be transferred by the debug handler
                 * send CP write request (command 0x41) */
                xscale_send_u32(target, 0x41);
 
@@ -2574,7 +2582,6 @@ static int xscale_read_instruction(struct target *target, uint32_t pc,
        struct arm_instruction *instruction)
 {
        struct xscale_common *const xscale = target_to_xscale(target);
-       int i;
        int section = -1;
        size_t size_read;
        uint32_t opcode;
@@ -2584,7 +2591,7 @@ static int xscale_read_instruction(struct target *target, uint32_t pc,
                return ERROR_TRACE_IMAGE_UNAVAILABLE;
 
        /* search for the section the current instruction belongs to */
-       for (i = 0; i < xscale->trace.image->num_sections; i++) {
+       for (unsigned int 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)) {
@@ -2645,21 +2652,21 @@ static inline void xscale_branch_address(struct xscale_trace_data *trace_data,
 
 static inline void xscale_display_instruction(struct target *target, uint32_t pc,
        struct arm_instruction *instruction,
-       struct command_context *cmd_ctx)
+       struct command_invocation *cmd)
 {
        int retval = xscale_read_instruction(target, pc, instruction);
        if (retval == ERROR_OK)
-               command_print(cmd_ctx, "%s", instruction->text);
+               command_print(cmd, "%s", instruction->text);
        else
-               command_print(cmd_ctx, "0x%8.8" PRIx32 "\t<not found in image>", pc);
+               command_print(cmd, "0x%8.8" PRIx32 "\t<not found in image>", pc);
 }
 
-static int xscale_analyze_trace(struct target *target, struct command_context *cmd_ctx)
+static int xscale_analyze_trace(struct target *target, struct command_invocation *cmd)
 {
        struct xscale_common *xscale = target_to_xscale(target);
        struct xscale_trace_data *trace_data = xscale->trace.data;
        int i, retval;
-       uint32_t breakpoint_pc;
+       uint32_t breakpoint_pc = 0;
        struct arm_instruction instruction;
        uint32_t current_pc = 0;/* initialized when address determined */
 
@@ -2762,7 +2769,7 @@ static int xscale_analyze_trace(struct target *target, struct command_context *c
                        count = trace_data->entries[i].data & 0x0f;
                        for (j = 0; j < count; j++) {
                                xscale_display_instruction(target, current_pc, &instruction,
-                                       cmd_ctx);
+                                       cmd);
                                current_pc += xscale->trace.core_state == ARM_STATE_ARM ? 4 : 2;
                        }
 
@@ -2770,7 +2777,7 @@ static int xscale_analyze_trace(struct target *target, struct command_context *c
                         * 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);
+                                       cmd);
                                current_pc += xscale->trace.core_state == ARM_STATE_ARM ? 4 : 2;
                        }
 
@@ -2778,13 +2785,13 @@ static int xscale_analyze_trace(struct target *target, struct command_context *c
                                continue;
 
                        if (exception) {
-                               command_print(cmd_ctx, "--- exception %i ---", exception);
+                               command_print(cmd, "--- exception %i ---", exception);
                                continue;
                        }
 
                        /* 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);
+                       xscale_display_instruction(target, current_pc, &instruction, cmd);
 
                        /* for direct branches, extract branch destination from instruction */
                        if ((trace_msg_type == 8) || (trace_msg_type == 12)) {
@@ -2800,11 +2807,11 @@ static int xscale_analyze_trace(struct target *target, struct command_context *c
                                                current_pc = chkpt_reg;
                                        else if (current_pc != chkpt_reg)       /* sanity check */
                                                LOG_WARNING("trace is suspect: checkpoint register "
-                                                       "inconsistent with adddress from image");
+                                                       "inconsistent with address from image");
                                }
 
                                if (current_pc == 0)
-                                       command_print(cmd_ctx, "address unknown");
+                                       command_print(cmd, "address unknown");
 
                                continue;
                        }
@@ -2846,7 +2853,7 @@ static int xscale_analyze_trace(struct target *target, struct command_context *c
 
        /* display remaining instructions */
        for (i = 0; i < gap_count; i++) {
-               xscale_display_instruction(target, current_pc, &instruction, cmd_ctx);
+               xscale_display_instruction(target, current_pc, &instruction, cmd);
                current_pc += xscale->trace.core_state == ARM_STATE_ARM ? 4 : 2;
        }
 
@@ -2875,17 +2882,18 @@ static void xscale_build_reg_cache(struct target *target)
        /* fill in values for the xscale reg cache */
        (*cache_p)->name = "XScale registers";
        (*cache_p)->next = NULL;
-       (*cache_p)->reg_list = malloc(num_regs * sizeof(struct reg));
+       (*cache_p)->reg_list = calloc(num_regs, sizeof(struct reg));
        (*cache_p)->num_regs = num_regs;
 
        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;
+               (*cache_p)->reg_list[i].exist = true;
                arch_info[i] = xscale_reg_arch_info[i];
                arch_info[i].target = target;
        }
@@ -2893,6 +2901,21 @@ static void xscale_build_reg_cache(struct target *target)
        xscale->reg_cache = (*cache_p);
 }
 
+static void xscale_free_reg_cache(struct target *target)
+{
+       struct xscale_common *xscale = target_to_xscale(target);
+       struct reg_cache *cache = xscale->reg_cache;
+
+       for (unsigned int i = 0; i < ARRAY_SIZE(xscale_reg_arch_info); i++)
+               free(cache->reg_list[i].value);
+
+       free(cache->reg_list[0].arch_info);
+       free(cache->reg_list);
+       free(cache);
+
+       arm_free_reg_cache(&xscale->arm);
+}
+
 static int xscale_init_target(struct command_context *cmd_ctx,
        struct target *target)
 {
@@ -2900,8 +2923,16 @@ static int xscale_init_target(struct command_context *cmd_ctx,
        return ERROR_OK;
 }
 
+static void xscale_deinit_target(struct target *target)
+{
+       struct xscale_common *xscale = target_to_xscale(target);
+
+       xscale_free_reg_cache(target);
+       free(xscale);
+}
+
 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 *arm;
        uint32_t high_reset_branch, low_reset_branch;
@@ -2909,36 +2940,10 @@ static int xscale_init_arch_info(struct target *target,
 
        arm = &xscale->arm;
 
-       /* store architecture specfic data */
+       /* store architecture specific 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
@@ -2997,7 +3002,7 @@ static int xscale_init_arch_info(struct target *target,
 
        /* prepare ARMv4/5 specific information */
        arm->arch_info = xscale;
-       arm->core_type = ARM_MODE_ANY;
+       arm->core_type = ARM_CORE_TYPE_STD;
        arm->read_core_reg = xscale_read_core_reg;
        arm->write_core_reg = xscale_write_core_reg;
        arm->full_context = xscale_full_context;
@@ -3020,7 +3025,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;
        }
@@ -3029,8 +3034,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)
@@ -3050,7 +3054,7 @@ COMMAND_HANDLER(xscale_handle_debug_handler_command)
        }
 
        xscale = target_to_xscale(target);
-       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       retval = xscale_verify_pointer(CMD, xscale);
        if (retval != ERROR_OK)
                return retval;
 
@@ -3084,7 +3088,7 @@ COMMAND_HANDLER(xscale_handle_cache_clean_address_command)
                return ERROR_FAIL;
        }
        xscale = target_to_xscale(target);
-       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       retval = xscale_verify_pointer(CMD, xscale);
        if (retval != ERROR_OK)
                return retval;
 
@@ -3104,15 +3108,15 @@ COMMAND_HANDLER(xscale_handle_cache_info_command)
        struct xscale_common *xscale = target_to_xscale(target);
        int retval;
 
-       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       retval = xscale_verify_pointer(CMD, xscale);
        if (retval != ERROR_OK)
                return retval;
 
-       return armv4_5_handle_cache_info_command(CMD_CTX, &xscale->armv4_5_mmu.armv4_5_cache);
+       return armv4_5_handle_cache_info_command(CMD, &xscale->armv4_5_mmu.armv4_5_cache);
 }
 
 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);
        uint32_t cb;
@@ -3149,12 +3153,12 @@ COMMAND_HANDLER(xscale_handle_mmu_command)
        struct xscale_common *xscale = target_to_xscale(target);
        int retval;
 
-       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       retval = xscale_verify_pointer(CMD, xscale);
        if (retval != ERROR_OK)
                return retval;
 
        if (target->state != TARGET_HALTED) {
-               command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
+               command_print(CMD, "target must be stopped for \"%s\" command", CMD_NAME);
                return ERROR_OK;
        }
 
@@ -3168,7 +3172,7 @@ COMMAND_HANDLER(xscale_handle_mmu_command)
                xscale->armv4_5_mmu.mmu_enabled = enable;
        }
 
-       command_print(CMD_CTX, "mmu %s",
+       command_print(CMD, "mmu %s",
                (xscale->armv4_5_mmu.mmu_enabled) ? "enabled" : "disabled");
 
        return ERROR_OK;
@@ -3179,12 +3183,12 @@ COMMAND_HANDLER(xscale_handle_idcache_command)
        struct target *target = get_current_target(CMD_CTX);
        struct xscale_common *xscale = target_to_xscale(target);
 
-       int retval = xscale_verify_pointer(CMD_CTX, xscale);
+       int retval = xscale_verify_pointer(CMD, xscale);
        if (retval != ERROR_OK)
                return retval;
 
        if (target->state != TARGET_HALTED) {
-               command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
+               command_print(CMD, "target must be stopped for \"%s\" command", CMD_NAME);
                return ERROR_OK;
        }
 
@@ -3213,7 +3217,7 @@ COMMAND_HANDLER(xscale_handle_idcache_command)
                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);
+       command_print(CMD, "%s %s", CMD_NAME, msg);
 
        return ERROR_OK;
 }
@@ -3240,11 +3244,10 @@ COMMAND_HANDLER(xscale_handle_vector_catch_command)
        uint32_t catch = 0;
        struct reg *dcsr_reg = &xscale->reg_cache->reg_list[XSCALE_DCSR];
 
-       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       retval = xscale_verify_pointer(CMD, xscale);
        if (retval != ERROR_OK)
                return retval;
 
-       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) {
@@ -3268,14 +3271,14 @@ COMMAND_HANDLER(xscale_handle_vector_catch_command)
                                return ERROR_COMMAND_SYNTAX_ERROR;
                        }
                }
-               *(uint32_t *)(dcsr_reg->value) &= ~DCSR_TRAP_MASK;
-               *(uint32_t *)(dcsr_reg->value) |= catch;
+               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);
        }
 
        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,
+               command_print(CMD, "%15s: %s", vec_ids[i].name,
                        (dcsr_value & vec_ids[i].mask) ? "catch" : "ignore");
        }
 
@@ -3290,23 +3293,23 @@ COMMAND_HANDLER(xscale_handle_vector_table_command)
        int err = 0;
        int retval;
 
-       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       retval = xscale_verify_pointer(CMD, xscale);
        if (retval != ERROR_OK)
                return retval;
 
        if (CMD_ARGC == 0) {    /* print current settings */
                int idx;
 
-               command_print(CMD_CTX, "active user-set static vectors:");
+               command_print(CMD, "active user-set static vectors:");
                for (idx = 1; idx < 8; idx++)
                        if (xscale->static_low_vectors_set & (1 << idx))
-                               command_print(CMD_CTX,
+                               command_print(CMD,
                                        "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,
+                               command_print(CMD,
                                        "high %d: 0x%" PRIx32,
                                        idx,
                                        xscale->static_high_vectors[idx]);
@@ -3348,12 +3351,12 @@ COMMAND_HANDLER(xscale_handle_trace_buffer_command)
        uint32_t dcsr_value;
        int retval;
 
-       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       retval = xscale_verify_pointer(CMD, xscale);
        if (retval != ERROR_OK)
                return retval;
 
        if (target->state != TARGET_HALTED) {
-               command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
+               command_print(CMD, "target must be stopped for \"%s\" command", CMD_NAME);
                return ERROR_OK;
        }
 
@@ -3372,7 +3375,7 @@ COMMAND_HANDLER(xscale_handle_trace_buffer_command)
                        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");
+                               command_print(CMD, "fill buffer count must be > 0");
                                xscale->trace.mode = XSCALE_TRACE_DISABLED;
                                return ERROR_COMMAND_SYNTAX_ERROR;
                        }
@@ -3388,12 +3391,12 @@ COMMAND_HANDLER(xscale_handle_trace_buffer_command)
 
        if (xscale->trace.mode != XSCALE_TRACE_DISABLED) {
                char fill_string[12];
-               sprintf(fill_string, "fill %" PRId32, xscale->trace.buffer_fill);
-               command_print(CMD_CTX, "trace buffer enabled (%s)",
+               sprintf(fill_string, "fill %d", xscale->trace.buffer_fill);
+               command_print(CMD, "trace buffer enabled (%s)",
                        (xscale->trace.mode == XSCALE_TRACE_FILL)
                        ? fill_string : "wrap");
        } else
-               command_print(CMD_CTX, "trace buffer disabled");
+               command_print(CMD, "trace buffer disabled");
 
        dcsr_value = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32);
        if (xscale->trace.mode == XSCALE_TRACE_FILL)
@@ -3413,26 +3416,26 @@ COMMAND_HANDLER(xscale_handle_trace_image_command)
        if (CMD_ARGC < 1)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       retval = xscale_verify_pointer(CMD, xscale);
        if (retval != ERROR_OK)
                return retval;
 
        if (xscale->trace.image) {
                image_close(xscale->trace.image);
                free(xscale->trace.image);
-               command_print(CMD_CTX, "previously loaded image found and closed");
+               command_print(CMD, "previously loaded image found and closed");
        }
 
        xscale->trace.image = malloc(sizeof(struct image));
-       xscale->trace.image->base_address_set = 0;
-       xscale->trace.image->start_address_set = 0;
+       xscale->trace.image->base_address_set = false;
+       xscale->trace.image->start_address_set = false;
 
        /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
        if (CMD_ARGC >= 2) {
-               xscale->trace.image->base_address_set = 1;
+               xscale->trace.image->base_address_set = true;
                COMMAND_PARSE_NUMBER(llong, CMD_ARGV[1], xscale->trace.image->base_address);
        } else
-               xscale->trace.image->base_address_set = 0;
+               xscale->trace.image->base_address_set = false;
 
        if (image_open(xscale->trace.image, CMD_ARGV[0],
                (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL) != ERROR_OK) {
@@ -3449,15 +3452,15 @@ 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);
+       retval = xscale_verify_pointer(CMD, xscale);
        if (retval != ERROR_OK)
                return retval;
 
        if (target->state != TARGET_HALTED) {
-               command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
+               command_print(CMD, "target must be stopped for \"%s\" command", CMD_NAME);
                return ERROR_OK;
        }
 
@@ -3467,7 +3470,7 @@ COMMAND_HANDLER(xscale_handle_dump_trace_command)
        trace_data = xscale->trace.data;
 
        if (!trace_data) {
-               command_print(CMD_CTX, "no trace data collected");
+               command_print(CMD, "no trace data collected");
                return ERROR_OK;
        }
 
@@ -3477,19 +3480,19 @@ COMMAND_HANDLER(xscale_handle_dump_trace_command)
        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 |
+                       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;
 }
@@ -3500,11 +3503,11 @@ COMMAND_HANDLER(xscale_handle_analyze_trace_buffer_command)
        struct xscale_common *xscale = target_to_xscale(target);
        int retval;
 
-       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       retval = xscale_verify_pointer(CMD, xscale);
        if (retval != ERROR_OK)
                return retval;
 
-       xscale_analyze_trace(target, CMD_CTX);
+       xscale_analyze_trace(target, CMD);
 
        return ERROR_OK;
 }
@@ -3515,12 +3518,12 @@ COMMAND_HANDLER(xscale_handle_cp15)
        struct xscale_common *xscale = target_to_xscale(target);
        int retval;
 
-       retval = xscale_verify_pointer(CMD_CTX, xscale);
+       retval = xscale_verify_pointer(CMD, xscale);
        if (retval != ERROR_OK)
                return retval;
 
        if (target->state != TARGET_HALTED) {
-               command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
+               command_print(CMD, "target must be stopped for \"%s\" command", CMD_NAME);
                return ERROR_OK;
        }
        uint32_t reg_no = 0;
@@ -3554,7 +3557,7 @@ COMMAND_HANDLER(xscale_handle_cp15)
                                reg_no = XSCALE_CPACCESS;
                                break;
                        default:
-                               command_print(CMD_CTX, "invalid register number");
+                               command_print(CMD, "invalid register number");
                                return ERROR_COMMAND_SYNTAX_ERROR;
                }
                reg = &xscale->reg_cache->reg_list[reg_no];
@@ -3566,7 +3569,7 @@ COMMAND_HANDLER(xscale_handle_cp15)
                /* 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),
+               command_print(CMD, "%s (/%i): 0x%" PRIx32 "", reg->name, (int)(reg->size),
                        value);
        } else if (CMD_ARGC == 2) {
                uint32_t value;
@@ -3595,6 +3598,7 @@ static const struct command_registration xscale_exec_command_handlers[] = {
                .handler = xscale_handle_cache_info_command,
                .mode = COMMAND_EXEC,
                .help = "display information about CPU caches",
+               .usage = "",
        },
        {
                .name = "mmu",
@@ -3713,17 +3717,15 @@ struct target_type xscale_target = {
        .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,
@@ -3744,6 +3746,7 @@ struct target_type xscale_target = {
        .commands = xscale_command_handlers,
        .target_create = xscale_target_create,
        .init_target = xscale_init_target,
+       .deinit_target = xscale_deinit_target,
 
        .virt2phys = xscale_virt2phys,
        .mmu = xscale_mmu