ARMv7M: review scope of functions
[fw/openocd] / src / target / xscale.c
index 0fa3270034434912cd3e2bdc961c6125cc243186..24c07941b549765c4db7d7b3bec2098b8371cd1f 100644 (file)
@@ -36,6 +36,8 @@
 #include <helper/time_support.h>
 #include "register.h"
 #include "image.h"
+#include "arm_opcodes.h"
+#include "armv4_5.h"
 
 
 /*
@@ -156,7 +158,7 @@ static int xscale_verify_pointer(struct command_context *cmd_ctx,
        return ERROR_OK;
 }
 
-static int xscale_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr)
+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;
@@ -167,12 +169,11 @@ static int xscale_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr)
                uint8_t scratch[4];
 
                memset(&field, 0, sizeof field);
-               field.tap = tap;
                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(1, &field, jtag_get_end_state());
+               jtag_add_ir_scan(tap, &field, end_state);
        }
 
        return ERROR_OK;
@@ -190,32 +191,29 @@ static int xscale_read_dcsr(struct target *target)
        uint8_t field2_check_value = 0x0;
        uint8_t field2_check_mask = 0x1;
 
-       jtag_set_end_state(TAP_DRPAUSE);
        xscale_jtag_set_instr(target->tap,
-               XSCALE_SELDCSR << xscale->xscale_variant);
+               XSCALE_SELDCSR << xscale->xscale_variant,
+               TAP_DRPAUSE);
 
        buf_set_u32(&field0, 1, 1, xscale->hold_rst);
        buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
 
        memset(&fields, 0, sizeof fields);
 
-       fields[0].tap = target->tap;
        fields[0].num_bits = 3;
        fields[0].out_value = &field0;
        uint8_t tmp;
        fields[0].in_value = &tmp;
 
-       fields[1].tap = target->tap;
        fields[1].num_bits = 32;
        fields[1].in_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
 
-       fields[2].tap = target->tap;
        fields[2].num_bits = 1;
        fields[2].out_value = &field2;
        uint8_t tmp2;
        fields[2].in_value = &tmp2;
 
-       jtag_add_dr_scan(3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(target->tap, 3, fields, TAP_DRPAUSE);
 
        jtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask);
        jtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask);
@@ -236,9 +234,7 @@ static int xscale_read_dcsr(struct target *target)
        fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
        fields[1].in_value = NULL;
 
-       jtag_set_end_state(TAP_IDLE);
-
-       jtag_add_dr_scan(3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(target->tap, 3, fields, TAP_DRPAUSE);
 
        /* DANGER!!! this must be here. It will make sure that the arguments
         * to jtag_set_check_value() does not go out of scope! */
@@ -277,23 +273,20 @@ static int xscale_receive(struct target *target, uint32_t *buffer, int num_words
 
        memset(&fields, 0, sizeof fields);
 
-       fields[0].tap = target->tap;
        fields[0].num_bits = 3;
        fields[0].check_value = &field0_check_value;
        fields[0].check_mask = &field0_check_mask;
 
-       fields[1].tap = target->tap;
        fields[1].num_bits = 32;
 
-       fields[2].tap = target->tap;
        fields[2].num_bits = 1;
        fields[2].check_value = &field2_check_value;
        fields[2].check_mask = &field2_check_mask;
 
-       jtag_set_end_state(TAP_IDLE);
        xscale_jtag_set_instr(target->tap,
-               XSCALE_DBGTX << xscale->xscale_variant);
-       jtag_add_runtest(1, jtag_get_end_state()); /* ensures that we're in the TAP_IDLE state as the above could be a no-op */
+               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 */
 
        /* repeat until all words have been collected */
        int attempts = 0;
@@ -309,7 +302,7 @@ static int xscale_receive(struct target *target, uint32_t *buffer, int num_words
 
                        fields[1].in_value = (uint8_t *)(field1 + i);
 
-                       jtag_add_dr_scan_check(3, fields, jtag_set_end_state(TAP_IDLE));
+                       jtag_add_dr_scan_check(target->tap, 3, fields, TAP_IDLE);
 
                        jtag_add_callback(xscale_getbuf, (jtag_callback_data_t)(field1 + i));
 
@@ -372,10 +365,9 @@ static int xscale_read_tx(struct target *target, int consume)
        uint8_t field2_check_value = 0x0;
        uint8_t field2_check_mask = 0x1;
 
-       jtag_set_end_state(TAP_IDLE);
-
        xscale_jtag_set_instr(target->tap,
-               XSCALE_DBGTX << xscale->xscale_variant);
+               XSCALE_DBGTX << xscale->xscale_variant,
+               TAP_IDLE);
 
        path[0] = TAP_DRSELECT;
        path[1] = TAP_DRCAPTURE;
@@ -390,15 +382,12 @@ static int xscale_read_tx(struct target *target, int consume)
 
        memset(&fields, 0, sizeof fields);
 
-       fields[0].tap = target->tap;
        fields[0].num_bits = 3;
        fields[0].in_value = &field0_in;
 
-       fields[1].tap = target->tap;
        fields[1].num_bits = 32;
        fields[1].in_value = xscale->reg_cache->reg_list[XSCALE_TX].value;
 
-       fields[2].tap = target->tap;
        fields[2].num_bits = 1;
        uint8_t tmp;
        fields[2].in_value = &tmp;
@@ -419,7 +408,7 @@ static int xscale_read_tx(struct target *target, int consume)
                        jtag_add_pathmove(ARRAY_SIZE(noconsume_path), noconsume_path);
                }
 
-               jtag_add_dr_scan(3, fields, jtag_set_end_state(TAP_IDLE));
+               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);
@@ -471,23 +460,19 @@ static int xscale_write_rx(struct target *target)
        uint8_t field2_check_value = 0x0;
        uint8_t field2_check_mask = 0x1;
 
-       jtag_set_end_state(TAP_IDLE);
-
        xscale_jtag_set_instr(target->tap,
-               XSCALE_DBGRX << xscale->xscale_variant);
+               XSCALE_DBGRX << xscale->xscale_variant,
+               TAP_IDLE);
 
        memset(&fields, 0, sizeof fields);
 
-       fields[0].tap = target->tap;
        fields[0].num_bits = 3;
        fields[0].out_value = &field0_out;
        fields[0].in_value = &field0_in;
 
-       fields[1].tap = target->tap;
        fields[1].num_bits = 32;
        fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_RX].value;
 
-       fields[2].tap = target->tap;
        fields[2].num_bits = 1;
        fields[2].out_value = &field2;
        uint8_t tmp;
@@ -500,7 +485,7 @@ static int xscale_write_rx(struct target *target)
        LOG_DEBUG("polling RX");
        for (;;)
        {
-               jtag_add_dr_scan(3, fields, jtag_set_end_state(TAP_IDLE));
+               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);
@@ -532,7 +517,7 @@ static int xscale_write_rx(struct target *target)
 
        /* set rx_valid */
        field2 = 0x1;
-       jtag_add_dr_scan(3, fields, jtag_set_end_state(TAP_IDLE));
+       jtag_add_dr_scan(target->tap, 3, fields, TAP_IDLE);
 
        if ((retval = jtag_execute_queue()) != ERROR_OK)
        {
@@ -552,10 +537,9 @@ static int xscale_send(struct target *target, uint8_t *buffer, int count, int si
        int retval;
        int done_count = 0;
 
-       jtag_set_end_state(TAP_IDLE);
-
        xscale_jtag_set_instr(target->tap,
-               XSCALE_DBGRX << xscale->xscale_variant);
+               XSCALE_DBGRX << xscale->xscale_variant,
+               TAP_IDLE);
 
        bits[0]=3;
        t[0]=0;
@@ -596,7 +580,7 @@ static int xscale_send(struct target *target, uint8_t *buffer, int count, int si
                                3,
                                bits,
                                t,
-                               jtag_set_end_state(TAP_IDLE));
+                               TAP_IDLE);
                buffer += size;
        }
 
@@ -635,32 +619,29 @@ static int xscale_write_dcsr(struct target *target, int hold_rst, int ext_dbg_br
        if (ext_dbg_brk != -1)
                xscale->external_debug_break = ext_dbg_brk;
 
-       jtag_set_end_state(TAP_IDLE);
        xscale_jtag_set_instr(target->tap,
-               XSCALE_SELDCSR << xscale->xscale_variant);
+               XSCALE_SELDCSR << xscale->xscale_variant,
+               TAP_IDLE);
 
        buf_set_u32(&field0, 1, 1, xscale->hold_rst);
        buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
 
        memset(&fields, 0, sizeof fields);
 
-       fields[0].tap = target->tap;
        fields[0].num_bits = 3;
        fields[0].out_value = &field0;
        uint8_t tmp;
        fields[0].in_value = &tmp;
 
-       fields[1].tap = target->tap;
        fields[1].num_bits = 32;
        fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
 
-       fields[2].tap = target->tap;
        fields[2].num_bits = 1;
        fields[2].out_value = &field2;
        uint8_t tmp2;
        fields[2].in_value = &tmp2;
 
-       jtag_add_dr_scan(3, fields, jtag_get_end_state());
+       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);
@@ -700,9 +681,9 @@ static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8]
        LOG_DEBUG("loading miniIC at 0x%8.8" PRIx32 "", va);
 
        /* LDIC into IR */
-       jtag_set_end_state(TAP_IDLE);
        xscale_jtag_set_instr(target->tap,
-               XSCALE_LDIC << xscale->xscale_variant);
+               XSCALE_LDIC << xscale->xscale_variant,
+               TAP_IDLE);
 
        /* CMD is b011 to load a cacheline into the Mini ICache.
         * Loading into the main ICache is deprecated, and unused.
@@ -715,15 +696,13 @@ static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8]
 
        memset(&fields, 0, sizeof fields);
 
-       fields[0].tap = target->tap;
        fields[0].num_bits = 6;
        fields[0].out_value = &cmd;
 
-       fields[1].tap = target->tap;
        fields[1].num_bits = 27;
        fields[1].out_value = packet;
 
-       jtag_add_dr_scan(2, fields, jtag_get_end_state());
+       jtag_add_dr_scan(target->tap, 2, fields, TAP_IDLE);
 
        /* rest of packet is a cacheline: 8 instructions, with parity */
        fields[0].num_bits = 32;
@@ -740,7 +719,7 @@ static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8]
                memcpy(&value, packet, sizeof(uint32_t));
                cmd = parity(value);
 
-               jtag_add_dr_scan(2, fields, jtag_get_end_state());
+               jtag_add_dr_scan(target->tap, 2, fields, TAP_IDLE);
        }
 
        return jtag_execute_queue();
@@ -753,9 +732,9 @@ static int xscale_invalidate_ic_line(struct target *target, uint32_t va)
        uint8_t cmd;
        struct scan_field fields[2];
 
-       jtag_set_end_state(TAP_IDLE);
        xscale_jtag_set_instr(target->tap,
-               XSCALE_LDIC << xscale->xscale_variant);
+               XSCALE_LDIC << xscale->xscale_variant,
+               TAP_IDLE);
 
        /* CMD for invalidate IC line b000, bits [6:4] b000 */
        buf_set_u32(&cmd, 0, 6, 0x0);
@@ -765,15 +744,13 @@ static int xscale_invalidate_ic_line(struct target *target, uint32_t va)
 
        memset(&fields, 0, sizeof fields);
 
-       fields[0].tap = target->tap;
        fields[0].num_bits = 6;
        fields[0].out_value = &cmd;
 
-       fields[1].tap = target->tap;
        fields[1].num_bits = 27;
        fields[1].out_value = packet;
 
-       jtag_add_dr_scan(2, fields, jtag_get_end_state());
+       jtag_add_dr_scan(target->tap, 2, fields, TAP_IDLE);
 
        return ERROR_OK;
 }
@@ -857,21 +834,14 @@ static int xscale_arch_state(struct target *target)
                "", "\n(processor reset)", "\n(trace buffer full)"
        };
 
-       if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
+       if (armv4_5->common_magic != ARM_COMMON_MAGIC)
        {
                LOG_ERROR("BUG: called for a non-ARMv4/5 target");
                return ERROR_INVALID_ARGUMENTS;
        }
 
-       LOG_USER("target halted in %s state due to %s, current mode: %s\n"
-                       "cpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "\n"
-                       "MMU: %s, D-Cache: %s, I-Cache: %s"
-                       "%s",
-                        arm_state_strings[armv4_5->core_state],
-                        Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name ,
-                        arm_mode_name(armv4_5->core_mode),
-                        buf_get_u32(armv4_5->cpsr->value, 0, 32),
-                        buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
+       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],
@@ -946,9 +916,9 @@ static int xscale_debug_entry(struct target *target)
        LOG_DEBUG("r0: 0x%8.8" PRIx32 "", buffer[0]);
 
        /* move pc from buffer to register cache */
-       buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, buffer[1]);
-       armv4_5->core_cache->reg_list[15].dirty = 1;
-       armv4_5->core_cache->reg_list[15].valid = 1;
+       buf_set_u32(armv4_5->pc->value, 0, 32, buffer[1]);
+       armv4_5->pc->dirty = 1;
+       armv4_5->pc->valid = 1;
        LOG_DEBUG("pc: 0x%8.8" PRIx32 "", buffer[1]);
 
        /* move data from buffer to register cache */
@@ -1000,7 +970,7 @@ static int xscale_debug_entry(struct target *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->core_cache->reg_list[15].value, 0, 32);
+       pc = buf_get_u32(armv4_5->pc->value, 0, 32);
 
        switch (moe)
        {
@@ -1047,7 +1017,7 @@ static int xscale_debug_entry(struct target *target)
        }
 
        /* apply PC fixup */
-       buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, pc);
+       buf_set_u32(armv4_5->pc->value, 0, 32, pc);
 
        /* on the first debug entry, identify cache type */
        if (xscale->armv4_5_mmu.armv4_5_cache.ctype == -1)
@@ -1217,23 +1187,26 @@ static int xscale_resume(struct target *target, int current,
 
        /* current = 1: continue on current pc, otherwise continue at <address> */
        if (!current)
-               buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
+               buf_set_u32(armv4_5->pc->value, 0, 32, address);
 
-       current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
+       current_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
 
        /* if we're at the reset vector, we have to simulate the branch */
        if (current_pc == 0x0)
        {
                arm_simulate_step(target, NULL);
-               current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
+               current_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
        }
 
        /* the front-end may request us not to handle breakpoints */
        if (handle_breakpoints)
        {
-               if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
+               breakpoint = breakpoint_find(target,
+                               buf_get_u32(armv4_5->pc->value, 0, 32));
+               if (breakpoint != NULL)
                {
                        uint32_t next_pc;
+                       int saved_trace_buffer_enabled;
 
                        /* 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);
@@ -1253,15 +1226,8 @@ static int xscale_resume(struct target *target, int current,
                        /* restore banked registers */
                        retval = xscale_restore_banked(target);
 
-                       /* 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,
@@ -1277,12 +1243,21 @@ static int xscale_resume(struct target *target, int current,
                        }
 
                        /* send PC */
-                       xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
-                       LOG_DEBUG("writing PC with value 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
+                       xscale_send_u32(target,
+                                       buf_get_u32(armv4_5->pc->value, 0, 32));
+                       LOG_DEBUG("writing PC with value 0x%8.8" PRIx32,
+                                       buf_get_u32(armv4_5->pc->value, 0, 32));
+
+                       /* disable trace data collection in xscale_debug_entry() */
+                       saved_trace_buffer_enabled = xscale->trace.buffer_enabled;
+                       xscale->trace.buffer_enabled = 0;
 
                        /* wait for and process debug entry */
                        xscale_debug_entry(target);
 
+                       /* re-enable trace buffer, if enabled previously */
+                       xscale->trace.buffer_enabled = saved_trace_buffer_enabled;
+
                        LOG_DEBUG("disable single-step");
                        xscale_disable_single_step(target);
 
@@ -1302,6 +1277,12 @@ static int xscale_resume(struct target *target, int current,
         * clean the trace buffer if it is to be enabled (0x62) */
        if (xscale->trace.buffer_enabled)
        {
+               /* if trace buffer is set to 'fill' mode, save starting pc */
+               if (xscale->trace.buffer_fill > 0)
+               {
+                       xscale->trace.pc_ok = 1;
+                       xscale->trace.current_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
+               }
                xscale_send_u32(target, 0x62);
                xscale_send_u32(target, 0x31);
        }
@@ -1321,8 +1302,9 @@ static int xscale_resume(struct target *target, int current,
        }
 
        /* send PC */
-       xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
-       LOG_DEBUG("writing PC with value 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
+       xscale_send_u32(target, buf_get_u32(armv4_5->pc->value, 0, 32));
+       LOG_DEBUG("wrote PC with value 0x%8.8" PRIx32,
+                       buf_get_u32(armv4_5->pc->value, 0, 32));
 
        target->debug_reason = DBG_REASON_NOTHALTED;
 
@@ -1359,7 +1341,7 @@ static int xscale_step_inner(struct target *target, int current,
        if ((retval = arm_simulate_step(target, &next_pc)) != ERROR_OK)
        {
                uint32_t current_opcode, current_pc;
-               current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
+               current_pc = buf_get_u32(armv4_5->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);
@@ -1404,9 +1386,12 @@ static int xscale_step_inner(struct target *target, int current,
        }
 
        /* send PC */
-       if ((retval = xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))) != ERROR_OK)
+       retval = xscale_send_u32(target,
+                       buf_get_u32(armv4_5->pc->value, 0, 32));
+       if (retval != ERROR_OK)
                return retval;
-       LOG_DEBUG("writing PC with value 0x%8.8" PRIx32, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
+       LOG_DEBUG("wrote PC with value 0x%8.8" PRIx32,
+                       buf_get_u32(armv4_5->pc->value, 0, 32));
 
        target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
 
@@ -1430,7 +1415,7 @@ static int xscale_step(struct target *target, int current,
                uint32_t address, int handle_breakpoints)
 {
        struct arm *armv4_5 = target_to_arm(target);
-       struct breakpoint *breakpoint = target->breakpoints;
+       struct breakpoint *breakpoint = NULL;
 
        uint32_t current_pc;
        int retval;
@@ -1443,16 +1428,16 @@ static int xscale_step(struct target *target, int current,
 
        /* current = 1: continue on current pc, otherwise continue at <address> */
        if (!current)
-               buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
+               buf_set_u32(armv4_5->pc->value, 0, 32, address);
 
-       current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
+       current_pc = buf_get_u32(armv4_5->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)
                        return retval;
-               current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
+               current_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
 
                target->debug_reason = DBG_REASON_SINGLESTEP;
                target_call_event_callbacks(target, TARGET_EVENT_HALTED);
@@ -1462,11 +1447,13 @@ static int xscale_step(struct target *target, int current,
 
        /* the front-end may request us not to handle breakpoints */
        if (handle_breakpoints)
-               if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
-               {
-                       if ((retval = xscale_unset_breakpoint(target, breakpoint)) != ERROR_OK)
-                               return retval;
-               }
+               breakpoint = breakpoint_find(target,
+                               buf_get_u32(armv4_5->pc->value, 0, 32));
+       if (breakpoint != NULL) {
+               retval = xscale_unset_breakpoint(target, breakpoint);
+               if (retval != ERROR_OK)
+                       return retval;
+       }
 
        retval = xscale_step_inner(target, current, address, handle_breakpoints);
 
@@ -1491,9 +1478,9 @@ static int xscale_assert_reset(struct target *target)
        /* select DCSR instruction (set endstate to R-T-I to ensure we don't
         * end up in T-L-R, which would reset JTAG
         */
-       jtag_set_end_state(TAP_IDLE);
        xscale_jtag_set_instr(target->tap,
-               XSCALE_SELDCSR << xscale->xscale_variant);
+               XSCALE_SELDCSR << xscale->xscale_variant,
+               TAP_IDLE);
 
        /* set Hold reset, Halt mode and Trap Reset */
        buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
@@ -1501,7 +1488,7 @@ static int xscale_assert_reset(struct target *target)
        xscale_write_dcsr(target, 1, 0);
 
        /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
-       xscale_jtag_set_instr(target->tap, 0x7f);
+       xscale_jtag_set_instr(target->tap, ~0, TAP_IDLE);
        jtag_execute_queue();
 
        /* assert reset */
@@ -1571,7 +1558,7 @@ static int xscale_deassert_reset(struct target *target)
                /* wait 300ms; 150 and 100ms were not enough */
                jtag_add_sleep(300*1000);
 
-               jtag_add_runtest(2030, jtag_set_end_state(TAP_IDLE));
+               jtag_add_runtest(2030, TAP_IDLE);
                jtag_execute_queue();
 
                /* set Hold reset, Halt mode and Trap Reset */
@@ -1628,7 +1615,7 @@ static int xscale_deassert_reset(struct target *target)
                if (retval != ERROR_OK)
                        return retval;
 
-               jtag_add_runtest(30, jtag_set_end_state(TAP_IDLE));
+               jtag_add_runtest(30, TAP_IDLE);
 
                jtag_add_sleep(100000);
 
@@ -1910,7 +1897,13 @@ static int xscale_read_memory(struct target *target, uint32_t address,
 static int xscale_read_phys_memory(struct target *target, uint32_t address,
                uint32_t size, uint32_t count, uint8_t *buffer)
 {
-       /** \todo: provide a non-stub implementtion of this routine. */
+       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);
+
+       /** \todo: provide a non-stub implementation of this routine. */
        LOG_ERROR("%s: %s is not implemented.  Disable MMU?",
                        target_name(target), __func__);
        return ERROR_FAIL;
@@ -1997,7 +1990,13 @@ static int xscale_write_memory(struct target *target, uint32_t address,
 static int xscale_write_phys_memory(struct target *target, uint32_t address,
                uint32_t size, uint32_t count, uint8_t *buffer)
 {
-       /** \todo: provide a non-stub implementtion of this routine. */
+       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);
+
+       /** \todo: provide a non-stub implementation of this routine. */
        LOG_ERROR("%s: %s is not implemented.  Disable MMU?",
                        target_name(target), __func__);
        return ERROR_FAIL;
@@ -2133,7 +2132,7 @@ static int xscale_set_breakpoint(struct target *target,
                        {
                                return retval;
                        }
-                       /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
+                       /* write the bkpt instruction in target endianness (arm7_9->arm_bkpt is host endian) */
                        if ((retval = target_write_u32(target, breakpoint->address, xscale->arm_bkpt)) != ERROR_OK)
                        {
                                return retval;
@@ -2146,13 +2145,18 @@ static int xscale_set_breakpoint(struct target *target,
                        {
                                return retval;
                        }
-                       /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
+                       /* write the bkpt instruction in target endianness (arm7_9->arm_bkpt is host endian) */
                        if ((retval = target_write_u32(target, breakpoint->address, xscale->thumb_bkpt)) != 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;
@@ -2233,6 +2237,11 @@ static int xscale_unset_breakpoint(struct target *target,
                        }
                }
                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;
@@ -2561,7 +2570,8 @@ static int xscale_read_trace(struct target *target)
        (*trace_data_p)->next = NULL;
        (*trace_data_p)->chkpt0 = trace_buffer[256];
        (*trace_data_p)->chkpt1 = trace_buffer[257];
-       (*trace_data_p)->last_instruction = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
+       (*trace_data_p)->last_instruction =
+                       buf_get_u32(armv4_5->pc->value, 0, 32);
        (*trace_data_p)->entries = malloc(sizeof(struct xscale_trace_entry) * (256 - j));
        (*trace_data_p)->depth = 256 - j;
 
@@ -2859,7 +2869,7 @@ static void xscale_build_reg_cache(struct target *target)
        int i;
        int num_regs = ARRAY_SIZE(xscale_reg_arch_info);
 
-       (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
+       (*cache_p) = arm_build_reg_cache(target, armv4_5);
 
        (*cache_p)->next = malloc(sizeof(struct reg_cache));
        cache_p = &(*cache_p)->next;
@@ -2975,6 +2985,9 @@ static int xscale_init_arch_info(struct target *target,
        xscale->dbr0_used = 0;
        xscale->dbr1_used = 0;
 
+       LOG_INFO("%s: hardware has 2 breakpoints and 2 watchpoints",
+                       target_name(target));
+
        xscale->arm_bkpt = ARMV5_BKPT(0x0);
        xscale->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
 
@@ -2992,7 +3005,7 @@ static int xscale_init_arch_info(struct target *target,
        armv4_5->write_core_reg = xscale_write_core_reg;
        armv4_5->full_context = xscale_full_context;
 
-       armv4_5_init_arch_info(target, armv4_5);
+       arm_init_arch_info(target, armv4_5);
 
        xscale->armv4_5_mmu.armv4_5_cache.ctype = -1;
        xscale->armv4_5_mmu.get_ttb = xscale_get_ttb;
@@ -3196,21 +3209,26 @@ COMMAND_HANDLER(xscale_handle_idcache_command)
                return ERROR_OK;
        }
 
-       bool icache;
-       COMMAND_PARSE_BOOL(CMD_NAME, icache, "icache", "dcache");
-
+       bool icache = false;
+       if (strcmp(CMD_NAME, "icache") == 0)
+               icache = true;
        if (CMD_ARGC >= 1)
        {
                bool enable;
                COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
-               if (enable)
-                       xscale_enable_mmu_caches(target, 1, 0, 0);
-               else
-                       xscale_disable_mmu_caches(target, 1, 0, 0);
-               if (icache)
+               if (icache) {
                        xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = enable;
-               else
+                       if (enable)
+                               xscale_enable_mmu_caches(target, 0, 0, 1);
+                       else
+                               xscale_disable_mmu_caches(target, 0, 0, 1);
+               } else {
                        xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = enable;
+                       if (enable)
+                               xscale_enable_mmu_caches(target, 0, 1, 0);
+                       else
+                               xscale_disable_mmu_caches(target, 0, 1, 0);
+               }
        }
 
        bool enabled = icache ?
@@ -3365,7 +3383,8 @@ COMMAND_HANDLER(xscale_handle_trace_buffer_command)
                /* 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->core_cache->reg_list[15].value, 0, 32);
+               xscale->trace.current_pc =
+                               buf_get_u32(armv4_5->pc->value, 0, 32);
        }
        else
        {
@@ -3417,7 +3436,7 @@ COMMAND_HANDLER(xscale_handle_trace_image_command)
        if (CMD_ARGC >= 2)
        {
                xscale->trace.image->base_address_set = 1;
-               COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], xscale->trace.image->base_address);
+               COMMAND_PARSE_NUMBER(llong, CMD_ARGV[1], xscale->trace.image->base_address);
        }
        else
        {
@@ -3597,94 +3616,101 @@ COMMAND_HANDLER(xscale_handle_cp15)
 static const struct command_registration xscale_exec_command_handlers[] = {
        {
                .name = "cache_info",
-               .handler = &xscale_handle_cache_info_command,
-               .mode = COMMAND_EXEC, NULL,
+               .handler = xscale_handle_cache_info_command,
+               .mode = COMMAND_EXEC,
+               .help = "display information about CPU caches",
        },
-
        {
                .name = "mmu",
-               .handler = &xscale_handle_mmu_command,
+               .handler = xscale_handle_mmu_command,
                .mode = COMMAND_EXEC,
-               .usage = "[enable|disable]",
                .help = "enable or disable the MMU",
+               .usage = "['enable'|'disable']",
        },
        {
                .name = "icache",
-               .handler = &xscale_handle_idcache_command,
+               .handler = xscale_handle_idcache_command,
                .mode = COMMAND_EXEC,
-               .usage = "[enable|disable]",
-               .help = "enable or disable the ICache",
+               .help = "display ICache state, optionally enabling or "
+                       "disabling it",
+               .usage = "['enable'|'disable']",
        },
        {
                .name = "dcache",
-               .handler = &xscale_handle_idcache_command,
+               .handler = xscale_handle_idcache_command,
                .mode = COMMAND_EXEC,
-               .usage = "[enable|disable]",
-               .help = "enable or disable the DCache",
+               .help = "display DCache state, optionally enabling or "
+                       "disabling it",
+               .usage = "['enable'|'disable']",
        },
-
        {
                .name = "vector_catch",
-               .handler = &xscale_handle_vector_catch_command,
+               .handler = xscale_handle_vector_catch_command,
                .mode = COMMAND_EXEC,
-               .help = "mask of vectors that should be caught",
-               .usage = "[<mask>]",
+               .help = "set or display 8-bit mask of vectors "
+                       "that should trigger debug entry",
+               .usage = "[mask]",
        },
        {
                .name = "vector_table",
-               .handler = &xscale_handle_vector_table_command,
+               .handler = xscale_handle_vector_table_command,
                .mode = COMMAND_EXEC,
-               .usage = "<high|low> <index> <code>",
-               .help = "set static code for exception handler entry",
+               .help = "set vector table entry in mini-ICache, "
+                       "or display current tables",
+               .usage = "[('high'|'low') index code]",
        },
-
        {
                .name = "trace_buffer",
-               .handler = &xscale_handle_trace_buffer_command,
+               .handler = xscale_handle_trace_buffer_command,
                .mode = COMMAND_EXEC,
-               .usage = "<enable | disable> [fill [n]|wrap]",
+               .help = "display trace buffer status, enable or disable "
+                       "tracing, and optionally reconfigure trace mode",
+               .usage = "['enable'|'disable' ['fill' number|'wrap']]",
        },
        {
                .name = "dump_trace",
-               .handler = &xscale_handle_dump_trace_command,
+               .handler = xscale_handle_dump_trace_command,
                .mode = COMMAND_EXEC,
-               .help = "dump content of trace buffer to <file>",
-               .usage = "<file>",
+               .help = "dump content of trace buffer to file",
+               .usage = "filename",
        },
        {
                .name = "analyze_trace",
-               .handler = &xscale_handle_analyze_trace_buffer_command,
+               .handler = xscale_handle_analyze_trace_buffer_command,
                .mode = COMMAND_EXEC,
                .help = "analyze content of trace buffer",
+               .usage = "",
        },
        {
                .name = "trace_image",
-               .handler = &xscale_handle_trace_image_command,
-               COMMAND_EXEC,
-               .help = "load image from <file> [base address]",
-               .usage = "<file> [address] [type]",
+               .handler = xscale_handle_trace_image_command,
+               .mode = COMMAND_EXEC,
+               .help = "load image from file to address (default 0)",
+               .usage = "filename [offset [filetype]]",
        },
-
        {
                .name = "cp15",
-               .handler = &xscale_handle_cp15,
+               .handler = xscale_handle_cp15,
                .mode = COMMAND_EXEC,
-               .help = "access coproc 15",
-               .usage = "<register> [value]",
+               .help = "Read or write coprocessor 15 register.",
+               .usage = "register [value]",
        },
        COMMAND_REGISTRATION_DONE
 };
 static const struct command_registration xscale_any_command_handlers[] = {
        {
                .name = "debug_handler",
-               .handler = &xscale_handle_debug_handler_command,
+               .handler = xscale_handle_debug_handler_command,
                .mode = COMMAND_ANY,
-               .usage = "<target#> <address>",
+               .help = "Change address used for debug handler.",
+               .usage = "target address",
        },
        {
                .name = "cache_clean_address",
-               .handler = &xscale_handle_cache_clean_address_command,
+               .handler = xscale_handle_cache_clean_address_command,
                .mode = COMMAND_ANY,
+               .help = "Change address used for cleaning data cache.",
+               .usage = "address",
        },
        {
                .chain = xscale_exec_command_handlers,
@@ -3721,7 +3747,8 @@ struct target_type xscale_target =
        .deassert_reset = xscale_deassert_reset,
        .soft_reset_halt = NULL,
 
-       .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
+       /* REVISIT on some cores, allow exporting iwmmxt registers ... */
+       .get_gdb_reg_list = arm_get_gdb_reg_list,
 
        .read_memory = xscale_read_memory,
        .read_phys_memory = xscale_read_phys_memory,